Claude Code is a coding agent you start with claude inside a Node.js project, and it reads project-level instructions from CLAUDE.md. For Node.js work, that means giving the agent your exact install, test, lint, build commands and your module conventions before it touches code. This guide covers a practical setup, a small-step working loop, testing, and the Node.js-specific failure modes to watch.
Why Claude Code fits Node.js projects
Node.js projects are mostly text files, package scripts, and fast test suites, which makes them a good fit for an agent that can inspect files and run commands. Claude Code can read a stack trace and map it to the relevant source file, edit an Express route or Fastify plugin in place, and run npm test to get tight feedback after a change. Because Node.js uses the filesystem and child processes directly, an agent that can execute commands has access to the same feedback you use: test output, lint errors, and build logs. That makes it practical for tasks like adding an endpoint and immediately running the affected test file. The value increases when CLAUDE.md documents the exact commands, because the agent then follows your existing workflow instead of guessing at npm run check or npm run verify.
Preparing a Node.js project for Claude Code
Put a CLAUDE.md file in the repository root and keep it short: commands, module system, folder layout, and rules. The file should be specific to the project, not a generic Node.js guide. For a typical Express or Fastify service, the following block is enough to start.
# CLAUDE.md
Node.js project instructions for Claude Code.
## Commands
- Install dependencies: npm ci
- Run the dev server: npm run dev
- Run tests: npm test -- --run
- Lint: npm run lint
- Build: npm run build
## Project conventions
- ES modules are enabled with "type": "module" in package.json. Use import/export, not require/module.exports.
- Source code lives in src/. Tests live in test/ and use node:test.
- Keep Express routes thin. Business logic belongs in src/services/.
- Load environment variables from .env with dotenv, but never commit .env.
## Node.js rules
- Always await promises that can reject. Do not leave floating promises.
- Prefer async/await over callbacks.
- Use node: imports, such as node:fs and node:path.
- Do not call process.exit() inside library or service code. Set process.exitCode or throw instead.
If you use TypeScript, add the typecheck command and map src/ to dist/ so the agent does not edit build output. If you use Fastify, note that plugins must be async or use the done callback, because route handlers often need that context. The goal is to prevent the agent from re-learning rules that are already obvious to the team.
A practical edit-review loop
Use a short loop: plan first, change one piece, run the test command, and review the diff. Start with a plan mode pass before editing, then ask the agent to make the smallest change that satisfies the request. Ask the plan to list the files it intends to change and the exact test command it will run. Reject any plan that includes generated files or node_modules. After every change, have it run the exact test command from package.json and show the result. Finally, inspect git diff yourself and ask questions about any changes to package.json, package-lock.json, or environment setup.
Example prompts for common Node.js tasks:
- “Add a
GET /healthroute to the Express app that returns{ ok: true }. Do not change the existing error handling middleware.” - “Refactor
src/services/user.jsfrom callbacks to async/await and add a try/catch that maps errors to HTTP 500 responses.” - “Write node:test cases for
createUser, mocking the repository with an in-memory object. Runnpm testand fix only the test failures.” - “Find all floating promise warnings in the codebase and show a plan to fix the top three without editing files yet.”
- “Update the build script to use esbuild, then run
npm run buildand report any warnings.”
What Claude Code handles well vs. Node.js traps
The agent is useful for adding REST endpoints, writing request validation, converting callback code to async/await, adding tests, fixing failing assertions, updating package scripts, and explaining stack traces. It can also help with common config tasks such as adding dotenv loading or adjusting Fastify plugin registration, but it needs clear boundaries.
Watch closely around Node.js-specific areas:
- Module system. If package.json says “type”: “module”, Node requires import specifiers to include file extensions. The agent may write
import router from './routes/user'instead of./routes/user.js, which fails at runtime. - Floating promises. An unawaited promise can become an unhandled rejection and crash the process. Ask the agent to run a lint rule or test for this before merging.
- process.exit(). A service module that calls
process.exit(1)will make tests and imported scripts exit immediately. Prefer throwing an error and letting the entrypoint handle exit codes. - Non-watch test and dev commands. If the test script includes
--watch, the agent may hang in the terminal waiting for changes. Use the non-watch command in CLAUDE.md. - Package changes. The agent may update package.json or run
npm installto add a dependency. Review package-lock.json changes separately and ask for a one-line reason. - Source maps and build output. In TypeScript or bundled projects, stack traces may point to dist/ while the agent edits src/. Tell it to map errors back to source, not edit generated files.
- Top-level await and dynamic imports. If the app uses those features, state it in CLAUDE.md, because the agent may otherwise assume CommonJS and produce incorrect syntax.
For more on reducing these review mistakes, see the Claude Code best practices: a practical checklist.
Testing Node.js changes with the agent
Testing is the main verification loop for Node.js work. Have the agent run the test command after each step, read the failing output, and fix only what broke. For node:test projects, use node --test test/ or the npm script that maps to it. For Jest projects, make sure the command is non-interactive; many projects use jest --runInBand or --ci in CI but run watch mode locally. State the exact command in CLAUDE.md so the agent does not start a watcher. If the agent fixes a bug, ask it to add a regression test that fails on the old behavior and passes on the new one.
The table below lists commands that are useful to ask the agent to run after a change.
| Command | What it verifies |
|---|---|
npm test -- --run | Jest suite completes without failures; --run avoids watch mode |
node --test test/ | node:test runner executes all test files and reports failed assertions |
npm run lint | ESLint catches syntax errors, unused variables, and missing extensions in imports |
npm run build | TypeScript compiler or bundler catches type errors and emits output |
git diff --check | whitespace errors and accidental conflict markers in the diff |
After the tests pass, review the diff manually. Ask the agent to explain any file outside the intended scope, especially package-lock.json or environment configuration.
Running parallel agents on one Node.js project
For larger Node.js work, AgentVera helps run multiple Claude Code instances side by side in real terminal panels. The most useful parts are parallel git worktrees, so agents can edit different branches without overwriting files; automatic code review that links findings to file:line, which is valuable when async stack traces hide the true source; token budgets, so long npm install and test loops do not exhaust one agent session; and checkpoints for rolling back a bad refactor. Those matter more than broad orchestration for day-to-day Express or Fastify work.
Final notes
Keep the agent grounded in your Node.js project by making CLAUDE.md the single source of truth for commands and module rules. Work in small planned steps, require tests after each change, and inspect the diff like you would for a pull request. With that discipline, Claude Code handles Express and Fastify additions, async refactors, and test fixes without turning a quick change into a debugging session.