Skip to main content
Anvil is distributed as a single npm package, published as anvil-sdk — the anvil name on npm belongs to an unrelated package, so the install command uses anvil-sdk while every CLI command you run stays anvil (anvil dev, anvil build, and so on). This page covers everything needed to go from an empty directory to a correctly configured, running Anvil project.

Requirements

  • Node.js ≥ 20 — Anvil relies on the native Request, Response, Headers, and ReadableStream APIs that ship with Node 20; there’s no polyfill layer.
  • An ESM project — Anvil is ESM-only. Your package.json must declare "type": "module".
  • npm, yarn, or pnpm — any of the three major package managers work; examples below cover all three.

Install the package

zod is a direct dependency of your route and tool schemas — install it alongside Anvil. Anvil re-exports the pieces of Zod it needs internally, but you write your own z.object(...) calls, so it must be present in your own dependencies.
The package name is anvil-sdk, but every command you run is still anvilnpx anvil dev, npx anvil build, and so on. Only the string you pass to npm install/yarn add/pnpm add uses the -js suffix.

Scaffold with anvil init

The fastest path to a working project is anvil init — it writes package.json, tsconfig.json, .gitignore, and a starter route or two, so you don’t hand-assemble the project structure yourself:
Without any flags, and when stdin is a TTY, it prompts you to pick a starting point:
A minimal REST API — one static route (GET /) and one dynamic route (GET /users/[id]). The default template; good for plain HTTP APIs with no AI surface.
Pass -y to accept the basic default without prompting — useful in CI or scripts:
anvil init never overwrites a file that already exists — running it in a directory that already has a package.json merges in the dev/build/start/lint scripts and the anvil-sdk/zod dependencies (without clobbering versions you’ve already pinned) instead of starting over. Re-running it is always safe; it reports what it wrote and what it skipped:
It only writes files — it doesn’t run npm install for you and doesn’t assume a package manager, so run that yourself afterward:

Full anvil init reference

Every flag, what gets merged versus created, and non-interactive usage for CI.

Configure package.json by hand

If you’d rather not use anvil init, add "type": "module" yourself and wire up the scripts:
package.json
If you omit "type": "module", Node treats your files as CommonJS and import ... from 'anvil-sdk' fails with a syntax error at the first import/export statement. ESM is required — there is no CommonJS build.

Project structure

Route handlers live under server/routes/; everything else is up to you:
A minimal tsconfig.json — the one anvil init writes:
tsconfig.json
moduleResolution: "bundler" matches how anvil dev/anvil build resolve subpath exports like anvil-sdk/agent and anvil-sdk/llm — using "node16" or "nodenext" instead still works, but "bundler" gives the cleanest editor experience for these deep imports.

Optional peer dependencies

Core routing and middleware need nothing beyond anvil-sdk and zod. AI provider drivers and persistence adapters are optional peer dependencies, loaded lazily — install only what you actually use, and pure-REST projects stay lean.

Anthropic (Claude)

Required to use AnthropicDriver from anvil-sdk/llm in an agent route or LlmClient.

OpenAI (GPT / o-series)

Required to use OpenAIDriver from anvil-sdk/llm.

Google Gemini

Required to use GeminiDriver from anvil-sdk/llm.

SQLite persistence

Required for SqliteStateStore, SqliteTraceStore, or SqliteVectorStore — persists traces, checkpoints, memory, and vectors across restarts instead of losing them on process exit.
Using a driver or store whose peer dependency isn’t installed throws a clear error at the call site naming the missing package and the in-memory alternative you can fall back to — it never fails silently.

CLI commands reference

Once installed, the anvil binary is available in node_modules/.bin/. Run it through your package manager’s script runner (npm run dev, or npx anvil dev directly):

anvil CLI overview

Deeper reference for every command, including flags not covered above.

Verify the installation

Create a minimal route and start the dev server to confirm everything is wired correctly:
server/routes/get.ts
If you see that JSON response, the installation is complete and the dev server is correctly loading your route files.

Next steps

Quickstart

Build a validated dynamic route, expose it as an MCP tool, and add a streaming agent — one walkthrough.

anvil init

Every template, flag, and file it writes — including how it merges into an existing project.

File-Based Routing

The full routing convention: verbs, groups, catch-alls, and the generated route manifest.

MCP Overview

Expose routes and standalone tools as MCP tools over stdio or Streamable HTTP.