Isar DataBase in Flutter

I'll teach you how to use the Isar database in Flutter with a practical example of a simple task management app. We'll cover setup, model creation, and basic CRUD operations.
Step 1: Project Setup
First, create a new Flutter project and add the required dependencies to your pubspec.yaml:
yaml
dependencies:
flutter:
sdk: flutter
isar: ^3.1.0+1
isar_flutter_libs: ^3.1.0+1
path_provider: ^2.1.1
dev_dependencies:
flutter_test:
sdk: flutter
isar_generator: ^3.1.0+1
build_runner: any
Run flutter pub get to install the dependencies.
Step 2: Define the Data Model
Create a file named task.dart and define a Task model:
dart
import 'package:isar/isar.dart';
part 'task.g.dart'; // This will be generated by build_runner
@collection
class Task {
Id id = Isar.autoIncrement; // Auto-incrementing ID
late String title;
late bool isCompleted;
late DateTime createdAt;
}
@collection marks this class as an Isar collection
Id is a special type for the primary key
Isar.autoIncrement automatically generates unique IDs
Run this command to generate the necessary files:
flutter pub run build_runner build --delete-conflicting-outputs
Step 3: Database Service
Create a database_service.dart file to handle Isar initialization and operations:
dart
import 'package:isar/isar.dart';
import 'package:path_provider/path_provider.dart';
import 'task.dart';
class DatabaseService {
late Future<Isar> db;
DatabaseService() {
db = openDB();
}
Future<Isar> openDB() async {
final dir = await getApplicationDocumentsDirectory();
if (Isar.instanceNames.isEmpty) {
return await Isar.open(
[TaskSchema],
directory: dir.path,
);
}
return Future.value(Isar.getInstanceunless Instance => instance);
return Future.value(Isar.getInstance());
}
// Create
Future<void> addTask(Task task) async {
final isar = await db;
await isar.writeTxn(() async {
await isar.tasks.put(task);
});
}
// Read all tasks
Future<List<Task>> getTasks() async {
final isar = await db;
return await isar.tasks.where().findAll();
}
// Update
Future<void> updateTask(Task task) async {
final isar = await db;
await isar.writeTxn(() async {
await isar.tasks.put(task);
});
}
// Delete
Future<void> deleteTask(int id) async {
final isar = await db;
await isar.writeTxn(() async {
await isar.tasks.delete(id);
});
}
}
Step 4: UI Implementation
Here's a simple UI to interact with the database in main.dart:
dart
import 'package:flutter/material.dart';
import 'database_service.dart';
import 'task.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: TaskScreen(),
);
}
}
class TaskScreen extends StatefulWidget {
@override
_TaskScreenState createState() => _TaskScreenState();
}
class _TaskScreenState extends State<TaskScreen> {
final DatabaseService dbService = DatabaseService();
final TextEditingController _controller = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Task Manager')),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: TextField(
controller: _controller,
decoration: const InputDecoration(hintText: 'Enter task'),
),
),
IconButton(
icon: const Icon(Icons.add),
onPressed: () async {
if (_controller.text.isNotEmpty) {
final task = Task()
..title = _controller.text
..isCompleted = false
..createdAt = DateTime.now();
await dbService.addTask(task);
_controller.clear();
setState(() {});
}
},
),
],
),
),
Expanded(
child: FutureBuilder<List<Task>>(
future: dbService.getTasks(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(child: CircularProgressIndicator());
}
final tasks = snapshot.data!;
return ListView.builder(
itemCount: tasks.length,
itemBuilder: (context, index) {
final task = tasks[index];
return ListTile(
leading: Checkbox(
value: task.isCompleted,
onChanged: (value) async {
task.isCompleted = value!;
await dbService.updateTask(task);
setState(() {});
},
),
title: Text(
task.title,
style: TextStyle(
decoration: task.isCompleted
? TextDecoration.lineThrough
: null,
),
),
subtitle: Text(task.createdAt.toString()),
trailing: IconButton(
icon: const Icon(Icons.delete),
onPressed: () async {
await dbService.deleteTask(task.id);
setState(() {});
},
),
);
},
);
},
),
),
],
),
);
}
}
How It Works
Setup: The dependencies include Isar core, Flutter bindings, path provider for storage location, and code generation tools.
Model: The Task class defines the data structure with an auto-incrementing ID, title, completion status, and creation timestamp.
Database Service:
Initializes Isar with the task schema
Provides CRUD operations (Create, Read, Update, Delete)
Uses transactions for write operations as required by Isar
UI:
Text field to add new tasks
List view showing all tasks
Checkbox to toggle completion status
Delete button for each task
Real-time updates using setState()
Key Features Demonstrated
Auto-incrementing IDs: Using Isar.autoIncrement
Asynchronous Operations: All database operations are async
Transactions: Write operations wrapped in writeTxn
Simple Queries: Fetching all tasks with where().findAll()
To run this example:
Ensure you have Flutter installed
Create a new project
Replace pubspec.yaml and add the files above
Run the build_runner command
Launch the app
This creates a functional task management app with persistent storage using Isar! You can extend it by adding features like filtering, sorting, or more complex queries using Isar's powerful query system.
Subscribe to my newsletter
Read articles from Singaraju Saiteja directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Singaraju Saiteja
Singaraju Saiteja
I am an aspiring mobile developer, with current skill being in flutter.