SKILL.md
Flutter Drift
Use this skill to add or repair Drift-based local persistence in Flutter apps. The skill is an operating workflow: inspect the target app first, choose only the relevant reference files, implement with current Drift APIs, and validate generated code.
Core Workflow
- Inspect the app before editing:
- Check
pubspec.yaml, existing database files,build.yaml, state management package, target platforms, and tests.
- Prefer the app's current architecture and naming over the examples in this skill.
- Add or verify dependencies with package commands instead of hardcoding versions:
dart pub add drift drift_flutter path_provider dev:drift_dev dev:build_runner
- Add
providerorflutter_riverpodonly when the app already uses it or the user asks for that integration.
- Create or update the database entry point:
- Define tables in Dart or
.driftfiles.
- Add the tables to
@DriftDatabase.
- Open Flutter databases with
driftDatabasefrompackage:drift_flutter/drift_flutter.dartunless the project needs a custom executor.
- Keep Drift calls scoped to the database object:
- Use
database.select(database.todoItems),database.into(database.todoItems),database.update(database.todoItems), anddatabase.delete(database.todoItems)from widgets, services, and repositories.
- Use bare
select(todoItems)only insideGeneratedDatabasesubclasses orDatabaseAccessorclasses where the methods and table getters are in scope.
- Generate code after changing Drift declarations:
- Run
dart run build_runner build.
- Treat generator errors as blockers, not optional cleanup.
- For schema changes in an existing app, use Drift's guided migration workflow:
- Configure
drift_devdatabases inbuild.yaml.
- Run
dart run drift_dev make-migrationsbefore and after schema changes as needed.
- Bump
schemaVersion, write generated step-by-step migrations, and run generated migration tests.
- Validate before finishing:
- Run
dart formaton edited Dart files.
- Run
flutter analyzeordart analyzefor the package.
- Run targeted tests, including generated migration tests when migrations changed.
Resource Routing
- Read references/setup.md when adding Drift, opening a database, configuring web support, or sharing a database across isolates.
- Read references/tables.md when defining tables, columns, defaults, keys, indexes, constraints, generated columns, or strict tables.
- Read references/queries.md when implementing selects, filters, sorting, pagination, joins, aggregations, subqueries, custom columns, or unions.
- Read references/writes.md when implementing inserts, updates, deletes, upserts, companions, transactions, or batch operations.
- Read references/streams.md when implementing reactive Drift streams, StreamBuilder, StreamProvider, custom select streams, table update listeners, or manual stream invalidation.
- Read references/migrations.md when
schemaVersion, existing user data,build.yaml,make-migrations, generated schema files, or migration tests are involved.
- Read references/flutter-ui.md when wiring Drift data into Flutter widgets with Provider, Riverpod, StreamBuilder, search, filtering, pagination, or user-facing loading and error states.
Required API Rules
- Do not call
select(database.table)as a top-level function from a widget. Usedatabase.select(database.table)outside database classes.
- Do not use
watch(...),todoUpdates(...), ornotifyTableUpdates(...). UsecustomSelect(...).watch(),tableUpdates(...), andnotifyUpdates(...).
- Do not call
delete(table).go(id). Add awhereclause and then callgo(), or use generated table extension helpers if the project already uses them.
- Do not use
batch.updateAll(...)or pass raw ids tobatch.delete(...). Usebatch.update(..., where: ...),batch.delete(...)with an insertable row, orbatch.deleteWhere(...).
- Do not mix Provider and Riverpod APIs.
Provider.of<AppDatabase>(context)belongs toprovider;Provider<AppDatabase>((ref) { ... })andAsyncValue.when(...)belong to Riverpod.
- Do not bump
schemaVersionwithout a migration plan for existing databases.
- Do not rely on raw SQLite writes when UI streams must update. Use Drift write APIs or call
notifyUpdateswith explicitTableUpdatemetadata.
Fallbacks
- If package downloads are blocked, update source files and leave exact
dart pub addorflutter pub addcommands for the user, then state that dependency resolution was not validated.
- If a project cannot run
build_runner, do not hand-write generated*.g.dartfiles. Fix source declarations and report the generator blocker.
- If migration state is unclear, stop before changing
schemaVersion; ask for the current released schema history or database files.
- If web support is required but
sqlite3.wasmanddrift_worker.jsare missing, add the code path and explicitly report the required web assets.
Validation Checklist
pubspec.yamlcontains Drift runtime and generator dependencies.
- Database files have valid
partdirectives, table declarations,@DriftDatabase, constructor, andschemaVersion.
- All query and write examples are scoped to the correct database/accessor context.
- Generated code was rebuilt with
build_runner.
- Flutter UI examples handle loading, empty, error, and data states without treating
AsyncValueas aList.
- Migrations changed only with generated schema snapshots, step-by-step migration code, and tests.
flutter analyzeordart analyzepasses for the edited package, or any remaining analyzer failure is reported with the blocker.