Quickstart
Prerequisites
Section titled “Prerequisites”- Bun ≥1.0.0 (
curl -fsSL https://bun.sh/install | bash) - An API key from Anthropic, Google Gemini, OpenAI, or LiteLLM — or run a local model with Ollama (no key needed)
The fastest path through this guide is the rax workflow (Rax = Reactive Agents Executable).
1. Create a Project
Section titled “1. Create a Project”Using the CLI:
bunx rax init my-agent-app --template standardcd my-agent-appbun installrax init --template standard scaffolds:
Directorymy-agent-app/
Directorysrc/
- agent.ts Your first agent — runnable with
bun run src/agent.ts Directorytools/ Drop custom tools here; auto-discovered when wired into builder
- …
- agent.ts Your first agent — runnable with
- .env Provider API keys (gitignored by default)
- package.json
reactive-agentsdependency +bun run agentscript - tsconfig.json strict mode + Bun-aware module resolution
- README.md
Or manually:
mkdir my-agent-app && cd my-agent-appbun init -ybun add reactive-agents2. Set Up Environment
Section titled “2. Set Up Environment”Set at least one provider key. Pick whichever you have access to:
# Pick at least oneecho 'ANTHROPIC_API_KEY=sk-ant-...' > .env # Recommended for first agentecho 'OPENAI_API_KEY=sk-...' >> .envecho 'GOOGLE_API_KEY=...' >> .env
# Or run fully local — no key neededollama pull qwen3:4bOptional keys for built-in tools (web search, etc.) — add them later when you call .withTools():
echo 'TAVILY_API_KEY=tvly-...' >> .env # Web search (Tavily backend)echo 'SERPER_API_KEY=...' >> .env # Web search (Serper.dev backend)3. Build an Agent
Section titled “3. Build an Agent”Create src/agent.ts:
import { ReactiveAgents } from "reactive-agents";
const agent = await ReactiveAgents.create() .withProvider("anthropic") .build();
const result = await agent.run("What are the three laws of thermodynamics?");console.log(result.output);That’s the minimum. .withProvider() picks the default model for the provider automatically (claude-sonnet-4-6 for Anthropic). Set ANTHROPIC_API_KEY in your environment before running.
To pin a specific model or add a name:
const agent = await ReactiveAgents.create() .withName("my-first-agent") .withProvider("anthropic") .withModel("claude-sonnet-4-6") .build();
const result = await agent.run("What are the three laws of thermodynamics?");console.log("Output:", result.output);console.log("Duration:", result.metadata.duration, "ms");console.log("Steps:", result.metadata.stepsCount);4. Run It
Section titled “4. Run It”bun run src/agent.ts5. Add Capabilities
Section titled “5. Add Capabilities”The canonical composition path is a HarnessProfile preset — lean(),
balanced(), or intelligent(). Presets compose the registry’s
default-on capability set so you don’t pile up redundant .withX()
calls.
import { ReactiveAgents, HarnessProfile } from "reactive-agents";
const agent = await ReactiveAgents.create() .withName("research-agent") .withProvider("anthropic") .withModel("claude-sonnet-4-6") .withProfile(HarnessProfile.balanced()) // memory + RI + verifier + strategy switching .build();Pick the preset that matches the workload:
HarnessProfile.lean()— model + nothing else. Latency- and cost-sensitive paths; benchmark ablations.HarnessProfile.balanced()— today’s production defaults (memory + reactive intelligence + verifier + strategy switching).HarnessProfile.intelligent()— balanced + skill persistence for cross-session compounding learning.
Override one capability after the preset — order matters; later calls win:
const agent = await ReactiveAgents.create() .withName("research-agent") .withProvider("anthropic") .withModel("claude-sonnet-4-6") .withProfile(HarnessProfile.balanced()) .withMemory({ tier: "enhanced" }) // upgrade memory to vector embeddings .compose((h) => h.before("act", logFn)) // canonical chokepoint composition .build();Individual .withX() methods still work for backward compatibility,
but most are now @deprecated aliases for either a HarnessProfile
preset or a .compose(...) chokepoint. Check the JSDoc on a method
to see which preset / compose primitive it routes to.