Skip to content

Node

import {
const makeAdapter: ({ sync, ...options }: NodeAdapterOptions & {
sync?: SyncOptions;
}) => Adapter

Creates a single-threaded LiveStore adapter for Node.js applications.

This adapter runs the leader thread (persistence and sync) in the same thread as your application. Suitable for CLI tools, scripts, and applications where simplicity is preferred over maximum performance.

For production servers or performance-critical applications, consider makeWorkerAdapter which runs persistence/sync in a separate worker thread.

@example

import { makeAdapter } from '@livestore/adapter-node'
import { makeWsSync } from '@livestore/sync-cf/client'
const adapter = makeAdapter({
storage: { type: 'fs', baseDirectory: './data' },
sync: {
backend: makeWsSync({ url: 'wss://api.example.com/sync' }),
},
})

@example

// With DevTools support
const adapter = makeAdapter({
storage: { type: 'fs', baseDirectory: './data' },
devtools: {
schemaPath: new URL('./schema.ts', import.meta.url),
port: 4242,
},
})

@seehttps://livestore.dev/docs/reference/adapters/node for setup guide

makeAdapter
} from '@livestore/adapter-node'
import {
import schema
schema
,
import tables
tables
} from './livestore/schema.ts'
const
const adapter: Adapter
adapter
=
function makeAdapter({ sync, ...options }: NodeAdapterOptions & {
sync?: SyncOptions;
}): Adapter

Creates a single-threaded LiveStore adapter for Node.js applications.

This adapter runs the leader thread (persistence and sync) in the same thread as your application. Suitable for CLI tools, scripts, and applications where simplicity is preferred over maximum performance.

For production servers or performance-critical applications, consider makeWorkerAdapter which runs persistence/sync in a separate worker thread.

@example

import { makeAdapter } from '@livestore/adapter-node'
import { makeWsSync } from '@livestore/sync-cf/client'
const adapter = makeAdapter({
storage: { type: 'fs', baseDirectory: './data' },
sync: {
backend: makeWsSync({ url: 'wss://api.example.com/sync' }),
},
})

@example

// With DevTools support
const adapter = makeAdapter({
storage: { type: 'fs', baseDirectory: './data' },
devtools: {
schemaPath: new URL('./schema.ts', import.meta.url),
port: 4242,
},
})

@seehttps://livestore.dev/docs/reference/adapters/node for setup guide

makeAdapter
({
NodeAdapterOptions.storage: {
readonly type: ["in-memory"];
readonly importSnapshot?: any;
} | {
readonly type: ["fs"];
readonly baseDirectory?: string | undefined;
}
storage
: {
type: string
type
: 'fs' },
// sync: { backend: makeWsSync({ url: 'ws://localhost:8787' }) },
})
const
const main: () => Promise<void>
main
= async () => {
const
const store: Store<any, {}>
store
= await
createStorePromise<any, {}, Codec<Json, Json, never, never>>({ signal, otelOptions, ...options }: CreateStoreOptionsPromise<any, {}, Codec<Json, Json, never, never>>): Promise<Store<any, {}>>

Create a new LiveStore Store

createStorePromise
({
CreateStoreOptions<TSchema extends LiveStoreSchema, TContext = {}, TSyncPayloadSchema extends Codec<Json, Json> = Codec<Json, Json, never, never>>.adapter: Adapter

Adapter used for data storage and synchronization.

adapter
,
CreateStoreOptions<any, {}, Codec<Json, Json, never, never>>.schema: any

The LiveStore schema defining tables, events, and materializers.

schema
,
CreateStoreOptions<TSchema extends LiveStoreSchema, TContext = {}, TSyncPayloadSchema extends Codec<Json, Json> = Codec<Json, Json, never, never>>.storeId: string

Unique identifier for the Store instance, stable for its lifetime.

  • Valid characters: Only alphanumeric characters, underscores (_), and hyphens (-) are allowed. Must match /^[a-zA-Z0-9_-]+$/.
  • Globally unique: Use globally unique IDs (e.g., nanoid) to prevent collisions across stores.
  • Use namespaces: Prefix to avoid collisions and for easier identification when debugging (e.g., app-root, workspace-abc123, issue-456)

storeId
: 'demo-store' })
const
const todos: unknown
todos
=
const store: Store<any, {}>
store
.
Store<any, {}>.query: <unknown>(query: Queryable<unknown> | {
query: string;
bindValues: Bindable;
schema?: Decoder<unknown, never>;
}, options?: {
otelContext?: Context;
debugRefreshReason?: RefreshReason;
}) => unknown

Synchronously queries the database without creating a LiveQuery. This is useful for queries that don't need to be reactive.

Example: Query builder

const completedTodos = store.query(tables.todo.where({ complete: true }))

Example: Raw SQL query

const completedTodos = store.query({ query: 'SELECT * FROM todo WHERE complete = 1', bindValues: {} })

query
(
import tables
tables
.
any
todos
)
var console: Console
console
.
Console.log(...data: any[]): void (+2 overloads)

The console.log() static method outputs a message to the console.

MDN Reference

log
(
const todos: unknown
todos
)
}
const main: () => Promise<void>
main
().
Promise<void>.catch<undefined>(onrejected?: ((reason: any) => PromiseLike<undefined> | undefined) | null | undefined): Promise<void | undefined>

Attaches a callback for only the rejection of the Promise.

@paramonrejected The callback to execute when the Promise is rejected.

@returnsA Promise for the completion of the callback.

catch
(() =>
var undefined
undefined
)

For a quick start, we recommend using our template app following the steps below.

  1. Set up project from template

    Terminal window
    bunx @livestore/cli create --example node-todomvc-sync-cf livestore-app

    Replace livestore-app with your desired app name.

  2. Install dependencies

    It’s strongly recommended to use bun or pnpm for the simplest and most reliable dependency setup (see note on package management for more details).

    Terminal window
    bun install

    Pro tip: You can use direnv to manage environment variables.

  3. Run dev environment

    Terminal window
    bun start