Skill v1.0.0
LLM-judged scan90/100version: "1.0.0" name: supabase-typegen-generate description: >- Generates the typed Dart schema (row, insert and update types, column constants, enums and typed rpc methods) for a Supabase database with supabase gen types --lang dart, and keeps it in sync with the database. Use when setting up typed queries with table(), after changing a database migration, when a table, column or function is missing from the generated file, or when the generated file fails to analyze.
Generating the typed Supabase schema
The supabase_typegen package turns a Supabase database schema into the Dart types that client.table() and the typed client.rpc methods use. It is never run by hand: the Supabase CLI introspects the database and runs dart run supabase_typegen --output - in the current directory with the schema on stdin, and the generated code arrives on stdout.
Rules
- Generate with the Supabase CLI, version 2.122.0 or newer. Check with
supabase --version, or npx supabase --version when the project pins the CLI in package.json.
- Never edit the generated file. Change the database and regenerate instead.
- Regenerate after every database migration, before writing code against the
new schema.
- Commit the generated file, so the app builds without a database.
- Run the command from the directory of the app's
pubspec.yaml. The CLI
finds the supabase/ folder in that directory or any parent, and runs the generator where it was started.
Setup
dart pub add dev:supabase_typegen
Use flutter pub add in a Flutter app. The generator must be a dev dependency of the package the file is written into, since the CLI runs it with dart run there.
Generating
Pick the database to read from:
| Source | Command | |
|---|---|---|
Local stack from the supabase/ migrations (after supabase start) | supabase gen types --lang dart --local > lib/supabase_schema.g.dart | |
The project linked with supabase link | supabase gen types --lang dart --linked > lib/supabase_schema.g.dart | |
| Any hosted project | supabase gen types --lang dart --project-id <ref> > lib/supabase_schema.g.dart |
Prefer --local when the project keeps its schema as migrations, so the SQL in supabase/migrations stays the source of truth. --local needs Docker and a running stack.
Without --schema, the CLI generates public plus the schemas listed in api.schemas of supabase/config.toml. Pass --schema once per schema to choose them yourself:
supabase gen types --lang dart --local --schema public --schema inventory > lib/supabase_schema.g.dart
Only schemas exposed through the Data API can be queried at runtime. A table in a schema other than public carries the schema as a prefix, inventory.books becomes InventoryBooks, and its table definition carries the schema, so no .schema() call is needed.
After generating, analyze the file, with flutter analyze in a Flutter app. It must be clean:
dart analyze lib/supabase_schema.g.dart
The file is already formatted for the project's language version, so dart format leaves it unchanged.
What the file contains
For a table books in public:
| Generated | Use | |
|---|---|---|
BooksRow | The row type returned by select(), with one typed getter per column | |
BooksInsert | The only value insert() and upsert() accept; required columns are required parameters | |
BooksUpdate | The only value update() accepts, plus set…ToNull() for nullable columns | |
Books.table | The table definition passed to client.table() | |
Books.title, Books.authorId, … | Column constants for filters, orderings and selectOnly | |
Books.authors | A relation constant per foreign key, for embedding | |
Mood | A Dart enum per Postgres enum | |
client.rpc.bookById(…) | A typed method per function PostgREST exposes |
final List<BooksRow> books = await supabase.table(Books.table).select().where(Books.mood.eq(Mood.happy));final BooksRow? book = await supabase.rpc.bookById(bookId: 1);
Read-only relations, such as materialized views, get a row type and column constants but no insert or update type, so writes to them do not compile.
When something is missing
- A table is missing. Its schema was not generated: add
--schema, or
add the schema to api.schemas. A table without columns is skipped, and the CLI says so in its summary.
- A relation constant is missing. Foreign keys into another schema and
self-referencing foreign keys get no relation, since PostgREST cannot embed them. Query those through a second request.
- A function has no method. The generated file has a comment where the
method would be, explaining why. Call it untyped with supabase.rpc('fn', params: {...}).
- A column has an unexpected type.
numericmaps tonum,dateto
PostgresDate, interval to PostgresInterval, and array elements are assumed non-null. The full list is in the `supabase_typegen` README.
Errors
The CLI reports a generator failure as failed to generate dart types: dart run supabase_typegen exited with code N: …, followed by the generator's own message.
| Symptom | Fix | |
|---|---|---|
dart run cannot find supabase_typegen | Add the dev dependency and run pub get in the directory the command runs in. | |
The project is on Dart X, but the generated code needs Dart Y or newer | Raise the lower bound of environment.sdk in pubspec.yaml. | |
The database has no schema "x" | Check the schema name, or that the stack has run the migration that creates it. | |
--lang dart is rejected | Upgrade the Supabase CLI to 2.122.0 or newer. | |
--local cannot reach the database | Run supabase start first. |