flutter-drift-persistence-engineering
Skill8 starsChanged 48 days agoMITView on GitHub
Design, implement, review, debug, test, migrate, and optimize production Flutter persistence built with Drift and SQLite. Use for @DriftDatabase, Dart tables, .drift SQL files, DAOs, generated code, driftDatabase, NativeDatabase, WasmDatabase, reactive watch streams, joins, transactions, batches, upserts, indexes, foreign keys, schemaVersion, guided migrations, background isolates, read pools, WAL, web workers/OPFS/IndexedDB, backup/export, or slow and janky local database behavior across Android, iOS, Web, Windows, macOS, and Linux. Trigger when users mention Drift, Moor migration, database streams rerunning, database locked errors, N+1 local queries, large SQLite datasets, or broken Drift migrations. Do not use for generic remote API caching without Drift, Firebase/Firestore modeling, or server-only database design.
In this repository70 other files it gives its agents.
- camerawesome-flutterSkill
- dart-args-production-cliSkill
- dart-flutter-equatable-engineeringSkill
- dart-flutter-ffi-systems-engineeringSkill
- dart-metaSkill
- document-camera-frameSkill
- document-scan-flutterSkill
- figma-to-flutter-expertSkill
- flutter-animations-production-engineeringSkill
- flutter-app-hardening-reverse-engineeringSkill
- flutter-app-icon-engineeringSkill
- flutter-application-security-engineeringSkill
- flutter-app-links-deep-link-engineeringSkill
- flutter-cachingSkill
- flutter-concurrency-memory-performanceSkill
- flutter-confetti-engineeringSkill
- flutter-dart-package-engineeringSkill
- flutter-design-system-from-design-mdSkill
- flutter-dio-cache-interceptor-engineeringSkill
- flutter-dio-engineeringSkill
- flutter-doc-scannerSkill
- flutter-expert-tipsSkill
- flutter-firebase-analyticsSkill
- flutter-firebase-core-engineeringSkill
- flutter-firebase-messagingSkill
- flutter-get-it-injectable-dependency-injectionSkill
- flutter-go-router-engineeringSkill
- flutter-hive-persistence-engineeringSkill
- flutter-image-performanceSkill
- flutter-image-picker-production-engineeringSkill
- flutter-lints-static-analysis-engineeringSkill
- flutter-local-notifications-production-engineeringSkill
- flutter-memory-leak-engineeringSkill
- flutter-mobile-developmentSkill
- flutter-motion-engineeringSkill
- flutter-multi-environmentSkill
- flutter-native-splash-engineeringSkill
- flutter-package-plugin-selectionSkill
- flutter-path-provider-production-storageSkill
- flutter-performance-jank-optimizationSkill
- flutter-permission-handler-engineeringSkill
- flutter-pinputSkill
- flutter-production-build-releaseSkill
- flutter-production-engineeringSkill
- flutter-production-loggingSkill
- flutter-pro-image-editor-engineeringSkill
- flutter-secure-storage-security-engineeringSkill
- flutter-sentry-engineeringSkill
- flutter-share-plus-engineeringSkill
- flutter-skeletonizer-engineeringSkill
- flutter-squadron-concurrency-engineeringSkill
- flutter-supabase-engineeringSkill
- flutter-svg-engineeringSkill
- flutter-ui-performance-engineeringSkill
- flutter-url-launcher-engineeringSkill
- flutter-video-player-production-engineeringSkill
- flutter-webview-production-engineeringSkill
- freezed-production-engineeringSkill
- html-to-flutterSkill
- hydrated-blocSkill
- The first 60 shown.
The file
Show its rules and text
We split this skill into the rules it gives an agent
32 rules. About 0 are common, 19 are distinctive, and 13 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈19
Distinctive · estimate
This author's own choices. Worth a look.
13
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 9
Treat Drift as a typed SQLite persistence system with generated APIs, reactive invalidation, platform-specific executors, and irreversible …
- Distinctive: line 13
Read only what the task requires:
- Very specific: line 32
Every database constructor and owner.
- Distinctive: line 37
Search for at least:
- Distinctive: line 62
Do not add repositories, DAOs, converters, or isolate pools merely for symmetry.
- Distinctive: line 77
Keep one long-lived logical database per application database file unless isolation is intentional.
- Very specific: line 79
Use driftDatabase from drift_flutter for the ordinary cross-platform Flutter setup.
- Very specific: line 80
Use NativeDatabase.createInBackground for manual native setup so synchronous SQLite work stays off the UI isolate.
- Very specific: line 81
Use manual DriftIsolate wiring only when multiple application-controlled isolates must share one logical database.
- Very specific: line 82
Use WasmDatabase.open or driftDatabase with DriftWebOptions on Web.
- Distinctive: line 90
Avoid duplicate prefix indexes and low-selectivity leading columns unless a measured plan benefits.
- Distinctive: line 91
Use joins or set-based SQL instead of query-per-row loops.
- Very specific: line 94
Verify important plans with EXPLAIN QUERY PLAN and representative data before claiming an optimization.
- Distinctive: line 98
Use a transaction for a business invariant spanning multiple statements.
- Distinctive: line 99
Keep transactions short and free of network calls, UI waits, timers, and unrelated computation.
- Very specific: line 100
Use batch/insertAll for bulk writes so Drift can reuse statements and reduce crossings.
- Distinctive: line 101
Use explicit upserts only when the chosen primary/unique conflict target matches product semantics.
- Very specific: line 107
Use get*() for one-shot reads and watch*() only when consumers need automatic updates.
- Distinctive: line 108
Keep watched queries selective, indexed, and small.
- Very specific: line 110
Do not combine an initial get() with watch().
- Distinctive: line 112
Do not expose transaction-local streams outside their transaction.
- Very specific: line 117
Prefer dart run drift_dev make-migrations and generated step-by-step migrations/tests over handwritten ad hoc upgrades.
- Distinctive: line 118
Commit historical schema snapshots and generated migration support files required by the project.
- Distinctive: line 119
Test upgrades from every supported historical version and assert retained business data, not only final DDL shape.
- Very specific: line 120
Run complex migrations transactionally, handle foreign-key pragmas as documented, and check PRAGMA foreign_key_check.
- Distinctive: line 121
Never use destructive fallback migration in production unless product policy explicitly permits data loss.
- Very specific: line 122
Treat downgrades as unsupported unless a separately designed export/reinstall/restore flow exists.
- Distinctive: line 142
Run code generation, formatting, analysis, and focused tests.
- Distinctive: line 143
Run generated migration tests and data-integrity assertions.
- Distinctive: line 144
Test create-new, upgrade, failed upgrade/rollback, reopen, and close ownership.
- Distinctive: line 145
Test every shipped executor: native targets and real supported browsers.
- Very specific: line 146
Verify Web worker and sqlite3.wasm deployment plus the selected persistence implementation.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Flutter Drift Persistence Engineering
Treat Drift as a typed SQLite persistence system with generated APIs, reactive invalidation, platform-specific executors, and irreversible schema evolution—not as a generic key-value store.
Reference routing
Read only what the task requires:
| Need | Reference |
| Dependencies, database declaration, connection ownership, DAOs, generated-code layout | references/01-setup-and-architecture.md |
| Tables, constraints, relationships, indexes, Dart/SQL queries, joins, pagination | references/02-schema-and-queries.md |
| Writes, transactions, batches, streams, invalidation, profiling, large datasets | references/03-writes-streams-and-performance.md |
Native isolates, driftDatabase, NativeDatabase, WAL/read pools, Web/WASM | references/04-platforms-and-concurrency.md |
| Migrations, migration tests, ordinary tests, backup, diagnostics, security, reviews | references/05-migrations-testing-and-operations.md |
| Version baseline and authoritative URLs | references/06-authoritative-sources.md |
The bundled research was checked on 2026-08-11 against Drift 2.34.3, drift_flutter 0.3.1, and current official Drift/SQLite documentation. Always inspect the project’s pubspec.lock, SDK constraints, generated code, and installed package source before relying on a signature or default.
Inspect before changing code
Inspect:
pubspec.yaml,pubspec.lock,build.yaml, Flutter/Dart versions, and shipped platforms.- Database classes, tables,
.driftfiles, DAOs, repositories, generated parts, and schema snapshots. - Every database constructor and owner; locate all opens, providers, overrides, and
close()calls. schemaVersion,migration, generated migration steps/tests, and historical schema files.- Hot queries, watched streams, indexes, write paths, transaction boundaries, and large result materializations.
- Native/Web connection setup, worker/WASM assets, headers, database path, pragmas, isolate sharing, and backup behavior.
Search for at least:
@DriftDatabase @DriftAccessor Table TableIndex .drift
driftDatabase NativeDatabase WasmDatabase LazyDatabase DriftIsolate
schemaVersion MigrationStrategy make-migrations beforeOpen onUpgrade
watch watchSingle transaction batch insertAll readPool journal_mode
customSelect customStatement notifyUpdates closeTrace callers before fixing a symptom. Put connection ownership, migration policy, and repeated-query fixes at their shared boundary.
Define the persistence contract
Establish:
- Which data is authoritative, cached, replaceable, or user-created?
- Which platforms and browser modes must persist reliably?
- What consistency and atomicity must each workflow provide?
- Which queries are hot, how many rows can they touch, and how are they ordered?
- Which UI surfaces truly need reactive results?
- How will every released schema version migrate and retain data?
- Who owns database startup, lifetime, close, backup, restore, and destructive recovery?
- What data is sensitive, and what encryption or platform storage boundary is required?
Do not add repositories, DAOs, converters, or isolate pools merely for symmetry. Add a boundary when it owns queries, policy, test seams, or lifecycle.
Choose the smallest sound architecture
Default to:
UI/state
→ feature repository or DAO when it adds a real boundary
→ one application database
→ generated Drift API
→ platform-aware executor
→ SQLite/WASM persistence- Keep one long-lived logical database per application database file unless isolation is intentional.
- Inject a
QueryExecutororDatabaseConnectionfor tests and specialized runtimes. - Use
driftDatabasefromdrift_flutterfor the ordinary cross-platform Flutter setup. - Use
NativeDatabase.createInBackgroundfor manual native setup so synchronous SQLite work stays off the UI isolate. - Use manual
DriftIsolatewiring only when multiple application-controlled isolates must share one logical database. - Use
WasmDatabase.openordriftDatabasewithDriftWebOptionson Web; never use deprecatedpackage:drift/web.dartfor new work. - Close the database from its actual owner. Do not close a shared singleton from a widget.
Design schema from invariants and queries
- Encode required values, uniqueness, keys, references, and safe defaults in the schema.
- Enable SQLite foreign-key enforcement deliberately; declaring references does not replace runtime enforcement.
- Index measured or clearly dominant
WHERE, join, andORDER BYpaths. Match composite-index leftmost order to real predicates. - Avoid duplicate prefix indexes and low-selectivity leading columns unless a measured plan benefits.
- Use joins or set-based SQL instead of query-per-row loops.
- Select only needed columns for large or hot paths.
- Give pagination a deterministic unique tie-breaker. Prefer keyset pagination for deep, frequently traversed datasets; use offset pagination for small/simple lists.
- Verify important plans with
EXPLAIN QUERY PLANand representative data before claiming an optimization.
Keep writes atomic and bounded
- Use a transaction for a business invariant spanning multiple statements; await every database operation inside it.
- Keep transactions short and free of network calls, UI waits, timers, and unrelated computation.
- Use
batch/insertAllfor bulk writes so Drift can reuse statements and reduce crossings. - Use explicit upserts only when the chosen primary/unique conflict target matches product semantics.
- Require a deliberate
whereclause for updates and deletes unless the task explicitly targets the full table. - Chunk very large imports when a single transaction creates unacceptable memory, lock, or latency pressure; preserve restart/idempotency semantics.
Make reactivity intentional
- Use
get*()for one-shot reads andwatch*()only when consumers need automatic updates. - Keep watched queries selective, indexed, and small. Drift invalidates by observed tables, so a write may rerun more streams than the exact changed rows require.
- Share or hoist equivalent streams when UI rebuilds would create redundant subscriptions.
- Do not combine an initial
get()withwatch(); Drift streams emit an initial current snapshot. - Declare
readsFrom/update metadata correctly for raw custom SQL and external writes, or reactive results can become stale. - Do not expose transaction-local streams outside their transaction.
Evolve schemas without gambling with data
- Bump
schemaVersionfor every released schema change. - Prefer
dart run drift_dev make-migrationsand generated step-by-step migrations/tests over handwritten ad hoc upgrades. - Commit historical schema snapshots and generated migration support files required by the project.
- Test upgrades from every supported historical version and assert retained business data, not only final DDL shape.
- Run complex migrations transactionally, handle foreign-key pragmas as documented, and check
PRAGMA foreign_key_check. - Never use destructive fallback migration in production unless product policy explicitly permits data loss.
- Treat downgrades as unsupported unless a separately designed export/reinstall/restore flow exists.
Optimize from evidence
Classify the bottleneck:
startup jank → executor placement, eager queries, migration/open work
slow query → scan/sort/join plan, missing or wrong index, excess columns/rows
database locked → multiple connections, long writes, WAL/read-pool configuration
stream churn → broad table invalidation, duplicate subscriptions, expensive result set
slow import → per-row statements, oversized transaction, serialization/isolate overhead
web slowness → chosen storage backend, worker deployment, missing COOP/COEP capabilities
memory growth → unbounded get(), retained result lists/subscriptions, large blobsProfile release/profile builds with representative row counts. Background isolates protect UI responsiveness but add message-copying and coordination overhead; they do not make SQL intrinsically faster.
Validate before finishing
- Run code generation, formatting, analysis, and focused tests.
- Run generated migration tests and data-integrity assertions.
- Test create-new, upgrade, failed upgrade/rollback, reopen, and close ownership.
- Test every shipped executor: native targets and real supported browsers.
- Verify Web worker and
sqlite3.wasmdeployment plus the selected persistence implementation. - Exercise cancellation/retry around imports, exports, backups, and app lifecycle.
- Benchmark hot queries and bulk writes with production-like data; inspect query plans.
- Review the final diff for unbounded reads, N+1 loops, missing constraints/indexes, broad watched queries, leaked connections, sensitive SQL logging, and data-loss fallbacks.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

