Three tiers. One binary. Everything composable.
Clients talk to the gateway over JSON-RPC 2.0 (HTTP or WebSocket). The gateway composes agents, channels, providers, and plugins on top of a shared core. Each layer is its own crate, each crate is independently usable.
The crate dependency graph
Read the graph bottom-up. openclaw-core sits at the
foundation — every other crate depends on it, none of them depend on
anything above it. openclaw-providers + openclaw-ipc
sit on the core. openclaw-agents + openclaw-channels
+ openclaw-plugins sit on those. openclaw-gateway
sits on top of everything and embeds openclaw-ui at build
time. The CLI ties it all together.
There is no circular dependency, no global state, no hidden coupling. You can swap any layer for your own — or use any single crate in isolation from your own service.
Event-sourced session model
Sessions are append-only logs in sled. Eight event kinds
cover everything that can happen during a session.
Projecting the log into the current state uses last-write-wins CRDT semantics. The same projection is safe to compute in multiple instances in parallel — which makes future clustering straightforward.
Platform sandbox backends
Tool execution is process-isolated. The Rust API stays the same; the backend dispatches by OS at compile time.
Three levels — None, Relaxed,
Strict — pick the policy. The backend implements it. See
the sandbox deep dive
for the policy details.
Thread model
Everything async-first via tokio. Shared state lives behind
Arc<RwLock<T>>; no global mutable state, no
hidden locking. Backpressure via bounded channels at the channel-adapter
boundary so a flood of inbound events can't OOM the runtime.
#![forbid(unsafe_code)] is enforced across every workspace
crate. There is no unsafe block in openclaw-rs. We rely on
well-tested ecosystem crates for the rare cases (rkyv,
aes-gcm, nng) where unsafe sits
below the surface.
The full inventory
Ten crates. Eight stable today, two partial.
| Crate | Status | Role | Links |
|---|---|---|---|
openclaw-core | stable | Foundation: types, JSON5 config loader, sled-backed event store, AES-256-GCM credential store, OAuth token management, input validation. | crates.io ↗ docs.rs ↗ |
openclaw-ipc | stable | IPC message types and nng transport — the wire format for the TypeScript plugin bridge. | crates.io ↗ docs.rs ↗ |
openclaw-providers | stable | Anthropic + OpenAI clients with SSE streaming, tool use, and configurable base URLs. | crates.io ↗ docs.rs ↗ |
openclaw-agents | stable | Agent runtime, platform-specific sandbox (bwrap / sandbox-exec / Job Objects), tool registry, node-based workflow engine. | crates.io ↗ docs.rs ↗ |
openclaw-channels | partial | Channel traits + allowlist + routing. Telegram adapter complete; Discord, Slack, Signal, Matrix, WhatsApp planned. | |
openclaw-gateway | stable | axum HTTP/WebSocket server with JSON-RPC 2.0 dispatch, rate-limit and auth middleware, embedded Vue 3 dashboard. | crates.io ↗ docs.rs ↗ |
openclaw-plugins | partial | Plugin API + nng-based TypeScript bridge. WASM runtime (wasmtime vs wasmer) under evaluation. | |
openclaw-cli | stable | Top-level CLI: onboard, gateway, doctor, status, config, sessions, channels, daemon, completion. | crates.io ↗ |
openclaw-node | stable | napi-rs bindings: AnthropicProvider, OpenAIProvider, NodeEventStore, CredentialStore, ToolRegistry. Pre-built binaries on npm. | npm ↗ |
openclaw-ui | stable | Vue 3 + Vite dashboard. Served by openclaw-gateway at /. No external admin to deploy. |