flutter_easy_db

A secure, easy-to-use encrypted local database for Flutter with two modes:

  1. EasyDbNoSql — Isar-style document database (schema-free, simple put/get/query)
  2. EasyDbSql — Drift-style relational database (typed tables, joins, foreign keys, migrations)

Both use AES-256 encryption for secure data at rest.

Installation

dependencies:
  flutter_easy_db: ^1.0.0

EasyDbNoSql (Isar-style)

Schema-free document store. No table definitions needed.

final db = await EasyDbNoSql.open(
  EasyDbConfig(
    dbName: 'my_app',
    encryptionKey: 'my-32-character-secret-key!!!!!', // exactly 32 chars
  ),
);

final users = db.collection('users');

// Insert
await users.put({'name': 'Alice', 'age': 30});

// Query
final results = await users.query()
  .where('age', isGreaterThan: 25)
  .where('name', contains: 'li')
  .sortBy('age', descending: true)
  .limit(10)
  .find();

// Watch (reactive)
users.watch().listen((docs) => print('Changed!'));

await db.close();

NoSQL API

Method Description
collection.put(data, {id}) Insert or update a document
collection.putAll(items) Batch insert
collection.get(id) Get by ID
collection.getAll() Get all
collection.delete(id) Delete by ID
collection.clear() Clear collection
collection.count() Count documents
collection.query() Fluent query builder
collection.watch() Reactive stream

EasyDbSql (Drift-style)

Typed relational tables with schemas, foreign keys, joins, and migrations.

// Define schemas
final usersSchema = EasyTableSchema(
  name: 'users',
  columns: [
    EasyColumn(name: 'id', type: ColumnType.integer, isPrimaryKey: true, autoIncrement: true),
    EasyColumn(name: 'name', type: ColumnType.text),
    EasyColumn(name: 'email', type: ColumnType.text, isUnique: true),
    EasyColumn(name: 'age', type: ColumnType.integer),
  ],
);

final postsSchema = EasyTableSchema(
  name: 'posts',
  columns: [
    EasyColumn(name: 'id', type: ColumnType.integer, isPrimaryKey: true, autoIncrement: true),
    EasyColumn(name: 'title', type: ColumnType.text),
    EasyColumn(name: 'user_id', type: ColumnType.integer,
      foreignKey: ForeignKey(referenceTable: 'users', referenceColumn: 'id'),
    ),
  ],
);

// Open
final db = await EasyDbSql.open(
  EasyDbConfig(dbName: 'my_app', encryptionKey: 'my-32-character-secret-key!!!!!'),
  tables: [usersSchema, postsSchema],
);

// Get table — optionally encrypt specific columns
final users = db.table('users', encryptedColumns: ['email']);

// Insert
final userId = await users.insert({'name': 'Alice', 'email': 'alice@example.com', 'age': 30});

// Select with WHERE
final results = await users.select()
  .where('age > ?', [25])
  .orderBy('name ASC')
  .limit(10)
  .run();

// JOIN
final joined = await users.select(columns: ['users.name', 'posts.title'])
  .join('posts', on: 'users.id = posts.user_id')
  .run();

// Update / Delete
await users.update({'age': 31}, where: 'name = ?', whereArgs: ['Alice']);
await users.delete(where: 'name = ?', whereArgs: ['Bob']);

await db.close();

SQL API

Method Description
table.insert(row) Insert a row
table.insertAll(rows) Batch insert
table.update(values, where:) Update matching rows
table.delete(where:) Delete matching rows
table.deleteAll() Delete all rows
table.count() Count rows
table.select() Start a SELECT query
table.watch() Reactive stream
db.rawQuery(sql) Raw SQL query
db.transaction(fn) Run in transaction
db.addTable(schema) Add table at runtime
db.dropTable(name) Drop a table

SELECT Query Builder

table.select(columns: ['name', 'age'])
  .where('age > ?', [18])
  .join('posts', on: 'users.id = posts.user_id')
  .leftJoin('comments', on: 'posts.id = comments.post_id')
  .orderBy('name ASC')
  .limit(20)
  .offset(10)
  .run();       // List<Map<String, dynamic>>
  .runFirst();  // Map<String, dynamic>?

Security

  • AES-256-CBC encryption with SHA-256 key derivation
  • NoSQL: entire document encrypted as one blob
  • SQL: choose which columns to encrypt (e.g. email, phone)
  • Each encryption uses a unique random IV (prevents pattern analysis)
  • Key never stored on disk
  • Pass null for encryptionKey to disable (dev mode)

Architecture

┌─────────────────────────────────────────────┐
│             Your Flutter App                │
├──────────────────┬──────────────────────────┤
│  EasyDbNoSql     │  EasyDbSql              │
│  (Isar-style)    │  (Drift-style)          │
│  put/get/query   │  insert/select/join     │
├──────────────────┴──────────────────────────┤
│         AES-256 Encryption Layer            │
├─────────────────────────────────────────────┤
│              SQLite (sqflite)               │
└─────────────────────────────────────────────┘

License

MIT

Libraries

flutter_easy_db
flutter_easy_db - A secure, easy-to-use encrypted local database for Flutter.