Skip to content

LiveStore CLI

The LiveStore CLI provides tools for creating new projects and integrating with AI assistants through MCP (Model Context Protocol).

You can use the LiveStore CLI in several ways:

Terminal window
# Recommended: Use bunx (no installation needed)
bunx @livestore/cli --help
# Alternative options:
npm install -g @livestore/cli # Global install
npm install -D @livestore/cli # Project install
npx @livestore/cli --help # Use with npx

Create a new LiveStore project from available examples.

Terminal window
# Interactive selection
livestore new-project
# Specify example and path
livestore new-project --example web-todomvc my-project
# Use specific branch
livestore new-project --branch main

MCP server tools for AI assistant integration. See MCP Integration for details.

Terminal window
# Start MCP server
livestore mcp
# Available subcommands
livestore mcp coach # AI coaching assistant (requires API key env var)
livestore mcp tools # Development tools server
# Coach command requires API key - check implementation for specific variable name
# Example: OPENAI_API_KEY=your_key livestore mcp coach

Import and export events from the sync backend. Useful for backup, migration, and debugging.

Export all events from the sync backend to a JSON file:

Terminal window
livestore sync export \
--config livestore-cli.config.ts \
--store-id my-store \
events.json

Example output:

Exporting events from LiveStore...
Config: livestore-cli.config.ts
Store ID: my-store
Output: events.json
Connecting to sync backend...
✓ Connected to sync backend: @livestore/cf-sync
Pulling events from sync backend...
Pulled 127 events
Exported 127 events to /path/to/events.json

Options:

  • --config, -c (required) - Path to a config module that exports schema and syncBackend
  • --store-id, -i (required) - Store identifier
  • --client-id - Client identifier for the sync connection (default: cli-export)
  • Large exports load data in memory; for very large stores run this on a machine with sufficient RAM.

Import events from a JSON file to the sync backend:

Terminal window
livestore sync import \
--config livestore-cli.config.ts \
--store-id my-store \
events.json

Example output:

Importing events to LiveStore...
Config: livestore-cli.config.ts
Store ID: my-store
Input: events.json
Reading import file...
Found 127 events in export file
Checking for existing events...
Connecting to sync backend...
✓ Connected to sync backend: @livestore/cf-sync
Pushing events to sync backend...
Pushed 100/127 events
Pushed 127/127 events
Successfully imported 127 events

Options:

  • --config, -c (required) - Path to a config module that exports schema and syncBackend
  • --store-id, -i (required) - Store identifier
  • --client-id - Client identifier for the sync connection (default: cli-import)
  • --force, -f - Force import even if store ID in the file doesn’t match
  • --dry-run - Validate the import file without actually importing
  • Large imports are memory-intensive because the JSON is loaded fully before validation/push.

Note: The sync backend must be empty when importing. The import will fail if events already exist.

Both MCP and sync commands require a config file (conventionally named livestore-cli.config.ts) that exports:

import {
const makeWsSync: (options: WsSyncOptions) => SyncBackendConstructor<SyncMetadata>

Creates a sync backend that uses WebSocket to communicate with the sync backend.

@example

import { makeWsSync } from '@livestore/sync-cf/client'
const syncBackend = makeWsSync({ url: 'wss://sync.example.com' })

makeWsSync
} from '@livestore/sync-cf/client'
// Re-export your app's schema (adjust path to your project)
export {
export schema
schema
} from './schema.ts'
// Provide a sync backend constructor
export const
const syncBackend: SyncBackendConstructor<Struct.ReadonlySide<{
readonly _tag: tag<"SyncMessage.SyncMetadata">;
readonly createdAt: String;
}, "Type">, Json>
syncBackend
=
function makeWsSync(options: WsSyncOptions): SyncBackendConstructor<SyncMetadata>

Creates a sync backend that uses WebSocket to communicate with the sync backend.

@example

import { makeWsSync } from '@livestore/sync-cf/client'
const syncBackend = makeWsSync({ url: 'wss://sync.example.com' })

