Skip to main content
@livestore/adapter-node runs LiveStore in Node.js with SQLite-backed persistence on the filesystem. It exposes two adapters:
  • makeAdapter — single-threaded; leader logic runs in the same thread as your application
  • makeWorkerAdapter — multi-threaded; leader logic (persistence, sync, SQLite) runs in a separate worker thread

Installation

npm install @livestore/adapter-node

Exports

import { makeAdapter, makeWorkerAdapter } from '@livestore/adapter-node'

makeAdapter

Creates a single-threaded Node.js adapter. The leader thread (persistence and sync) runs in the same thread as your application. Use this for CLI tools, scripts, and simple applications where simplicity matters more than throughput.
function makeAdapter(options: NodeAdapterOptions & { sync?: SyncOptions }): Adapter

Parameters

options.storage
StorageType
required
Filesystem storage configuration:
storage: { type: 'fs', baseDirectory: './data' }
Data is stored at {baseDirectory}/{storeId}/.
options.sync
SyncOptions
Optional sync backend for multi-device synchronization.
options.clientId
string
Stable identifier for this Node.js process. Defaults to the machine hostname.
options.sessionId
string
default:"'static'"
Session identifier. The adapter does not currently support multiple concurrent sessions per client.
options.resetPersistence
boolean
default:"false"
Deletes all persisted data for this store on startup. Use only during development.
options.devtools
object
Enable the LiveStore DevTools server.

Example

import { createStorePromise, storeOptions } from '@livestore/livestore'
import { makeAdapter } from '@livestore/adapter-node'
import { makeWsSync } from '@livestore/sync-cf/client'
import { schema } from './schema'

const adapter = makeAdapter({
  storage: { type: 'fs', baseDirectory: './data' },
  sync: {
    backend: makeWsSync({ url: 'wss://sync.example.com' }),
  },
})

const store = await createStorePromise(
  storeOptions({ schema, adapter, storeId: 'my-app' })
)

makeWorkerAdapter

Creates a multi-threaded Node.js adapter. The leader thread runs in a separate worker_threads worker, keeping your main thread responsive. Use this for production servers and performance-critical applications.
function makeWorkerAdapter(
  options: NodeAdapterOptions & {
    workerUrl: URL
    workerExtraArgs?: Schema.JsonValue
  }
): Adapter

Parameters

options.workerUrl
URL
required
URL of the worker file. Use import.meta.url to make it relative to the current file:
workerUrl: new URL('./livestore.worker.ts', import.meta.url)
options.storage
StorageType
required
Same as makeAdapter.
options.workerExtraArgs
Schema.JsonValue
Extra arguments passed to the worker, accessible in the worker via getWorkerArgs().
All other options from NodeAdapterOptions also apply.

Worker file setup

Create a worker file that calls makeWorker:
livestore.worker.ts
import { makeWorker } from '@livestore/adapter-node/worker'
import { schema } from './schema'

makeWorker({ schema })

Full example

app.ts
import { createStorePromise, storeOptions } from '@livestore/livestore'
import { makeWorkerAdapter } from '@livestore/adapter-node'
import { schema } from './schema'

const adapter = makeWorkerAdapter({
  storage: { type: 'fs', baseDirectory: './data' },
  workerUrl: new URL('./livestore.worker.ts', import.meta.url),
})

const store = await createStorePromise(
  storeOptions({ schema, adapter, storeId: 'my-app' })
)

Worker exports

@livestore/adapter-node/worker exports:

makeWorker

Bootstraps the leader worker thread. Call once in your worker file.
function makeWorker(options: WorkerOptions): void
options.schema
LiveStoreSchema
required
The schema to use in the leader thread.
options.sync
SyncOptions
Optional sync backend.

getWorkerArgs

Reads the arguments passed from the main thread via workerExtraArgs:
function getWorkerArgs(): WorkerArgv

Peer dependencies

PackageVersion
effect^3.19.19

Build docs developers (and LLMs) love