isar/hive
> A key-value database for Flutter and Dart — pure Dart in its classic 1.x/2.x line, a thin wrapper over the Isar engine in its 4.x rewrite.
GitHub repo · pub.dev: hive · License: Apache-2.0
Overview
Hive is a NoSQL key-value store for Flutter and Dart applications, originally written in pure Dart with no native dependencies1. Its selling point was a box abstraction (a persisted Map<String, dynamic>) with synchronous reads, optional AES-256 encryption, and a code-generated TypeAdapter system for storing custom objects. For years it was the default local-storage choice for Flutter apps that needed more than shared_preferences but did not want SQL.
The important thing a reader must understand before adopting Hive today is that there are effectively two different databases under one name. The classic line (1.x and 2.x) is the pure-Dart, in-memory-indexed engine most tutorials and Stack Overflow answers describe. The 4.x line is a ground-up rewrite that makes Hive a lightweight wrapper around Isar — the same author's native database engine2 — and therefore ships native binaries (isar_flutter_libs), changes the public API, and drops the code-generation model. The two are not drop-in compatible.
The second thing to understand is momentum. The repository (transferred from hivedb/hive to isar/hive) has not seen a substantive push since mid-2024, carries several hundred open issues, and its 4.x release has sat in a -dev prerelease state for an extended period. Hive is widely deployed and stable in its 2.x form, but active engineering attention has moved to Isar. Treat it as mature-and-quiet, not actively-developed.
Getting Started
Classic (2.x), pure Dart, code-generated adapters:
dependencies:
hive: ^2.2.3
hive_flutter: ^1.1.0
dev_dependencies:
hive_generator: ^2.0.1
build_runner: ^2.4.0
import 'package:hive_flutter/hive_flutter.dart';
Future<void> main() async {
await Hive.initFlutter();
final box = await Hive.openBox('settings'); // async open
await box.put('theme', 'dark');
print(box.get('theme')); // synchronous read: dark
}
4.x (wrapper over Isar, native binaries, no code generation):
dependencies:
hive: ^4.0.0-dev.2
isar_flutter_libs: ^4.0.0-dev.13
path_provider: ^2.1.0
import 'package:hive/hive.dart';
void main() {
Hive.defaultDirectory = '/path/from/path_provider';
final box = Hive.box(name: 'settings'); // synchronous open
box.put('theme', 'dark');
print(box.get('theme')); // dark
}
Architecture / How It Works
Classic (1.x / 2.x). A box is an append-only log file on disk. Writes append new entries; the whole set of keys and their current values is held in memory, which is what makes get synchronous and fast. This is the design's core tradeoff: read latency is excellent, but a box's memory footprint scales with its contents, so large datasets bloat RAM. LazyBox addresses this by keeping only keys in memory and reading values from disk on demand, at the cost of async get. Because writes only append, the file grows until a compaction pass rewrites it to drop superseded entries. Custom objects require a TypeAdapter, normally generated by hive_generator + build_runner and registered with a stable, never-reused typeId.
4.x. The rewrite discards nearly all of the above. Hive 4 delegates storage to Isar's native core, so a "box" is backed by an Isar (.isar) or SQLite database file rather than the pure-Dart append log2. Native libraries are now a hard dependency, which changes the platform/build story (no more zero-native claim). Object serialization moves from generated TypeAdapters to plain fromJson/toJson methods registered via Hive.registerAdapter('Name', Name.fromJson). openBox becomes the synchronous Hive.box(name: ...), and transactions use box.write(() {...}) / box.read(() {...}) blocks that are atomic — either every mutation in the closure commits or none does.
Encryption in both lines uses 256-bit AES in CBC mode, applied per database page, gated on supplying an encryptionKey. The key is never stored by Hive; losing it means losing the data.
Production Notes
- Two databases, one name. Most search results, courses, and LLM training
data describe 2.x (Hive.openBox, TypeAdapter, part 'x.g.dart'). Code written against 4.x looks different and will not compile against 2.x, and vice versa. Confirm which major version a snippet targets before copying it.
- Migration 2.x → 4.x is not automatic. There is no in-place upgrade path
that reads an old binary box into the Isar-backed engine transparently; teams generally re-export and re-import. Budget for it rather than treating it as a version bump.
- Repository is quiet. No substantive commits since mid-2024 and a large open
issue backlog. Bugfixes and platform-compat updates may not land promptly. Pin versions and test thoroughly on new Flutter/Dart SDKs.
- 4.x is still a prerelease. The 4.0.0 line has lived under
-devtags for a
long time. It works for many, but "stable release" guarantees (semver, changelog discipline) are weaker than a .0 would imply. For risk-averse production, 2.x is the more battle-tested choice despite being the older design.
- Memory footprint (classic). A regular
Boxholds all values in RAM. Storing
large blobs or tens of thousands of rich objects can surprise you on memory-constrained devices — use LazyBox, or store large binaries as files and keep only paths in Hive.
typeIdis forever (classic). Reusing or renumbering aTypeAdapter
typeId silently corrupts reads of existing data. Treat the id space as an append-only registry.
- Synchronous API, single thread. Classic reads/writes run on the calling
isolate. Heavy operations can jank the UI thread; offload with compute() / Isolate.run() (4.x adds a convenience Hive.compute()).
When to Use / When Not
Use when:
- You want a simple, fast, local key-value store for Flutter without SQL or a
server.
- Your dataset is modest and fits comfortably in memory (classic 2.x).
- You want built-in at-rest encryption with minimal ceremony.
- You already ship 2.x in production and it meets your needs — there is little
reason to churn.
Avoid when:
- You need queries, indexes, relations, or full-text search — that is Isar's job,
not Hive's.
- You are starting a new project and want an actively maintained engine — the
author's attention is on Isar.
- You store large datasets on low-memory devices and cannot restructure around
LazyBox or external files.
- You need strong stability guarantees and are considering 4.x while it remains a
-dev prerelease.
Alternatives
- isar/isar — the successor engine by the same author; use when you need queries,
indexes, relations, or async access at scale.
- tekartik/sqflite — SQLite for Flutter; use when you want real relational SQL and
a well-understood storage engine.
- simolus3/drift — reactive, type-safe SQL layer over SQLite; use when you want
compile-checked queries and streaming results.
- objectbox/objectbox-dart — native object database with queries and relations;
use when you want ORM-style objects with strong performance.
- flutter/packages (shared_preferences) — use when you only need a handful of
simple config values, not a database.
History
| Version | Date | Notes |
|---|---|---|
| initial | 2019 | Repository created; pure-Dart key-value store for Flutter1. |
| 1.x | 2020 | Boxes, TypeAdapter code generation, AES encryption. |
| 2.x | 2021 | Widely adopted stable line; null-safety, hive_flutter integration. |
| 4.0.0-dev | 2023–2024 | Rewrite as a wrapper over Isar; native libs, fromJson/toJson adapters, synchronous Hive.box()2. |
| — | mid-2024 | Repository goes quiet; focus shifts to Isar. Last significant push 2024-06. |
References
- ^ Hive package on pub.dev — description and API. https://pub.dev/packages/hive
- ^ Hive README, "Hive or Isar?" — "Hive is a lightweight wrapper around Isar." https://github.com/isar/hive#readme
Tags
dart, flutter, database, key-value, nosql, local-storage, encryption, mobile, isar, embedded-database