makeWsSync
({
WsSyncOptions.url: string

URL of the sync backend

The protocol can either http/https or ws/wss

url
:
var process: NodeJS.Process
process
.
NodeJS.Process.env: NodeJS.ProcessEnv

The process.env property returns an object containing the user environment. See environ(7).

An example of this object looks like:

{
TERM: 'xterm-256color',
SHELL: '/usr/local/bin/bash',
USER: 'maciej',
PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',
PWD: '/Users/maciej',
EDITOR: 'vim',
SHLVL: '1',
HOME: '/Users/maciej',
LOGNAME: 'maciej',
_: '/usr/local/bin/node'
}

It is possible to modify this object, but such modifications will not be reflected outside the Node.js process, or (unless explicitly requested) to other Worker threads. In other words, the following example would not work:

node -e 'process.env.foo = "bar"' &#x26;&#x26; echo $foo

While the following will:

import { env } from 'node:process';
env.foo = 'bar';
console.log(env.foo);

Assigning a property on process.env will implicitly convert the value to a string. This behavior is deprecated. Future versions of Node.js may throw an error when the value is not a string, number, or boolean.

import { env } from 'node:process';
env.test = null;
console.log(env.test);
// => 'null'
env.test = undefined;
console.log(env.test);
// => 'undefined'

Use delete to delete a property from process.env.

import { env } from 'node:process';
env.TEST = 1;
delete env.TEST;
console.log(env.TEST);
// => undefined

On Windows operating systems, environment variables are case-insensitive.

import { env } from 'node:process';
env.TEST = 1;
console.log(env.test);
// => 1

Unless explicitly specified when creating a Worker instance, each Worker thread has its own copy of process.env, based on its parent thread's process.env, or whatever was specified as the env option to the Worker constructor. Changes to process.env will not be visible across Worker threads, and only the main thread can make changes that are visible to the operating system or to native add-ons. On Windows, a copy of process.env on a Worker instance operates in a case-sensitive manner unlike the main thread.

@sincev0.1.27

env
.
string | undefined
LIVESTORE_SYNC_URL
?? 'ws://localhost:8787',
})
// Optionally, pass an auth payload (must be JSON-serializable)
export const
const syncPayload: {
authToken: string | undefined;
}
syncPayload
= {
authToken: string | undefined
authToken
:
var process: NodeJS.Process
process
.
NodeJS.Process.env: NodeJS.ProcessEnv

The process.env property returns an object containing the user environment. See environ(7).

An example of this object looks like:

{
TERM: 'xterm-256color',
SHELL: '/usr/local/bin/bash',
USER: 'maciej',
PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',
PWD: '/Users/maciej',
EDITOR: 'vim',
SHLVL: '1',
HOME: '/Users/maciej',
LOGNAME: 'maciej',
_: '/usr/local/bin/node'
}

It is possible to modify this object, but such modifications will not be reflected outside the Node.js process, or (unless explicitly requested) to other Worker threads. In other words, the following example would not work:

node -e 'process.env.foo = "bar"' &#x26;&#x26; echo $foo

While the following will:

import { env } from 'node:process';
env.foo = 'bar';
console.log(env.foo);

Assigning a property on process.env will implicitly convert the value to a string. This behavior is deprecated. Future versions of Node.js may throw an error when the value is not a string, number, or boolean.

import { env } from 'node:process';
env.test = null;
console.log(env.test);
// => 'null'
env.test = undefined;
console.log(env.test);
// => 'undefined'

Use delete to delete a property from process.env.

import { env } from 'node:process';
env.TEST = 1;
delete env.TEST;
console.log(env.TEST);
// => undefined

On Windows operating systems, environment variables are case-insensitive.

import { env } from 'node:process';
env.TEST = 1;
console.log(env.test);
// => 1

Unless explicitly specified when creating a Worker instance, each Worker thread has its own copy of process.env, based on its parent thread's process.env, or whatever was specified as the env option to the Worker constructor. Changes to process.env will not be visible across Worker threads, and only the main thread can make changes that are visible to the operating system or to native add-ons. On Windows, a copy of process.env on a Worker instance operates in a case-sensitive manner unlike the main thread.

@sincev0.1.27

env
.
string | undefined
LIVESTORE_SYNC_AUTH_TOKEN
,
}
  • --verbose - Enable verbose logging
  • --help - Show command help