When building Flutter applications, managing local data efficiently is critical. You want a database that is lightweight, fast, and easy to integrate, especially if your app will work offline. Isar is one such database. It is a high-performance, easy-to-use NoSQL embedded database tailored for Flutter. With features like reactive queries, indexes, relationships, migrations, and transactions, Isar makes local data persistence both powerful and developer-friendly.
In this article, you’lll learn how to integrate Isar into a Flutter project, set up a data model, and perform the full range of CRUD (Create, Read, Update, Delete) operations. To make this practical, you’ll build a simple to-do app that allows users to create, view, update, and delete tasks.
Prerequisites
Before starting, ensure you have the following:
-
Flutter SDK installed (version 3.0 or above recommended).
Check your version with:flutter --version -
Dart knowledge: Familiarity with Dart syntax, classes, and async programming.
-
Flutter basics: You should know how to set up a Flutter project, build widgets, and use
FutureBuilderorsetStatefor state management. -
Code editor: VS Code or Android Studio is recommended.
If these are in place, we are ready to begin.
What We Are Building
We will create a Task Manager App that lets users:
-
Add new tasks.
-
View all tasks in a list.
-
Update existing tasks.
-
Delete tasks.
By the end, you will have a fully functioning CRUD app built with Flutter and Isar.
How to Set Up Isar in a Flutter Project
Step 1: Add dependencies
Open your pubspec.yaml file and add the following:
dependencies: flutter: sdk: flutter isar: ^3.1.0 isar_flutter_libs: ^3.1.0 dev_dependencies: isar_generator: ^3.1.0 build_runner: any
-
isar: The core Isar package. -
isar_flutter_libs: Required for Flutter integration. -
isar_generator: Used to generate code for your models. -
build_runner: Runs the code generator.
Run:
flutter pub get
Step 2: Create and initialize Isar
Create a file named isar_setup.dart. This will handle the opening of the Isar database.
import 'package:isar/isar.dart'; import 'package:path_provider/path_provider.dart'; import 'task.dart'; // we will create this model soon late final Isar isar; Future<void> initializeIsar() async { final dir = await getApplicationDocumentsDirectory(); isar = await Isar.open( [TaskSchema], directory: dir.path, ); }
Explanation:
-
getApplicationDocumentsDirectory()provides a storage location for the database file. -
Isar.open()initializes the database and registers ourTaskschema. -
late final Isar isar;ensures we can access the database instance globally after initialization.
How to Create the Task Model
Now let’s define our data model for tasks. Create a file named task.dart.
import 'package:isar/isar.dart'; part 'task.g.dart'; @Collection() class Task { Id id = Isar.autoIncrement; // auto-incrementing primary key late String name; late DateTime createdAt; Task(this.name) : createdAt = DateTime.now(); }
Explanation:
-
@Collection()tells Isar this class represents a database collection. -
Id id = Isar.autoIncrement;creates a unique identifier automatically. -
late String name;stores the task name. -
late DateTime createdAt;stores the creation timestamp. -
part 'task.g.dart';links to the generated code, which will be created after running the code generator.
Generate the code with:
flutter pub run build_runner build
This generates task.g.dart, which contains the necessary schema code.
How to Build the Repository for CRUD Operations
Create a new file called task_repository.dart. This will house the methods for interacting with the database.
import 'package:isar/isar.dart'; import 'task.dart'; import 'isar_setup.dart'; class TaskRepository { Future<void> addTask(String name) async { final task = Task(name); await isar.writeTxn(() async { await isar.tasks.put(task); }); } Future<List<Task>> getAllTasks() async { return await isar.tasks.where().findAll(); } Future<void> updateTask(Task task) async { await isar.writeTxn(() async { await isar.tasks.put(task); }); } Future<void> deleteTask(Task task) async { await isar.writeTxn(() async { await isar.tasks.delete(task.id); }); } }
Explanation:
-
addTask: Creates a new task and saves it. -
getAllTasks: Reads all tasks from the database. -
updateTask: Updates an existing task by calling.put()again. -
deleteTask: Removes a task by itsid. -
isar.writeTxn: Ensures operations run inside a transaction for safety and consistency.
How to Integrate CRUD into the Flutter UI
Now, let’s connect everything inside main.dart.
import 'package:flutter/material.dart'; import 'isar_setup.dart'; import 'task_repository.dart'; import 'task.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await initializeIsar(); // initialize Isar before runApp runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: TaskListScreen(), ); } } class TaskListScreen extends StatefulWidget { @override _TaskListScreenState createState() => _TaskListScreenState(); } class _TaskListScreenState extends State<TaskListScreen> { final TaskRepository _taskRepository = TaskRepository(); late Future<List<Task>> _tasksFuture; @override void initState() { super.initState(); _tasksFuture = _taskRepository.getAllTasks(); } Future<void> _addTask() async { await _taskRepository.addTask('New Task'); setState(() { _tasksFuture = _taskRepository.getAllTasks(); }); } Future<void> _deleteTask(Task task) async { await _taskRepository.deleteTask(task); setState(() { _tasksFuture = _taskRepository.getAllTasks(); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Isar CRUD Example')), body: FutureBuilder<List<Task>>( future: _tasksFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator()); } else if (snapshot.hasError) { return Center(child: Text('Error: ${snapshot.error}')); } else { final tasks = snapshot.data ?? []; if (tasks.isEmpty) { return Center(child: Text('No tasks yet.')); } return ListView.builder( itemCount: tasks.length, itemBuilder: (context, index) { final task = tasks[index]; return ListTile( title: Text(task.name), subtitle: Text('Created at: ${task.createdAt}'), trailing: IconButton( icon: Icon(Icons.delete), onPressed: () => _deleteTask(task), ), ); }, ); } }, ), floatingActionButton: FloatingActionButton( onPressed: _addTask, child: Icon(Icons.add), ), ); } }
Explanation:
-
initializeIsar(): Ensures the database is ready before the app runs. -
_tasksFuture: Holds a future of the list of tasks. -
_addTask: Adds a new task and refreshes the list. -
_deleteTask: Deletes a task and refreshes the list. -
FutureBuilder: Automatically rebuilds the UI when the future completes. -
ListView.builder: Displays all tasks dynamically.
This gives you a simple yet complete CRUD app using Isar.
Beyond CRUD: Advanced Features of Isar
Once you are comfortable with CRUD, Isar provides advanced tools to optimize and extend your application:
-
Reactive Queries:
Instead of usingFutureBuilder, you can listen for changes directly.final stream = isar.tasks.where().watch(fireImmediately: true); -
Indexes:
Improve query performance by indexing fields.@Collection() class Task { Id id = Isar.autoIncrement; @Index() late String name; } -
Relations:
Link one collection to another (for example,Projectwith manyTasks). -
Custom Queries:
Perform complex filtering, sorting, and pagination. -
Migrations:
Safely evolve your schema as the app grows. -
Batch Operations:
Insert or update many records in one transaction.
Conclusion
We built a simple Flutter to-do app with Isar that supports creating, reading, updating, and deleting tasks. Along the way, we learned how to:
-
Add Isar dependencies.
-
Define a model with annotations.
-
Generate schema code.
-
Implement CRUD operations in a repository.
-
Connect Isar to the Flutter UI.
With its performance, developer-friendly API, and advanced features, Isar is an excellent choice for local persistence in Flutter applications.
For further learning, consult the official docs:
Source: freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More.


Leave a Reply