Agent skill
flutter-drift
Complete guide for using drift database library in Flutter applications. Use when building Flutter apps that need local SQLite database storage with type-safe queries, reactive streams, migrations, and efficient CRUD operations. Includes setup with drift_flutter package, StreamBuilder integration, Provider/Riverpod patterns, and Flutter-specific database management for mobile, web, and desktop platforms.
Install this agent skill to your Project
npx add-skill https://github.com/Im5tu/claude/tree/main/skills/flutter-drift
SKILL.md
Flutter Drift
Comprehensive guide for using drift database library in Flutter applications.
Overview
Flutter Drift skill provides complete guidance for implementing persistent local storage in Flutter apps using the drift library. Drift is a reactive persistence library for Flutter built on SQLite, offering type-safe queries, auto-updating streams, schema migrations, and cross-platform support.
Quick Start
Add dependencies to pubspec.yaml:
dependencies:
drift: ^2.30.0
drift_flutter: ^0.2.8
path_provider: ^2.1.5
dev_dependencies:
drift_dev: ^2.30.0
build_runner: ^2.10.4
Define database:
@DriftDatabase(tables: [TodoItems])
class AppDatabase extends _$AppDatabase {
AppDatabase([QueryExecutor? e])
: super(
e ??
driftDatabase(
name: 'app_db',
native: const DriftNativeOptions(
databaseDirectory: getApplicationSupportDirectory,
),
web: DriftWebOptions(
sqlite3Wasm: Uri.parse('sqlite3.wasm'),
driftWorker: Uri.parse('drift_worker.js'),
),
),
);
@override
int get schemaVersion => 1;
}
Run code generator:
dart run build_runner build
Reference Files
See detailed documentation for each topic:
- setup.md - Flutter-specific setup with drift_flutter
- tables.md - Table definitions, columns, constraints
- queries.md - SELECT, WHERE, JOIN, aggregations
- writes.md - INSERT, UPDATE, DELETE, transactions
- streams.md - Reactive stream queries
- migrations.md - Database schema migrations
- flutter-ui.md - Flutter UI integration patterns
Common Patterns
Reactive Todo List with StreamBuilder
class TodoList extends StatelessWidget {
@override
Widget build(BuildContext context) {
final database = Provider.of<AppDatabase>(context);
return StreamBuilder<List<TodoItem>>(
stream: select(database.todoItems).watch(),
builder: (context, snapshot) {
final todos = snapshot.data ?? [];
return ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
final todo = todos[index];
return ListTile(
title: Text(todo.title),
trailing: Checkbox(
value: todo.isCompleted,
onChanged: (value) {
database.update(database.todoItems).replace(
TodoItem(
id: todo.id,
title: todo.title,
isCompleted: value ?? false,
),
);
},
),
);
},
);
},
);
}
}
Add Item with Form
Future<void> showAddTodoDialog(BuildContext context) async {
final controller = TextEditingController();
final database = Provider.of<AppDatabase>(context);
await showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('Add Todo'),
content: TextField(
controller: controller,
decoration: const InputDecoration(labelText: 'Title'),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Cancel'),
),
TextButton(
onPressed: () async {
if (controller.text.isNotEmpty) {
await database.into(database.todoItems).insert(
TodoItemsCompanion.insert(title: controller.text),
);
if (context.mounted) {
Navigator.pop(context);
}
}
},
child: const Text('Add'),
),
],
);
},
);
controller.dispose();
}
Provider Setup
final databaseProvider = Provider<AppDatabase>((ref) {
final database = AppDatabase();
ref.onDispose(database.close);
return database;
});
Database Migration
@override
MigrationStrategy get migration {
return MigrationStrategy(
onUpgrade: stepByStep(
from1To2: (m, schema) async {
await m.addColumn(schema.todoItems, schema.todoItems.dueDate);
},
),
);
}
Platform-Specific Setup
Mobile (Android/iOS/macOS/Windows/Linux)
Uses drift_flutter with getApplicationSupportDirectory.
Web
Place sqlite3.wasm and drift_worker.js in web/ folder.
Isolate Sharing
AppDatabase.defaults(): super(
driftDatabase(
name: 'app_db',
native: DriftNativeOptions(
shareAcrossIsolates: true,
),
),
);
Testing
Use in-memory database for tests:
AppDatabase createTestDatabase() {
return AppDatabase(NativeDatabase.memory());
}
Best Practices
- Use drift_flutter for easy database setup across platforms
- StreamBuilder for reactive UI updates
- Provider/Riverpod for database access management
- Close database on app/widget dispose
- Use migrations when schema changes
- Index columns used in WHERE clauses
- Limit stream query size for performance
- Use transactions for multi-step operations
- Debounce user input for search/filter
- Handle loading/error states in UI
Troubleshooting
Build Fails
dart run build_runner clean
dart run build_runner build --delete-conflicting-outputs
Migration Errors
dart run drift_dev schema validate
dart run drift_dev make-migrations
Stream Not Updating
Ensure operations go through drift APIs, not raw SQLite.
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
flutter-animations
Comprehensive guide for implementing animations in Flutter. Use when adding motion and visual effects to Flutter apps: implicit animations (AnimatedContainer, AnimatedOpacity, TweenAnimationBuilder), explicit animations (AnimationController, Tween, AnimatedWidget/AnimatedBuilder), hero animations (shared element transitions), staggered animations (sequential/overlapping), and physics-based animations. Includes workflow for choosing the right animation type, implementation patterns, and best practices for performance and user experience.
dotnet-source-gen-logging
Converts logging to use the LoggerMessage source generator for high-performance, AOT-compatible logging. Also use when the user mentions "LoggerMessage," "logging source generator," "high-performance logging," "optimize logging," "AOT logging," or "structured logging source gen." For full AOT analysis, see dotnet-aot-analysis.
dotnet-source-gen-options-validation
Converts options validation to use the compile-time source generator for AOT-compatible, reflection-free validation. Also use when the user mentions "OptionsValidator," "options validation source gen," "AOT options validation," "compile-time validation," "ValidateDataAnnotations replacement," or "reflection-free validation." For full AOT analysis, see dotnet-aot-analysis.
dotnet-enable-testing-platform
Enables the Microsoft Testing Platform runner in global.json. Also use when the user mentions "testing platform," "Microsoft.Testing.Platform," "new test runner," "migrate test runner," "global.json testing," or "modern test platform."
dotnet-json-polymorphic
Configures polymorphic JSON serialization with [JsonPolymorphic] and [JsonDerivedType] attributes. Also use when the user mentions "polymorphic JSON," "JsonDerivedType," "JSON inheritance," "type discriminator," "serialize derived types," or "JSON polymorphism." For full JSON source generation, see dotnet-source-gen-json.
competitor-alternatives
When the user wants to create competitor comparison or alternative pages for SEO and sales enablement. Also use when the user mentions 'alternative page,' 'vs page,' 'competitor comparison,' 'comparison page,' '[Product] vs [Product],' '[Product] alternative,' or 'competitive landing pages.' Covers four formats: singular alternative, plural alternatives, you vs competitor, and competitor vs competitor. Emphasizes deep research, modular content architecture, and varied section types beyond feature tables.
Didn't find tool you were looking for?