Skip to content

SQLite Storage Adapter (@invariant-tech/sqlite) ​

SQLite is the simplest durable local store for development, tests, single-host services, and small deployments.

Install and Configure ​

bash
npm install @invariant-tech/sdk@beta @invariant-tech/sqlite@beta
ts
import { invariant } from "@invariant-tech/sdk";
import { sqlite } from "@invariant-tech/sqlite";

const store = sqlite({
  filename: "./data/invariant.db",
  durability: "strict",
  busyTimeoutMs: 5_000,
});

export const app = invariant({ storage: store });

The string shorthand is equivalent to { filename }:

ts
const app = invariant({ storage: sqlite("./data/invariant.db") });

Use sqlite(":memory:") for isolated tests.

Storage Behavior ​

  • Schema migrations run when SqliteRuntimeStore is constructed.
  • File-backed databases enable WAL journaling.
  • durability: "normal" uses SQLite synchronous=NORMAL.
  • durability: "strict" uses synchronous=FULL.
  • Foreign-key enforcement is enabled.
  • Execution state, event history, commands, leases, and durable Session context implement the common RuntimeStore contract. Only file-backed SQLite survives process loss; :memory: does not.

Persistence is not automatic continuation. See the canonical Recovery Contract Matrix.

Schema Migrations and Data Lifecycle ​

The constructor creates invariant_schema_migrations and applies unapplied migrations in strictly increasing version order. Duplicate, non-positive, or out-of-order versions are rejected before DDL is applied. Built-in v1 creates the five runtime tables and indexes; application migrations may follow it with immutable higher versions.

See Database Schema & Data Lifecycle for the physical schema, how state/events/commands/Sessions are written, custom migrations, backup and restore, and retention behavior.

Close the Store ​

ts
await store.close();

Close the store during graceful application shutdown. Do not close it while Sessions are executing commands.

Move to PostgreSQL ​

Workflow definitions do not depend on the physical store, but persisted SQLite rows are not automatically copied. Provision PostgreSQL with initializeSchema(), stop writes, migrate application-required history with an explicit migration process, then change the configured store.

ts
import { PostgresRuntimeStore } from "@invariant-tech/postgres";

const store = new PostgresRuntimeStore({
  connectionString: process.env.DATABASE_URL,
});
await store.initializeSchema();

const app = invariant({ storage: store });

Next Steps ​

Invariant Durable Execution Engine.