Setup guide · Essentials
Node.js, pnpm and TypeScript
A current Node.js LTS, pnpm and a minimal TypeScript project that runs .ts files directly with node, with tests and a type check.
Many exercises and answer projects are small TypeScript programs: MCP servers, Agent SDK scripts and evaluation harnesses. This page sets up the toolchain they assume: Node.js 22.18 or newer (the current LTS is better), pnpm, and a project layout where node runs TypeScript directly, with no build step.
Before you start
- Works on macOS, Linux and Windows. On Windows, use PowerShell.
- If you already have Node, run
node --version. Anything fromv22.18.0up can run.tsfiles with no flags. The current LTS (v26 at the time of writing) is the best choice, and eve needs v24 or newer.
1. Install Node.js with fnm
fnm is a fast Node version manager. It lets you switch versions per project.
macOS
brew install fnmLinux
curl -fsSL https://fnm.vercel.app/install | bashWindows
winget install Schniz.fnmNext, set up your shell so fnm can put the right node on your PATH. Add the line for your shell to its profile and open a new terminal.
# ~/.zshrc (macOS default) or ~/.bashrc
eval "$(fnm env --use-on-cd --shell zsh)" # use --shell bash in ~/.bashrc# PowerShell profile: run `notepad $profile` to edit it
fnm env --use-on-cd --shell powershell | Out-String | Invoke-ExpressionThen install the current LTS line (v26 at the time of writing; fnm install --lts also works) and make it the default:
fnm install 26
fnm default 26
node --versionIf you don't want a version manager, use the installer from nodejs.org/en/download instead.
2. Install pnpm
pnpm 12 is a standalone binary. On macOS and Linux:
curl -fsSL https://get.pnpm.io/install.sh | sh -On Windows, pnpm recommends the npm route, because Windows Defender sometimes blocks the standalone executable:
npm install -g pnpm@latestOpen a new terminal and check the version with pnpm --version.
3. Create the project layout exercises assume
Answer projects follow this shape. Create it once to see it work:
mkdir ts-check && cd ts-check
mkdir src test
pnpm init
pnpm add -D typescript @types/nodeEdit package.json so it has these fields:
{
"name": "ts-check",
"private": true,
"type": "module",
"engines": { "node": ">=22.18" },
"scripts": {
"start": "node --env-file-if-exists=.env src/main.ts",
"test": "node --test",
"typecheck": "tsc --noEmit"
}
}Keep the devDependencies block that pnpm add wrote; only the fields shown change.
Add the tsconfig.json that the Node docs recommend for type stripping, plus strict:
{
"compilerOptions": {
"target": "esnext",
"module": "nodenext",
"noEmit": true,
"strict": true,
"rewriteRelativeImportExtensions": true,
"erasableSyntaxOnly": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true,
"types": ["node"]
},
"include": ["src", "test"]
}Then three small files:
export function greet(name: string): string {
return `Hello, ${name}!`;
}import { greet } from "./greet.ts";
console.log(greet(process.env.NAME ?? "world"));import { test } from "node:test";
import assert from "node:assert/strict";
import { greet } from "../src/greet.ts";
test("greets by name", () => {
assert.equal(greet("Ada"), "Hello, Ada!");
});What each piece does:
node src/main.tsruns TypeScript by stripping the types. Node doesn't type-check, sopnpm typecheckrunstscfor that.- Imports keep the
.tsextension (./greet.ts). Node requires it, andrewriteRelativeImportExtensionskeepstschappy. erasableSyntaxOnlymakestscreject syntax Node can't strip:enum, parameter properties, namespaces with runtime code. Use union types and plain classes instead.node --testfinds*.test.tsfiles on its own, so you don't need a test framework.--env-file-if-exists=.envloads settings such as your OpenRouter key (ANTHROPIC_AUTH_TOKENorOPENAI_API_KEY) from a.envfile when there is one. Add.envto.gitignore.
Check it works
pnpm install && pnpm start && pnpm test && pnpm typecheckExpected output, trimmed:
Hello, world!
ℹ tests 1
ℹ pass 1
ℹ fail 0pnpm typecheck prints nothing when it passes.
Troubleshooting
Unknown file extension ".ts". Your Node is older than 22.18. Run node --version. If fnm installed a newer one, the shell setup line is missing from your profile, or you haven't opened a new terminal since adding it.
Cannot find module './greet'. Add the extension: import { greet } from "./greet.ts".
An error about unsupported TypeScript syntax, often pointing at an enum. Type stripping can't handle that syntax. Rewrite it as erasable TypeScript, or run the file with tsx.
pnpm: command not found after installing. Open a new terminal; the installer edits your shell profile. On Windows, check that npm's global folder is on PATH (npm prefix -g).
Going further
- Python with uv for the Python exercises
- MCP servers in Claude Code, which registers a TypeScript server you write
Sources
- Running TypeScript nativelyDocs · Node.jsWhich Node versions run `.ts` files without flags, and what type stripping can't handle.
- Modules - TypeScriptDocs · Node.jsThe recommended `tsconfig.json`, mandatory `.ts` import extensions and other type-stripping rules.
- fnm (Fast Node Manager)DocsInstalling fnm and setting up your shell on each OS.
- pnpm installationDocs · pnpmThe standalone installers, the npm route and the Node compatibility table.
Exercises that use this
- Watch the agent loop in Claude CodeAgent Foundations · What is an agent?
- Run the same task through the Agent SDKAgent Foundations · What is an agent?
- Build a register tool and give it to Claude CodeAgent Foundations · Tools and the agent-computer interface
- Turn the tool into an MCP serverAgent Foundations · Tools and the agent-computer interface
- Measure context and move procedure into a skillAgent Foundations · Context engineering
- Isolate lease reading in a subagentAgent Foundations · Context engineering
- Produce and verify grounded title reportsAgent Foundations · Structured outputs and grounding
- Same report through the Agent SDKAgent Foundations · Structured outputs and grounding
- Build a chain with a code gate, then add routingAgent Foundations · Workflow patterns
- Orchestrator-workers and an evaluator loop with subagentsAgent Foundations · Workflow patterns
- Build and run a 10-case evalAgent Foundations · Risk and first evals
- Block outbound actions with a hookAgent Foundations · Risk and first evals
- One task, two modes of the same harnessBuilding Agents with Claude and eve · Choosing a harness
- Guardrails in Claude Code: tool, permissions, hooksBuilding Agents with Claude and eve · The Claude Agent SDK
- Run the title-review agent on the SDKBuilding Agents with Claude and eve · The Claude Agent SDK
- An enquiries skill and a search-reviewer subagent in Claude CodeBuilding Agents with Claude and eve · Skills and subagents
- Port the skill and subagent to eveBuilding Agents with Claude and eve · Skills and subagents
- A solicitor-approved send in eveBuilding Agents with Claude and eve · Human approval for high-stakes actions
- The same gate in the Agent SDKBuilding Agents with Claude and eve · Human approval for high-stakes actions
- Route auth and tenant isolation, checkedBuilding Agents with Claude and eve · Shipping agents
- Deploy to Vercel with a deployable modelBuilding Agents with Claude and eve · Shipping agents
- Write an eval charter for one agentEvaluating and Scoring Agents · Why evals, and their vocabulary
- Run your first repeated trials in Claude CodeEvaluating and Scoring Agents · Why evals, and their vocabulary
- Build a trace viewer and a counted taxonomyEvaluating and Scoring Agents · Error analysis from traces
- Generate a balanced 24-task datasetEvaluating and Scoring Agents · Error analysis from traces
- Mutation-test your gradersEvaluating and Scoring Agents · Code-based graders
- Build a Claude Code judge and measure its position biasEvaluating and Scoring Agents · LLM-as-judge
- Calibrate your Claude Code judge against your own labelsEvaluating and Scoring Agents · Calibrating judges
- Pick a t.judge threshold and correct a reported rateEvaluating and Scoring Agents · Calibrating judges
- Single agent versus lead plus subagents in Claude CodeProduction Agent Systems · Multi-agent systems
- Fan out to eve subagents with structured resultsProduction Agent Systems · Multi-agent systems
- Build and break an idempotent outboxProduction Agent Systems · Durable, long-running agents
- An eve workflow tool that waits for a search resultProduction Agent Systems · Durable, long-running agents
- Red-team and harden a pack-reading agent in Claude CodeProduction Agent Systems · Security and prompt injection
- Fixed recipients and a locked sandbox in eveProduction Agent Systems · Security and prompt injection
- Build a hash-chained audit log and a supervision samplerProduction Agent Systems · Compliance and auditability
- Trace Claude Code runs and build a per-matter budget reportProduction Agent Systems · Observability and cost
- Build a paired upgrade gate for Claude Code runsProduction Agent Systems · Continuous improvement