S
Store

SQLite Adapter

Embedded SQLite storage with WAL mode, zero configuration, and full offline support.

Overview

SQLite is the default adapter for Store. It stores data in a single file on disk with no external process required. This makes it ideal for desktop apps, mobile apps, CLI tools, and local-first workflows where simplicity matters.

Setup

import { createStore } from "@cuitty/store/client";

const store = await createStore({
  module: "my-app",
  profile: {
    id: "local-sqlite",
    name: "Local SQLite",
    local: { adapter: "local.sqlite", path: "./data/my-app.db", backend: "wasm-sqlite" },
    remotes: [],
    routes: [],
    encryption: { atRest: "preferred", remote: "disabled", p2p: "disabled" },
    sync: { mode: "manual" },
  },
  schema: { users: { class: "record" } },
});

If the file does not exist, Store creates it along with the required schema tables. If it already exists, Store validates the schema version and runs migrations if needed.

Configuration options

const store = await createStore({
  module: "my-app",
  profile: {
    id: "sqlite-contract",
    name: "SQLite Contract",
    local: {
      adapter: "local.sqlite",
      path: "./data/my-app.db",
      backend: "wasm-sqlite",
    },
    remotes: [],
    routes: [],
    encryption: { atRest: "preferred", remote: "disabled", p2p: "disabled" },
    sync: { mode: "manual" },
  },
});

WAL mode

Write-Ahead Logging (WAL) is enabled by default. WAL allows concurrent readers while a write is in progress, which significantly improves performance for stores that are read-heavy. Store sets PRAGMA journal_mode=WAL on first connection.

In WAL mode, SQLite creates two companion files (-wal and -shm) alongside the main database file. These are normal operation artifacts and should not be deleted manually.

Performance tips

  • Batch writes: Keep related writes close together and flush once with store.sync.flush().
  • Indexed queries: Define schema indexes and use record().query({ where }) for exact-match reads.
  • Format checks: Use the SQLite inspection and conversion commands before switching between contract JSON and wasm SQLite backends.
const users = store.record("users");
await users.put("user:1", { name: "Alice" });
await users.put("user:2", { name: "Bob" });
await users.put("user:3", { name: "Carol" });
await store.sync.flush();

File locking

SQLite uses file-level locking. Only one process can write at a time. If you need multiple processes to write concurrently, consider the Postgres adapter or run a single writer process with multiple reader processes.

Supported store classes

local.sqlite supports the local storage classes used by the client profile. For large binary objects, route blob or media classes to an object adapter such as S3.