Skip to content

How to Build AI Agents in TypeScript

If you want to build AI agents in TypeScript — agents that reason, call tools, remember context, and stream results into your app — this guide is the map. It explains what an agent actually is, the pieces you need for production, and how to assemble them with Reactive Agents, a type-safe TypeScript agent framework built on Effect-TS.

An AI agent is an LLM wrapped in a loop. Instead of answering once, it thinks, acts (calls a tool), observes the result, and repeats until the task is done. That loop — plus the machinery to keep it safe, observable, and affordable — is what an agent framework gives you, so you don’t hand-roll retry logic, tool parsing, and context management for every project.

TypeScript is a strong fit for agents: you get end-to-end types across tool inputs/outputs and model responses, the same language on server and client, and the npm ecosystem. Reactive Agents leans into that — every tool, hook, and result is a typed value, and errors are tagged rather than thrown.

Install the umbrella package and run your first agent in under a minute:

Terminal window
bun add reactive-agents
# or: npm install reactive-agents
import { ReactiveAgents } from "reactive-agents";
const agent = await ReactiveAgents.create()
.withProvider("anthropic")
.withModel("claude-sonnet-4-6")
.build();
const result = await agent.run("Explain quantum entanglement in two sentences.");
console.log(result.output);
console.log(result.metadata); // { duration, cost, tokensUsed, stepsCount }

That’s a working agent. Everything below is opt-in — you add capabilities one .with() call at a time, and only pay for what you enable. See the Quickstart for a guided version.

A toy agent is one LLM call. A production agent needs more, and each piece is a composable layer:

The think → act → observe cycle. Reactive Agents ships six strategies — ReAct, Reflexion, Plan-Execute, Tree-of-Thought, Adaptive, and Code-Action — and switches between them when a task calls for it. Add it with .withReasoning(). → Reasoning Strategies · Choosing a Strategy

Agents act by calling tools. Define your own with a typed builder, or plug in any MCP server (filesystem, GitHub, databases, browsers, and thousands more). Adaptive tool calling routes between native function-calling and text-parsing so the same code works on frontier and small local models. → Tools guide · Tutorial: agent with tool calling + MCP

Working, episodic, semantic (vector + full-text), and procedural memory let an agent carry context across steps and sessions. Add it with .withMemory(). → Memory guide

Stream tokens into your UI as they generate, with cancellation. Bridge a server agent to a browser with one line of SSE, and consume it with first-party React, Vue, and Svelte adapters. → Web Integration · Tutorial: add an agent to Next.js

Production agents need guardrails (injection/PII/toxicity), budgets and model routing to control spend, and tracing to see every decision. Each is one builder call: .withGuardrails(), .withBudget(), .withObservability(). → Guardrails · Cost Optimization · Production Checklist

The same agent code runs on a 4B-parameter local Ollama model and on Claude, GPT, or Gemini — swap one line. Model-adaptive context profiles tune prompts and compaction so small models punch above their weight. → Local Models · Tutorial: build a local agent with Ollama

Composed, this is what a real agent looks like — a research agent with tools, memory, and a budget cap:

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 + reactive intelligence + verifier
.withTools() // built-in tools + MCP
.withMaxIterations(15)
.withBudget({ tokenLimit: 100_000 }) // hard spend cap
.build();
const result = await agent.run("Research the latest TypeScript 6 features and summarize them.");

HarnessProfile.balanced() turns on the production default set in one line; lean() and intelligent() are the other presets. See Choosing a Stack.

Hands-on tutorials, each a complete build:

More patterns live in the Cookbook.

If you’re evaluating TypeScript agent frameworks, see the honest, sourced breakdowns:

Most agent frameworks are dynamically typed, monolithic, and opaque — they assume a frontier model and hide every decision. Reactive Agents is the opposite: end-to-end type-safe, composable (enable only what you need), observable (a 12-phase execution engine with hooks on every phase), and model-agnostic (the same code from local Ollama to frontier APIs). It’s MIT-licensed and published as 33 packages on npm.

Ready to build? Start with the Quickstart or Your First Agent.