Repository navigation
Make the generated Supabase types reproducible again #498
Description
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: neveron every table, andComputedFields: 'user_details_json'on one.NonNullable<Json>fornot nullJSON columns (push_credentials,notification_preferences,profile_data), where the committed file hasJson.display_name?: neverinInsertandUpdate, because the column is generated. The committed file hasstring | null.Args: neverbecameArgs: 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:18lists 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.
- Format the output inside the
typesscript? 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. - 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
-
Upgrade. In the root
package.jsoncatalog, setsupabase,@supabase/supabase-jsand@supabase/ssrto the latest published versions. Check each withbun info <package> version. On 2026-10-16 they were2.121.0,2.118.0and0.12.7(@supabase/ssris already current). Keep the caret ranges. Runbun installat the repo root, and commit thebun.lockchange. Frompackages/supabase,bunx supabase --versionmust print the new CLI version. -
Script. In
packages/supabase/package.json, maketypeswrite 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/nulllets this one call format a file that.prettierignorelists. -
Regenerate. Start local Supabase. From the repo root, run
bun run --filter @docs.plus/supabase_back types. -
Typecheck. Run
bun run typecheck. The new shapes can fail call sites:- a write to
display_name, which is nownever; - code that passes
nullwhereNonNullable<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.
- a write to
-
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: passAcceptance criteria
- Two
typesruns in a row give the same file. - After the commit,
typeson an unchanged database leavesgit statusclean. -
bun run typecheckpasses with no new casts. - The catalog names the latest
supabase,@supabase/supabase-jsand@supabase/ssrversions, andbun.lockresolves 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
create_direct_message_channelfunction #319document_viewspartitions start closed #315HMarzban commentedon Oct 15, 2026
Related issues
PushSentLogtable #320 — Related: Remove prod-only drift: four functions and thePushSentLogtable #320 says commitsupabase.tsif types changes. Until this lands, types always changes by CLI drift.content_changecarrier once the last carrier's digest is sent or skipped #451 — Related: Allow a newcontent_changecarrier once the last carrier's digest is sent or skipped #451 says include the regenerated types. Until this lands, that file holds only CLI drift.supabase.ts. Until this lands, the run shows only CLI drift.supabase.ts. Until this lands, each adds about 2,809 unrelated lines.Cross-link review, 2026-10-15. Generated by Claude Code
HMarzban commentedon Oct 16, 2026
Maintainer ruling, 2026-10-16
Decision 1: yes. The
typesscript 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-jsand@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. Thetypesscript runs the version inbun.lock.build(deps): bump the Supabase CLI and pin Pele
feat(supabase): check script parity and grant allowlists
HMarzban commentedon Oct 19, 2026
Checked 2026-10-19
typesruns in a row give the same file: pass.typesleavesgit statusclean: pass.bun run typecheck: pass. It is part of tonight's CI run 39297468969.bun.lockresolves them:supabase2.121.0,@supabase/supabase-js2.118.0 and@supabase/ssr0.12.7, each equal to npmlatesttoday.