Choose an engine¶
dORM is a portable ORM: it gives recurring application operations a shared, generated surface while allowing the storage system to remain explicit. Choose an engine when you want that common surface around a backend your application already uses, or when you want to start with a local engine and move to a server-backed one later.
The trade-off is deliberate. dORM is more portable than a backend-specific
ORM, but less expressive than the native API of each backend. The generated
Dorm and repository API are shared across engines; the engine turns those
operations into reads, writes, filters, relationships, and streams for a
specific storage system.
Compare the setup boundary¶
Engine |
Storage or runtime | What the application supplies |
|---|---|---|
| In-memory | Pure Dart in-process memory | A reusable Engine() instance |
| BLoC | In-memory BLoC state | A reusable Engine() instance |
| Firebase | Firebase Realtime Database | Initialized Firebase services and database configuration; the showcase generator also provides a local emulator profile |
| Firestore | Cloud Firestore | Initialized Firebase services and FirebaseFirestore; the showcase generator also provides a local emulator profile |
| MySQL | MySQL through mysql_client |
An opened MySQLConnection |
| PostgreSQL | PostgreSQL through postgres |
An opened Connection or Pool |
| MongoDB | MongoDB through mongo_dart |
An opened Db |
| HTTP/JSON | A REST-shaped service | An owned http.Client, base URI, and resource mapping; the showcase generator can provide a local demo server |
| SQLite | SQLite through sqlite_async |
An application-owned SqliteDatabase |
The application owns the lifecycle of the backend object when the engine
accepts one. The engine does not automatically open or close an application-
owned database connection, Db, or HTTP client.
Warning
The repository API is portable, but it does not expose every feature of every backend. Check the engine page before relying on transactions, reactive streams, schema generation, or backend-specific query features.
The framework does not select an engine automatically. The generated Dorm
receives the concrete engine through its constructor.
Choose by backend and capability¶
Choose the engine that matches the backend boundary and the capabilities your application needs. Do not choose an engine expecting it to reproduce every feature of another backend. Check the capability table before relying on transactions, reactive streams, advanced filters, generated identities, or schema behavior.
Use the common repository API for recurring operations. Keep native SQL, Firebase calls, MongoDB selectors, or HTTP-specific behavior beside dORM when the backend needs more expressiveness than the portable surface provides.
To create a complete project with the selected setup, use the showcase project generator. Its profiles follow the platform and capability boundaries listed on this page: Flutter profiles are generated for in-memory, BLoC, Firebase, Firestore, and HTTP; pure Dart profiles are generated for PostgreSQL, MySQL, MongoDB, and SQLite.
Select by runtime need¶
Use the in-memory engine for a pure Dart application that needs an in-process store without a database server. Use BLoC when local state must use the BLoC integration. Use Firebase for a Flutter/Firebase Realtime Database application. Use Cloud Firestore for a Flutter application that stores documents in Firestore and needs its queries, listeners, batches, or internal transactions.
Use MySQL or PostgreSQL when the
database is relational and SQL is part of the application's storage boundary.
Use MongoDB for document storage. Use HTTP/JSON
when the application talks to a REST-shaped API rather than directly to a
database. Use SQLite for local relational storage through the
asynchronous sqlite_async API.
Keep the application surface stable¶
The generated facade receives the engine and exposes the same entity accessors:
final Dorm<Query, OffsetPageRequest> dorm = Dorm(engine);
final User created = await dorm.users.repository.put(
Creation.auto(
dependency: const UserDependency(),
data: userData,
),
);
final List<Product> products = await dorm.products.repository.peekAll(
Filter.value('Notebook', field: ProductEntity.fields.name),
);
The concrete engine changes how these operations reach storage. The generated
Data, Model, Dependency, entity, filter, and relationship types keep the
same application role.
Compare the current capability boundaries¶
| Capability | In-memory | BLoC | Firebase | Firestore | MySQL | PostgreSQL | MongoDB | HTTP | SQLite |
|---|---|---|---|---|---|---|---|---|---|
| External server required | No | No | Firebase project or emulator | Firebase project or emulator | Yes | Yes | Yes | HTTP API | No |
| Streams | State-backed | State-backed | Firebase value events | Firestore snapshots | Initial read only | Initial read only | Initial read only | Initial read only | SQLite table watches |
Filter execution |
In-memory evaluation | In-memory evaluation | Firebase query | Firestore query | SQL query | PostgreSQL SQL query | MongoDB selector | URL parameters | SQLite SQL query |
| Comparisons and set membership | Yes | Yes | Basic filters only | Where supported by Firestore | Yes | Yes | Yes | Not declared | Yes |
allOf / anyOf |
Yes | Yes | No | Where supported by Firestore | Yes | Yes | Yes | Not declared | Yes |
not |
Yes | Yes | No | No general support | Yes | Yes | Yes | Not declared | Yes |
| Collection membership | Yes | Yes | No | Where supported by Firestore | No | No | Yes | Not declared | No |
| Public transaction API | Yes | Yes | No | No | Yes | Yes | No | No | Yes |
| Pagination | Offset pages | Offset pages | Offset pages with client-side skipping | Offset pages with client-side skipping | Offset pages | Offset pages | Offset pages | Offset pages | Offset pages |
| Composite creation | Explicit identity required | Explicit identity required | Unsupported | Unsupported | Explicit identity required | Explicit identity required | Explicit identity required | Explicit identity required | Explicit identity required |
This table describes current engine behavior. It does not promise that future versions will preserve every backend capability or limitation.
The additional filter rows describe typed query capabilities, not client-side
fallbacks. A No entry means the engine does not advertise that capability;
the repository will not download a larger result set to imitate it.
Continue with the engine page¶
After choosing a backend, follow its setup page. The pages include the package commands, lifecycle boundary, schema or mapping requirements, and behavior that differs from the common repository API.