resqlite

High-performance, reactive SQLite for Dart & Flutter.
Plain SQL. Stream anything. Zero main-isolate jank.

MIT License iOS · Android · macOS · Linux · Windows Dart 3.10+ No ORM · No codegen
1.8x
faster select()
(1K rows)
2.1x
faster writes
(single inserts)
1 ms
main-thread cost
(10K row read)
107K
point queries
per second

Compared against peer Dart SQLite libraries. See full benchmarks →

📖

API Reference

Full dartdoc-generated documentation for every public class, method, and property.

Benchmarks

Interactive charts comparing resqlite, sqlite3, and sqlite_async across reads, writes, streaming, and more.

🔬

Experiments

40 optimization experiments with performance-over-time charts. Click any data point to see what changed.

📝

Architecture Blog

How resqlite works under the hood — the reader pool, writer isolate, streaming engine, and the engineering story.

🛠

Source Code

Browse the repo, open issues, and contribute on GitHub.

🚀

Getting Started

Installation, setup, and usage examples to get up and running.

Quick look

final db = await Database.open('app.db');

// Queries run on background isolates — zero UI jank.
final users = await db.select(
  'SELECT * FROM users WHERE active = ?',
  [1],
);

// Row objects are lazy views — only accessed rows get materialized.
for (final user in users) {
  print('${user['name']}: ${user['email']}');
}
// Single write — runs on a dedicated writer isolate.
final result = await db.execute(
  'INSERT INTO users(name, email) VALUES (?, ?)',
  ['Ada', 'ada@example.com'],
);
print('Inserted row ${result.lastInsertId}');

// Batch write — one prepare, one commit, no per-row overhead.
await db.executeBatch(
  'INSERT INTO users(name) VALUES (?)',
  [['Ada'], ['Grace'], ['Sonja']],
);
// Turn any query into a live stream.
// Table dependencies detected automatically — works with
// JOINs, subqueries, views, and CTEs.
db.stream(
  'SELECT * FROM users WHERE active = ?',
  [1],
).listen((users) {
  setState(() => this.users = users);
});

// Identical queries are deduplicated.
// Unchanged results are suppressed.
// Re-queries fire on write commit — sub-millisecond.
// Atomic transactions — reads see uncommitted writes.
final count = await db.transaction((tx) async {
  await tx.execute(
    'INSERT INTO users(name) VALUES (?)',
    ['Sonja'],
  );
  final rows = await tx.select(
    'SELECT COUNT(*) as c FROM users',
  );
  return rows.first['c'];
});

// Nested transactions use SQLite SAVEPOINTs.
// JSON serialized entirely in C — zero Dart object allocation.
// Perfect for HTTP server responses.
final bytes = await db.selectBytes(
  'SELECT id, name, price FROM products WHERE active = ?',
  [1],
);

// bytes is a Uint8List of JSON — ready to write to a socket.
return Response.ok(
  bytes,
  headers: {'content-type': 'application/json'},
);