P
Persist

Adapters

Pluggable storage backends that let you swap between SQLite, Postgres, S3, and P2P without changing application code.

What is an adapter?

An adapter is a storage backend implementation that conforms to the Persist adapter interface. Your application code uses the same store.records.put() / store.records.get() API regardless of which adapter is active. Swapping from SQLite to Postgres requires only a configuration change.

// SQLite (local)
const local = await createStore("app", {
  adapter: "sqlite",
  path: "./data/app.db",
});

// Postgres (remote) — same API
const remote = await createStore("app", {
  adapter: "postgres",
  connectionString: "postgresql://user:pass@host:5432/persist",
});

Adapter registry

Persist discovers adapters through a registry. Built-in adapters are available by name. Third-party adapters can be registered by passing the adapter class directly.

import { registerAdapter } from "@cuitty/persist";
import { RedisAdapter } from "persist-adapter-redis";

registerAdapter("redis", RedisAdapter);

const store = await createStore("cache", {
  adapter: "redis",
  url: "redis://localhost:6379",
});

Capability matrix

Not every adapter supports every store class. The capability matrix shows what each built-in adapter provides:

AdapterRecordsEventsBlobsKVSync
SQLiteYesYesYesYesPush
PostgresYesYesNoYesFull
S3NoNoYesNoPull
P2PYesYesNoYesFull

When you use a store class that the adapter does not support, Persist throws a CapabilityError at store creation time rather than silently failing at runtime.

Choosing an adapter

  • SQLite is the default for local-first applications. Zero configuration, embedded, WAL-mode for concurrent reads.
  • Postgres is suited for server-side workloads or when you need full-text search and relational queries.
  • S3 (and S3-compatible services like R2) handles large binary objects.
  • P2P enables direct device-to-device replication over libp2p without a central server.

See the individual adapter guides for detailed setup instructions.