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.