Skip to content

CLI Usage

Synode includes a CLI for generating synthetic data from config files. Install it globally or use it as a project dependency.

Install

bash
# Global install
npm install -g @synode/cli

# Or as a project dependency (included when you run synode init)
npm install @synode/cli

Quick Start

bash
# Scaffold a new project interactively
synode init

# Generate data
synode generate synode.config.ts

# Validate config without generating
synode validate synode.config.ts

# Reverse-engineer a config from event data
synode analyze

# Show help
synode --help
synode generate --help

Commands

synode init [dir]

Interactive project scaffolder. Creates a complete Synode project with config, dependencies, and optional example journeys.

bash
synode init                  # Prompts for project name
synode init my-project       # Creates my-project/ directory

The scaffolder prompts for:

  1. Project name — directory to create
  2. Adapters — which output adapters to install (File, HTTP, BigQuery, Stream, Composite)
  3. Example journey — include a working browse-and-purchase example
  4. CLAUDE.md sections — AI assistant context (API reference, error codes, architecture)
  5. Package manager — pnpm, npm, or yarn

After scaffolding, it installs dependencies and shows next steps using your chosen package manager.

synode generate <config>

Loads the config file and runs event generation. Shows progress with timing and events/sec.

bash
synode generate synode.config.ts
synode generate synode.config.ts --users 5000 --lanes 4
synode generate synode.config.ts --output events.jsonl
synode generate synode.config.ts --output ./out/ --format csv

When --output is a directory (or a path without an extension), the CLI automatically creates a file named events.{ext} inside it.

TypeScript config files are loaded automatically using tsx — no compilation step needed.

synode validate <config>

Validates the config file structure without generating any events. Shows a pass/fail summary for each journey. Exits with code 0 on success, 1 on failure.

bash
synode validate synode.config.ts

Output:

  Validating 3 journeys...

  ✓ browse-session
  ✓ purchase-flow
  ✗ checkout — bounceChance must be between 0 and 1

  2 passed, 1 failed

synode analyze

Reverse-engineers a Synode config from real event data. Place your CSV, JSONL, or JSON files in an input/ directory and run the wizard. See the Analyzer guide for details.

bash
synode analyze                # Full wizard: parse → detect → mine → compile
synode analyze --compile-only # Re-compile from existing input/analysis.json

The analyzer:

  1. Parses event data and auto-detects the schema (GA4, Segment, Mixpanel, or custom)
  2. Discovers actions, sequences, adventures, and journeys from behavioral patterns
  3. Generates complete TypeScript config files ready for synode generate
  4. Optionally enhances names and conditions using AI (Anthropic or Google)
  5. Detects and offers to clean up stale files from previous runs

synode update

Checks for and installs updates to Synode packages.

bash
synode update

Flags

All flags apply to the generate command. They override config file values.

FlagShortTypeDescription
--users <n>-unumberOverride user count
--lanes <n>-lnumberOverride lane count
--tick <dur>stringOverride tick interval (e.g., 1m)
--scatter <n>numberOverride scatter factor (0-1)
--duration <dur>stringSimulation duration (e.g., 7d)
--start <date>stringSimulation start date (ISO string)
--end <date>stringSimulation end date (ISO string)
--streambooleanEnable real-time streaming mode
--output <path>-ostringOutput file or directory path
--format <fmt>-fstringOutput format: json, jsonl, csv
--dry-runbooleanValidate config, generate 1 user only
--quiet-qbooleanSuppress progress output
--version-VShow version number
--help-hShow help for any command

Config File Format

The config file exports a set of named fields that the CLI reads. Run synode init to scaffold one, or use synode analyze to generate one from event data.

ts
import { definePersona, weighted, generate } from '@synode/core';
import type { Journey, TimeConfig, SimulationConfig, DatasetDefinition } from '@synode/core';
import { browseJourney } from './src/journeys/Browse.js';
import { products } from './src/datasets/Products.js';

// Named exports — used by `synode generate`
export const journeys: Journey[] = [browseJourney];
export const time: TimeConfig = { duration: '7d' };
export const simulation: SimulationConfig = { users: 1000, lanes: 4, tick: '1m', scatter: 0.1 };
export const datasets: DatasetDefinition[] = [products];
export const persona = definePersona({
  id: 'shopper',
  name: 'Shopper',
  attributes: {
    locale: weighted({ en: 0.5, de: 0.3, fr: 0.2 }),
  },
});

// Direct execution — also works with `npx tsx synode.config.ts`
await generate(journeys, { time, simulation, datasets, persona });

Required Exports

ExportTypeRequiredDescription
journeysJourney[]YesJourney definitions to execute
timeTimeConfigYesTime window for the simulation
simulationSimulationConfigYesUsers, lanes, tick, scatter
datasetsDatasetDefinition[]NoDatasets to hydrate before execution
personaPersonaDefinitionNoPersona for user attribute generation

TimeConfig

ts
// Duration-based (most common)
export const time = { duration: '30d' };

// Fixed window
export const time = { start: new Date('2026-01-01'), end: new Date('2026-02-01') };

// Start + duration
export const time = { start: new Date('2026-01-01'), duration: '14d' };

SimulationConfig

ts
export const simulation = {
  users: 1000, // 1 to 10,000,000
  lanes: 4, // 1 to 10,000 — concurrent execution slots
  tick: '1m', // Clock interval per tick
  scatter: 0.1, // 0-1 — jitter applied to waits and cooloffs
};

AdapterConfig

The CLI supports two adapter types via config file:

ts
// Console output (default — writes to stdout)
adapter: { type: 'console' }

// File output
adapter: { type: 'file', path: './output/events.jsonl', format: 'jsonl' }

When --output is passed as a flag, it creates a file adapter. Format is inferred from the file extension or from the --format flag.

Example Workflow

bash
# 1. Scaffold a new project
synode init my-cdp-data

# 2. Enter the project
cd my-cdp-data

# 3. Edit synode.config.ts with your journeys, persona, datasets

# 4. Dry run to validate
synode generate synode.config.ts --dry-run

# 5. Generate a small sample
synode generate synode.config.ts --users 100 --output ./output/

# 6. Full generation
synode generate synode.config.ts --users 50000 --lanes 8 --output ./output/events.jsonl

Or reverse-engineer from existing data:

bash
# 1. Place event files in input/
mkdir input && cp events.csv input/

# 2. Run the analyzer
synode analyze

# 3. Review and run the generated config
synode generate synode.config.ts

Error Handling

Errors include the CLI version and a pre-filled GitHub issue link:

Error: Config file not found: /path/to/missing.ts

synode v5.0.14 on v24.12.0
Report: https://github.com/digitl-cloud/synode/issues?title=...

Set DEBUG=1 to include the full stack trace in error output.