cocomon

Choosing a runtime

Pick the right adapter and migration strategy for backend, local SQLite, Flutter, and tests.

Choosing a runtime

comon_orm gives you one generated client shape across several runtime adapters. The important choice is not only the database engine, but also who owns rollout.

Quick matrix

SituationRuntimeRollout strategy
Backend API with shared databasePostgreSQL or shared SQLiteReviewed CLI migrations
CLI tool or local VM appSQLiteReviewed migrations or explicit bootstrap
Flutter app with device-local dataFlutter SQLiteExplicit app-side upgrade before runtime open
Tests and examplesIn-memoryNo migration step; runtime metadata is enough

PostgreSQL

Choose PostgreSQL when:

  • the database is shared
  • concurrent application access matters
  • you need stronger in-place migration behavior than SQLite can offer
  • enums, richer native types, and operational tooling matter

Typical runtime path:

final db = await GeneratedComonOrmClientPostgresql.open();

Typical rollout path:

dart run comon_orm migrate dev --name 20260318_add_roles
dart run comon_orm migrate deploy

VM SQLite

Choose VM SQLite when:

  • the app runs locally on Dart VM or the server
  • the database is file-backed and simple to operate
  • you want the same generated client shape as PostgreSQL with a smaller local footprint

Typical runtime path:

final db = await GeneratedComonOrmClientSqlite.open();

Use the reviewed CLI flow when the SQLite file is shared or long-lived. For disposable local development data, explicit bootstrap can be enough.

Flutter SQLite

Choose Flutter SQLite when:

  • the app owns a device-local SQLite file
  • runtime goes through sqflite / sqflite_common
  • upgrades must happen on-device before the generated runtime opens the file

Typical runtime path:

await upgradeSqliteFlutterDatabase(
  databasePath: 'app.db',
  migrator: migrator,
);

final db = await GeneratedComonOrmClientFlutterSqlite.open(
  databasePath: 'app.db',
);

This is intentionally different from the shared-database CLI workflow.

In-memory

Choose in-memory when:

  • writing tests
  • prototyping generated-client behavior
  • validating relation semantics without filesystem or network setup

Typical runtime path:

final db = GeneratedComonOrmClient.openInMemory();

This path uses generated runtime metadata and is usually the fastest route for unit and integration tests.

Choosing the runtime is also choosing the operational model

The biggest mistakes happen when a project picks the right adapter but the wrong rollout story. Shared databases want reviewed migrations. Device-local Flutter databases want explicit app-side upgrades.

Continue with

On this page