Skip to content

Make the generated Supabase types reproducible again #498

Closed

Description

@HMarzban

Summary

bun run --filter @docs.plus/supabase_back types no longer reproduces the committed apps/webapp/src/types/supabase.ts. On an unchanged local database, the output differs by 2,809 diff lines (measured locally, 2026-10-15). So every SQL change that follows the "run types and commit it" rule also commits hundreds of unrelated lines.

The schema is not the cause. Both files hold 22 tables and 94 function Args blocks (measured locally). The cause is the generator. The locked CLI (supabase@2.120.0 in bun.lock) writes a newer shape than the CLI that made the committed file.

#496 Decision 1 (ruled 2026-10-15) keeps supabase.ts out of #489, #490 and #491 until this issue lands. This issue removes the need for that exception.

Problem

Measured locally, 2026-10-15, CLI 2.120.0 (the version bun.lock resolves; check with bunx supabase --version from packages/supabase):

Compare Diff lines
Raw types output vs the committed file 2,809
Raw output formatted with Prettier vs the committed file 1,120
Both files formatted with Prettier 226

The 226 left are CLI shape changes, not schema changes:

  • ComputedFields: never on every table, and ComputedFields: 'user_details_json' on one.
  • NonNullable<Json> for not null JSON columns (push_credentials, notification_preferences, profile_data), where the committed file has Json.
  • display_name?: never in Insert and Update, because the column is generated. The committed file has string | null.
  • Args: never became Args: Record<PropertyKey, never>.

Two repo facts make it worse:

  • The raw 2.120.0 output is not formatted: fields sit on one line, with odd indents.
  • .prettierignore:18 lists the file, so nothing formats it later.

The script is at packages/supabase/package.json:11. The range is in the root catalog (package.json:139).

Decisions

The recommended answer comes first. Maintainer rulings are posted as a comment.

  1. Format the output inside the types script? Ruled 2026-10-16: yes. Pipe it through Prettier, so the committed file is stable and readable whatever the CLI prints. Keep the file in .prettierignore, so lint-staged and editors do not touch it on their own.
  2. Pin the CLI, or upgrade every Supabase package? Ruled 2026-10-16: upgrade the CLI and all Supabase packages to their latest versions. Step 1 formats the output, so a later CLI bump shows up as a reviewable diff in its own change.

Depends on

Nothing. Land it before the next SQL change that adds a table, a column, an enum value or a function signature.

Fix plan

  1. Upgrade. In the root package.json catalog, set supabase, @supabase/supabase-js and @supabase/ssr to the latest published versions. Check each with bun info <package> version. On 2026-10-16 they were 2.121.0, 2.118.0 and 0.12.7 (@supabase/ssr is already current). Keep the caret ranges. Run bun install at the repo root, and commit the bun.lock change. From packages/supabase, bunx supabase --version must print the new CLI version.

  2. Script. In packages/supabase/package.json, make types write the file, then format it:

    "types": "dotenv -e ../../.env.local -- bunx supabase gen types typescript --local > ../../apps/webapp/src/types/supabase.ts && bunx prettier --write --ignore-path /dev/null ../../apps/webapp/src/types/supabase.ts"

    --ignore-path /dev/null lets this one call format a file that .prettierignore lists.

  3. Regenerate. Start local Supabase. From the repo root, run bun run --filter @docs.plus/supabase_back types.

  4. Typecheck. Run bun run typecheck. The new shapes can fail call sites:

    • a write to display_name, which is now never;
    • code that passes null where NonNullable<Json> is now required.

    Fix each call site to match the real schema. Do not cast the types away. If a fix needs a behaviour change, stop and ask.

  5. Ship. One commit: the catalog upgrade, bun.lock, the script, the regenerated file and any call-site fixes. No SQL and no production step.

Verify

bun run --filter @docs.plus/supabase_back types
cp apps/webapp/src/types/supabase.ts /tmp/types-a.ts
bun run --filter @docs.plus/supabase_back types
diff /tmp/types-a.ts apps/webapp/src/types/supabase.ts && echo stable   # expect: stable
git diff --stat apps/webapp/src/types/supabase.ts                        # expect: no change after the commit
bun run typecheck                                                        # expect: pass

Acceptance criteria

  • Two types runs in a row give the same file.
  • After the commit, types on an unchanged database leaves git status clean.
  • bun run typecheck passes with no new casts.
  • The catalog names the latest supabase, @supabase/supabase-js and @supabase/ssr versions, and bun.lock resolves them.
  • A comment on [Tracking] Stuck-Online users and the presence review follow-ups #496 says the Decision 1 exception is no longer needed.

Out of scope

  • Any schema change. This issue changes how the file is made, not what the database holds.

Generated by Claude Code

Activity

  1. HMarzban commented on Oct 15, 2026

    @HMarzban
    CollaboratorAuthor

    Related issues


    Cross-link review, 2026-10-15. Generated by Claude Code

  2. HMarzban commented on Oct 16, 2026

    @HMarzban
    CollaboratorAuthor

    Maintainer ruling, 2026-10-16

    Decision 1: yes. The types script formats its output with Prettier.

    Decision 2: upgrade, not pin. Upgrade the Supabase CLI and every Supabase package to the latest version: supabase, @supabase/supabase-js and @supabase/ssr. Fix plan Step 1 now says this.

    Also corrected in the body: the drift comes from the locked CLI 2.120.0, not from 2.121.0. The types script runs the version in bun.lock.

  3. added this to the v2.2.0 milestone on Oct 18, 2026
  4. HMarzban commented on Oct 19, 2026

    @HMarzban
    CollaboratorAuthor

    Checked 2026-10-19

    • Two types runs in a row give the same file: pass.
    • On an unchanged database, types leaves git status clean: pass.
    • bun run typecheck: pass. It is part of tonight's CI run 39297468969.
    • The catalog names the latest versions, and bun.lock resolves them: supabase 2.121.0, @supabase/supabase-js 2.118.0 and @supabase/ssr 0.12.7, each equal to npm latest today.
    • [Tracking] Stuck-Online users and the presence review follow-ups #496 now records that the Decision 1 exception is no longer needed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions