Laser Stack
Run the complete Laser SDK locally with Laser Stack, Apache Iggy VSR, and laser-plane.
Laser Stack runs the complete SDK locally. It starts the LaserData Apache Iggy fork and laser-plane. The startup script waits for Iggy health and plane readiness, then prints their connection string.
Use Laser Stack for projections, query, change feed, KV, forks, graph, RBAC, and runs. Standalone VSR-enabled Iggy supports streaming and log-backed agent features. It does not provide managed data APIs.
Requirements
- Docker Engine 25 or a current Docker Desktop.
- Docker Compose v2.20 or later.
- A 64-bit
amd64orarm64system. Published images support both, including Apple Silicon.
Start the stack
git clone https://github.com/laserdata/laser-stack
cd laser-stack
./scripts/upThe first run creates a mode-600 .env. It pulls the published images when available, starts both services, waits for Iggy health and plane readiness, and prints:
export LASER_CONNECTION_STRING='iggy:[email protected]:8090'Use the printed value. The default credentials are iggy:laser. For a new data volume, ./scripts/up --random-password creates a random password.
Verify the complete managed path:
./scripts/smokeThe smoke installs the published TypeScript SDK version selected by LASER_SDK_VERSION in a Node.js container. It checks Iggy TCP health, proves plane readiness through the authenticated AGDX capability path, then executes a managed KV set/get through Iggy and laser-plane.
If the registry is unavailable, later runs use cached images. If no published or cached image is available, the script builds from signed binaries. The default listeners bind to 127.0.0.1. Other machines cannot reach them.
What runs
| Service | Role | Local endpoint |
|---|---|---|
| LaserData Apache Iggy fork | Durable log, authentication, VSR transport, and managed-command forwarding | TCP 127.0.0.1:8090, HTTP 127.0.0.1:3000 |
laser-plane sidecar | Projection, query, state, graph, change-feed, authorization, and run read models | Internal Unix socket shared with Iggy |
Iggy owns the durable log. laser-plane consumes its control and data records. It maintains read models and handles managed operations. Applications use the existing SDK connection for both services.
The stack uses separate Docker volumes for Iggy and plane data. ./scripts/down keeps them. ./scripts/reset deletes them.
Tested versions
| Component | Version |
|---|---|
| LaserData Apache Iggy fork | 0.8.102-ld |
laser-plane | 0.12.0 |
| Rust, Python, and TypeScript Laser SDK | 0.0.1 |
These are the versions in .env.example and are tested together. Change LASER_IGGY_VERSION and LASER_PLANE_VERSION together before rebuilding with ./scripts/up --build.
VSR only
Rust, Python, and TypeScript always use VSR (Viewstamped Replication Revisited). Classic Iggy framing has no feature flag, connection option, or fallback.
- Rust and Python are built with Iggy's VSR client enabled.
- TypeScript always constructs a VSR client and rejects an injected Iggy client configured for another protocol.
- Standard streaming commands, managed reads, and replicated authorization writes share the same connection. The server classifies the operation path.
VSR handles Iggy transport and replication. AGDX defines the data carried over it. VSR does not change AGDX envelopes or headers.
Connect every client
Export the value printed by ./scripts/up, then connect with the idiomatic environment path in each client:
import { Laser } from "@laserdata/laser-sdk"
await using laser = await Laser.connectEnv()use laser_sdk::prelude::*;
let laser = Laser::connect_env().await?;import os
import laser_sdk as ls
laser = await ls.Laser.connect(
os.environ["LASER_CONNECTION_STRING"],
stream=os.environ.get("LASER_STREAM"),
)Rust and TypeScript provide connect_env and connectEnv. Python uses Laser.connect, so pass the environment values directly.
Run the SDK examples
The laser-sdk examples cover the same primitives in all clients. The query example checks both Iggy and laser-plane.
The Rust workspace manifest declares its minimum supported Rust version. Python requires 3.10 or later and the example setup uses uv. TypeScript requires Node.js 22.14 or later.
git clone https://github.com/laserdata/laser-sdkRun the command for your client from the directory containing that checkout:
cd laser-sdk/examples/typescript
npm run setup
npm run example:querycd laser-sdk/examples/rust
cargo run --example queryPublished package:
cd laser-sdk/examples/python
uv venv
uv pip install laser-sdk
uv run python query.pyLocal checkout:
cd laser-sdk/examples/python
uv sync --project ../../foreign/python --locked --extra testing
uv run --project ../../foreign/python python query.pyRun npm run setup once after cloning the TypeScript examples. Each npm run example:<name> command rebuilds before starting its example. Both Python paths use uv and do not require pip in /usr/bin/python3.
Other focused examples are log, watch, kv, graph, recall, context, and agent. Larger scenarios include native-streaming, event-analytics, order-book, firehose, concierge, memory, interop, orchestra, and governance. TypeScript and Rust use the hyphenated names. Python uses underscores in filenames, such as event_analytics.py. They all use the same environment variables.
Stack commands
| Command | Action |
|---|---|
./scripts/up | Start detached and wait for health |
./scripts/up --foreground | Run attached until Ctrl-C |
./scripts/up --build | Build images from signed, pinned binaries |
./scripts/up --random-password | Generate random credentials for a new data volume |
./scripts/smoke | Check health, readiness, AGDX capabilities, and a managed SDK KV round trip |
./scripts/logs [service] | Follow all logs or one service |
./scripts/down | Stop services and keep data |
./scripts/reset | Stop services and delete this stack's data |
./scripts/reset --yes | Reset without a prompt |
See the Laser Stack README for version overrides, image verification, local TLS guidance, and troubleshooting.
Smoke configuration
The smoke reads LASER_SDK_VERSION from .env and defaults to 0.0.1. LASER_SMOKE_TIMEOUT controls its overall timeout and defaults to 300 seconds. LASER_SMOKE_NODE_IMAGE selects the pinned Node.js runtime image.
Set LASER_SMOKE_SDK_SPEC in the process environment to test another npm package spec or a local .tgz without changing .env:
LASER_SMOKE_SDK_SPEC=/path/to/laser-sdk.tgz ./scripts/smokeChoose a target
| Target | Streaming and log-backed agents | Managed data surfaces | Protocol |
|---|---|---|---|
| Laser Stack | Yes | Yes, locally through laser-plane | VSR |
| LaserData Cloud | Yes | Yes, managed | VSR |
| Standalone Apache Iggy | Yes | No, unless a compatible managed backend is attached | VSR required |
The API stays the same across targets. Change LASER_CONNECTION_STRING. Check laser.capabilities() before using optional managed features.