@walkeros/cli
Command-line tools for building, testing, and running walkerOS event collection
flows.
What is this?
The walkerOS CLI is a developer tool that:
- Bundles flow configurations into optimized JavaScript
- Simulates event processing for testing
- Runs flows locally without Docker daemon
Think of it as your development toolchain for walkerOS - from config to running
production bundles.
When to Use the CLI
The CLI is for Bundled mode — when you want config-as-code and separate
deployment:
| Static sites, landing pages | React/Next.js apps |
| Docker/server deployments | TypeScript projects |
| CI/CD versioned configs | Programmatic control |
| Marketing/GTM workflows | Build-time type safety |
For Integrated mode (importing directly into your app), see the
Collector package.
Installation
npm install -g @walkeros/cli
npm install @walkeros/cli
Quick Start
walkeros bundle flow.json
walkeros simulate flow.json --event '{"name":"product view"}'
walkeros simulate dist/bundle.mjs --event '{"name":"product view"}'
walkeros push flow.json --event '{"name":"product view"}'
walkeros run collect dist/bundle.mjs --port 3000
Commands
bundle
Generate optimized JavaScript bundles from flow configurations.
walkeros bundle <config-file> [options]
Config files can be local paths or HTTP(S) URLs:
walkeros bundle ./config.json
walkeros bundle https://example.com/config.json
Options:
--flow <name> - Flow name for multi-flow configs
--all - Build all flows for multi-flow configs
--stats - Show bundle statistics
--json - Output as JSON (implies --stats)
--no-cache - Disable package caching
--dockerfile [file] - Generate Dockerfile (or copy custom file) to dist/
-v, --verbose - Verbose output
-s, --silent - Suppress output
Examples:
walkeros bundle examples/server-collect.json --stats
walkeros bundle flow.json --dockerfile
walkeros bundle flow.json --dockerfile Dockerfile.custom
The output path uses convention-based defaults: ./dist/bundle.mjs for server,
./dist/walker.js for web. The --dockerfile flag generates a Dockerfile with
the correct MODE (collect/serve) based on flow type.
simulate
Test event processing with simulated events. Accepts either a config JSON (which
gets bundled) or a pre-built bundle (executed directly).
walkeros simulate <input> --event '{"name":"page view"}' [options]
Input types:
- Config JSON - Bundled and executed with destination mocking
- Pre-built bundle (
.js/.mjs) - Executed directly, no mocking
The CLI auto-detects the input type by attempting to parse as JSON.
Options:
-e, --event <json> - Event to simulate (JSON string, file path, or URL)
--flow <name> - Flow name for multi-flow configs
-p, --platform <platform> - Platform override (web or server)
--json - Output as JSON
-v, --verbose - Verbose output
-s, --silent - Suppress output
Examples:
walkeros simulate examples/web-serve.json \
--event '{"name":"page view","data":{"title":"Home"}}' \
--json
walkeros simulate flow.json --flow server --event '{"name":"test"}'
walkeros simulate dist/bundle.mjs --event '{"name":"page view"}'
walkeros simulate dist/bundle.js --platform server --event '{"name":"page view"}'
Platform detection:
When using pre-built bundles, platform is detected from file extension:
.mjs → server (ESM, Node.js)
.js → web (IIFE, JSDOM)
Use --platform to override if extension doesn't match intended runtime.
push
Execute your flow with real API calls to configured destinations. Unlike
simulate which mocks API calls, push performs actual HTTP requests. Accepts
either a config JSON (which gets bundled) or a pre-built bundle.
walkeros push <input> --event '<json>' [options]
Input types:
- Config JSON - Bundled and executed
- Pre-built bundle (
.js/.mjs) - Executed directly
The CLI auto-detects the input type by attempting to parse as JSON.
Options:
-e, --event <source> - Event to push (JSON string, file path, or URL)
Required
--flow <name> - Flow name (for multi-flow configs)
-p, --platform <platform> - Platform override (web or server)
--json - Output results as JSON
-v, --verbose - Verbose output
-s, --silent - Suppress output (for CI/CD)
Event input formats:
walkeros push flow.json --event '{"name":"page view","data":{"title":"Home"}}'
walkeros push flow.json --event ./events/order.json
walkeros push flow.json --event https://example.com/sample-event.json
Bundle input:
walkeros push dist/bundle.mjs --event '{"name":"order complete"}'
walkeros push dist/bundle.js --platform server --event '{"name":"order complete"}'
Push vs Simulate:
| API Calls | Real HTTP requests | Mocked (captured) |
| Use Case | Integration testing | Safe local testing |
| Side Effects | Full (writes to DBs, sends to APIs) | None |
Use simulate first to validate configuration safely, then push to verify
real integrations.
run
Run flows locally (no Docker daemon required).
walkeros run <mode> <config-file> [options]
Modes:
collect - HTTP event collection server
serve - Static file server
Options:
-p, --port <number> - Server port
-h, --host <host> - Server host
--json - Output as JSON
-v, --verbose - Verbose output
-s, --silent - Suppress output
Examples:
walkeros run collect examples/server-collect.json --port 3000
walkeros run collect examples/server-collect.mjs --port 3000
walkeros run serve flow.json --port 8080 --static-dir ./dist
How it works:
- JSON configs are auto-bundled to temp
.mjs
.mjs bundles are used directly
- Runs in current Node.js process
- Press Ctrl+C for graceful shutdown
Caching
The CLI implements intelligent caching for faster builds:
Package Cache
- NPM packages are cached in
.tmp/cache/packages/
- Mutable versions (
latest, ^, ~) are re-checked daily
- Exact versions (
0.4.1) are cached indefinitely
Build Cache
- Compiled bundles are cached in
.tmp/cache/builds/
- Cache key based on flow.json content + current date
- Identical configs reuse cached build within the same day
Cache Management
walkeros cache info
walkeros cache clear
walkeros cache clear --packages
walkeros cache clear --builds
walkeros bundle flow.json --no-cache
Flow Configuration
Flow configs use the Flow.Setup format with version and flows:
{
"version": 1,
"flows": {
"default": {
"server": {},
"packages": {
"@walkeros/collector": { "imports": ["startFlow"] },
"@walkeros/server-source-express": {},
"@walkeros/destination-demo": {}
},
"sources": {
"http": {
"package": "@walkeros/server-source-express",
"config": {
"settings": { "path": "/collect", "port": 8080 }
}
}
},
"destinations": {
"demo": {
"package": "@walkeros/destination-demo",
"config": {
"settings": { "name": "Demo" }
}
}
},
"collector": { "run": true }
}
}
}
Platform is determined by the web: {} or server: {} key presence.
Package Configuration Patterns
The CLI automatically resolves imports based on how you configure packages:
1. Default exports (recommended for single-export packages):
{
"packages": {
"@walkeros/server-destination-api": {}
},
"destinations": {
"api": {
"package": "@walkeros/server-destination-api"
}
}
}
The CLI generates:
import _walkerosServerDestinationApi from '@walkeros/server-destination-api';
2. Named exports (for multi-export packages):
{
"packages": {
"@walkeros/server-destination-gcp": {}
},
"destinations": {
"bigquery": {
"package": "@walkeros/server-destination-gcp",
"code": "destinationBigQuery"
},
"analytics": {
"package": "@walkeros/server-destination-gcp",
"code": "destinationAnalytics"
}
}
}
The CLI generates:
import { destinationBigQuery, destinationAnalytics } from '@walkeros/server-destination-gcp';
3. Utility imports (for helper functions):
{
"packages": {
"lodash": { "imports": ["get", "set"] }
},
"mappings": {
"custom": {
"data": "({ data }) => get(data, 'user.email')"
}
}
}
The CLI generates: import { get, set } from 'lodash';
Key points:
- Omit
packages.imports for destinations/sources - the default export is used
automatically
- Only specify
code when using a specific named export from a multi-export
package
- Use
packages.imports only for utilities needed in mappings or custom code
Local Packages
Use local packages instead of npm for development or testing unpublished
packages:
{
"packages": {
"@walkeros/collector": {
"path": "../packages/collector",
"imports": ["startFlow"]
},
"@my/custom-destination": {
"path": "./my-destination",
"imports": ["myDestination"]
}
}
}
Resolution rules:
path takes precedence over version
- Relative paths are resolved from the config file's directory
- If
dist/ folder exists, it's used; otherwise package root is used
Dependency resolution:
When a local package has dependencies on other packages that are also specified
with local paths, the CLI will use the local versions for those dependencies
too. This prevents npm versions from overwriting your local packages.
{
"packages": {
"@walkeros/core": {
"path": "../packages/core",
"imports": []
},
"@walkeros/collector": {
"path": "../packages/collector",
"imports": ["startFlow"]
}
}
}
In this example, even though @walkeros/collector depends on @walkeros/core,
the local version of core will be used (not downloaded from npm).
See examples/ for complete working configurations.
Programmatic API
Use commands programmatically:
import { bundle, simulate, runCommand } from '@walkeros/cli';
await bundle({
config: './flow.json',
stats: true,
});
const result = await simulate(
'./flow.json',
{ name: 'page view', data: { title: 'Test' } },
{ json: true },
);
await runCommand('collect', {
config: './flow.json',
port: 3000,
verbose: true,
});
Examples
Working example configs in examples/:
- server-collect.json - Basic server-side collection
- server-collection.json - Advanced server setup
- web-serve.json - Web demo with API destination
- web-tracking.json - General web tracking
Try them:
walkeros bundle examples/server-collect.json --stats
walkeros simulate \
examples/web-serve.json \
--event '{"name":"product view","data":{"id":"P123"}}'
walkeros run collect examples/server-collect.json --port 3000
Development Workflow
Typical development cycle:
vim my-flow.json
walkeros simulate \
my-flow.json \
--event '{"name":"product view"}' \
--verbose
walkeros bundle my-flow.json --stats
walkeros run collect dist/bundle.mjs --port 3000
curl -X POST http://localhost:3000/collect \
-H "Content-Type: application/json" \
-d '{"name":"page view","data":{"title":"Home"}}'
Architecture
CLI (downloads packages + bundles with esbuild)
├─ Bundle → optimized .mjs file
├─ Simulate → test bundle with events
└─ Run → execute bundle with built-in runtime
Key principle: CLI handles both build-time and runtime operations.
Production Deployment
Deploy your flows using Docker or Node.js.
Using Docker
The walkeros/flow image runs pre-built bundles in production:
walkeros bundle flow.json --dockerfile
gcloud run deploy my-service --source ./dist
Or run locally:
docker run -v ./dist:/flow -p 8080:8080 walkeros/flow
Custom Dockerfile:
walkeros bundle flow.json --dockerfile Dockerfile.custom
Environment variables:
MODE - collect or serve (default: collect)
PORT - Server port (default: 8080)
BUNDLE - Bundle path (default: /app/flow/bundle.mjs)
Using Node.js
Run the bundle directly with the CLI:
walkeros bundle flow.json
walkeros run collect dist/bundle.mjs --port 8080
This runs the flow in the current Node.js process, suitable for deployment on
platforms like AWS Lambda, Google Cloud Run, or any Node.js hosting.
Requirements
- Node.js: 18+ or 22+
- Docker: Not required for CLI (only for production deployment)
Type Definitions
See src/types.ts for TypeScript interfaces.
Related
License
MIT © elbwalker