Quickstart
Get Durable Agents up and running in a few seconds and then define custom agents that run in your own web app (or serverless functions).
Runtime components
The Durable Agents runtime (aka DARIX) has three key components:
- DARIX runtime server — the durable streams server that persists entity state.
- DARIX CLI — a command-line tool for spawning entities, sending messages, and streaming events.
- DARIX GUI — an Electron app for observing and interacting with entities.
The first step is to get these running, with some built-in agents you can use right away.
You can then define and engineer agents (and agent topologies and coordination patterns, ...) in your own web app that use the @durable-streams/darix-runtime shim to register with the runtime.
Prerequisites
Clone the repo
DARIX packages are not yet published to npm. For now, clone the repo and use it as a local workspace:
git clone git@github.com:electric-sql/durable-streams.git
cd durable-streams
pnpm installSetup environment variables
Create a .env file with:
ANTHROPIC_API_KEY(mandatory)BRAVE_SEARCH_API_KEY(optional, if you're using agents that search)
E.g.:
cat <<'EOF' > .env
ANTHROPIC_API_KEY="sk-ant-..."
BRAVE_SEARCH_API_KEY="BS..."
EOFTry the built-in Horton assistant
The runtime server ships with a built-in agent type, horton — a friendly capable assistant that can chat, research the web, read and edit code, run shell commands, and dispatch subagents. It's the easiest way to try DARIX before writing any code.
1. Start the runtime server
pnpm start:darixThis starts Postgres and Electric containers via Docker, then launches the DARIX runtime server with horton (and an internal worker type it can spawn) registered. The server defaults to http://localhost:4437 but picks a random port if 4437 is in use — the URL is printed on startup.
2. Interact via CLI
In a separate terminal, spawn a Horton entity, send it a message, and observe the output:
pnpm darix spawn /horton/my-horton
pnpm darix send /horton/my-horton 'Hello!'
pnpm darix observe /horton/my-hortonspawncreates a new entity instance at the given path.senddelivers a message to the entity's inbox, waking its handler.observestreams the entity's events to your terminal in real-time.
3. Start the DARIX GUI (optional)
You can also start the Electron app to observe and interact with entities visually:
pnpm start:darix-appCreate your own entity types
Once you've seen the built-in agents in action, you can define your own entity types in your own app.
Set up your app
Your app is a separate project that uses @durable-streams/darix-runtime to define entities and handle webhooks. To use the local (unpublished) packages, add the durable-streams packages to your app's pnpm workspace.
For example, if your app is at ~/my-app and you cloned durable-streams to ~/durable-streams, add the following to your app's pnpm-workspace.yaml:
packages:
- "packages/*"
- "../durable-streams/packages/ts-darix-runtime"
- "../durable-streams/packages/client"
- "../durable-streams/packages/state"
- "../durable-streams/packages/server"Then run pnpm install in your app to link the workspace packages.
Create your app server
Create server.ts in your app:
import http from "node:http"
import {
createEntityRegistry,
createRuntimeHandler,
} from "@durable-streams/darix-runtime"
const DARIX_URL = process.env.DARIX_URL ?? "http://localhost:4437"
const PORT = Number(process.env.PORT ?? 3000)
const SERVE_URL = process.env.SERVE_URL ?? `http://localhost:${PORT}`
const registry = createEntityRegistry()
registry.define("assistant", {
description: "A general-purpose AI assistant",
async handler(ctx) {
ctx.useAgent({
systemPrompt: "You are a helpful assistant.",
model: "claude-sonnet-4-5-20250929",
tools: [...ctx.darixTools],
})
await ctx.agent.run()
},
})
const runtime = createRuntimeHandler({
baseUrl: DARIX_URL,
serveEndpoint: `${SERVE_URL}/webhook`,
registry,
})
const server = http.createServer(async (req, res) => {
if (req.url === "/webhook" && req.method === "POST") {
await runtime.onEnter(req, res)
return
}
res.writeHead(404)
res.end()
})
server.listen(PORT, async () => {
await runtime.registerTypes()
console.log(`App server ready on port ${PORT}`)
})This does four things:
- Defines an entity type called
assistantwith a handler that configures and runs an LLM agent. - Creates a runtime handler that connects to the DARIX runtime server.
- Starts an HTTP server that receives webhook callbacks from DARIX.
- Registers entity types with the DARIX runtime server on startup.
Run your app
Make sure the DARIX runtime server is already running, then:
npx tsx server.tsInteract with your entity
From the durable-streams repo:
pnpm darix spawn /assistant/my-assistant
pnpm darix send /assistant/my-assistant 'Hello!'
pnpm darix observe /assistant/my-assistantNext steps
- About — understand the mental model.
- Defining entities — entity types, schemas, and configuration.
- Writing handlers — handler lifecycle and context API.