Overview
Where durable state lives. A StateStore interface with MikroORM, TypeORM, Prisma and Drizzle adapters that run on Postgres, MySQL, SQLite or libSQL, an in-memory store for tests, and auto-schema on boot (opt-out, with a migration helper).
A state store persists workflow runs and step checkpoints — the source of truth for both
durability and the dashboard. It's a pluggable StateStore
interface, independent of the transport.
Writing a custom store? The interface includes renewRunLock(runId, owner, leaseUntilMs) (for
lease renewal while a run executes)
and listPendingRuns(limit) (so workers can poll for pending
runs to dispatch). All bundled adapters implement both.
Adapters
Each adapter has its own page with the full setup — register/copy the schema, wire the store, and own migrations:
| Store | Database | Schema | |
|---|---|---|---|
InMemoryStateStore (in core) | — | — | For tests and local dev. Not durable. |
| MikroORM | Postgres · MySQL · SQLite | auto-schema or ensure* | The reference adapter. |
| TypeORM | Postgres · MySQL/MariaDB · SQLite | auto-schema or ensure* | Register ENTITIES on your DataSource. |
| Prisma | any Prisma datasource | Prisma Migrate | Add the models, prisma generate, pass your PrismaClient. |
| Drizzle | SQLite / libSQL (Turso, edge) | drizzle-kit | Build your db with the package's schema. |
The MikroORM and TypeORM adapters work on any SQL database their ORM supports — Postgres, MySQL or SQLite (timestamps use native datetime columns, so epoch values never overflow). The quickest wire is one factory:
import { MikroOrmStateStore } from '@dudousxd/nestjs-durable-store-mikro-orm';
DurableModule.forRootAsync({
inject: [MikroORM],
useFactory: (orm) => ({ store: new MikroOrmStateStore(orm), transport }),
});Auto-schema
For the MikroORM and TypeORM adapters, the module creates the durable tables on boot
(durable_workflow_runs, durable_step_checkpoints, durable_run_attributes,
durable_signal_waiters, durable_buffered_signals) — zero setup in dev. Turn it off in production
and own the schema via a migration:
DurableModule.forRoot({ store, autoSchema: false });Each of those two adapters exports the exact function to call from your own migration —
ensureMikroOrmDurableSchema(orm) and ensureTypeOrmDurableSchema(dataSource). See the
MikroORM and
TypeORM pages for the full
migration snippets. It only ever adds the durable tables — it never touches yours.
The Prisma and Drizzle adapters have no auto-schema: their ORMs already own your schema and
migration history, so you create the durable tables with prisma migrate / drizzle-kit (the
autoSchema option is a no-op for them).
SQL (database)
A broker-less, DBOS-style transport — remote steps are rows in the database you already run. Workers claim tasks with SELECT … FOR UPDATE SKIP LOCKED. The table + claim contract is documented so Node and Python workers share it.
MikroORM
The reference StateStore adapter. Register the durable entities with your MikroORM config, pass the ORM to MikroOrmStateStore, and run on Postgres, MySQL or SQLite — with auto-schema on boot or an ensure* helper for your own migration.