Hive vs Isar vs SQLite: Choosing Local Storage for Offline-First Flutter Apps

in Flutter Devs21 days ago

If you're building offline-first in Flutter, sooner or later you have to pick a local storage engine. I've used all three of these in production apps, and each one has a real trade-off — here's how I'd actually decide between them.

Quick overview

HiveIsarSQLite (sqflite)
TypeNoSQL key-valueNoSQL object databaseRelational (SQL)
Query PowerBasicStrong (indexes, filters, sorting)Full SQL
Setup ComplexityVery LowLow-mediumMedium
Speed (simple reads/writes)Very FastVery FastFast, but slower for simple ops
Best forSimple key-value data, settings, small datasetsStructured objects with queries, medium-large datasetsComplex relational data, joins, existing SQL knowledge

Hive — when simplicity wins

Hive (the Flutter package, not the blockchain — easy to confuse if you're active on both like I am) is essentially a fast, lightweight key-value store. No query engine, no schema migrations to worry about. It shines when your data doesn't need complex querying — user preferences, cached API responses, simple lists.

dart var box = await Hive.openBox('tasks'); box.put('task1', Task(title: 'Buy milk', done: false)); var task = box.get('task1');

The catch: once your data model gets more relational (tasks that belong to projects that belong to users, with filtering across all of it), you'll feel Hive's limits fast.

Isar — the middle ground that often wins

Isar gives you Hive-like speed with actual query capabilities: indexes, filters, sorting, even full-text search. For most offline-first apps I build now, this is my default. It handles the "I need structured data AND I need to query it" problem without the overhead of full SQL.

dart
final tasks = await isar.tasks
.filter()
.doneEqualTo(false)
.sortByCreatedAtDesc()
.findAll();

The trade-off is a slightly steeper setup (code generation via build_runner) and it's a newer project than SQLite, so the ecosystem and community answers are thinner if you hit an edge case.

SQLite — when you actually need relational data

If your data genuinely has complex relationships — multiple tables, joins, aggregate queries — SQLite via sqflite is still the most battle-tested option. It's not Flutter-specific, so any SQL knowledge you already have transfers directly, and debugging tools are mature.

dart
final db = await openDatabase('app.db');
final tasks = await db.rawQuery(
'SELECT * FROM tasks WHERE done = 0 ORDER BY created_at DESC'
);

The cost is more boilerplate — you're writing migrations, managing schema versions, and SQL strings are less type-safe than Isar's query builder unless you add an ORM layer on top.

My actual decision rule

  1. Small, flat data (settings, cache, single-entity lists) → Hive

  2. Structured data that needs filtering/sorting but isn't deeply relational → Isar

  3. Genuinely relational data, or you're porting from a backend that's already SQL → SQLite

I default to Isar for most new offline-first apps at this point — it hits the sweet spot between Hive's simplicity and SQLite's query power without dragging in the full weight of a relational database.

What's your default pick, and has it changed as your apps got more complex? Curious if others have landed somewhere different.

Sort:  

Congratulations @iamjmarc! You have completed the following achievement on the Hive blockchain And have been rewarded with New badge(s)

You received more than 10 HP as payout for your posts, comments and curation.
Your next payout target is 50 HP.
The unit is Hive Power equivalent because post and comment rewards can be split into HP and HBD

You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP