Build your first feature with Claude Code
PLA first feature built with Claude Code follows six steps: define “done” as acceptance criteria, approve a plan in plan mode, pin the behaviour with failing tests, implement in small gated slices, review the diff in a fresh context, and commit with evidence. Tests and gates, not a line-by-line read, prove the result.
This page is for developers who have installed Claude Code and written a CLAUDE.md, and now have a real ticket in front of them. The feature touches five files, needs tests, and has to pass CI. The first attempt usually goes one of two ways: you ask for everything at once and receive a 600-line diff you cannot judge, or you approve every edit by hand and end up doing the work twice. The loop below avoids both.
What you’ll walk away with from your first Claude Code feature
Section titled “What you’ll walk away with from your first Claude Code feature”- A six-step loop you can reuse for any multi-file feature, with the Claude Code feature that drives each step.
- Seven copy-paste prompts, from “understand the ticket” to “commit with evidence”.
- A permission setup that lets Claude run your checks without asking every time.
- A way to trust the result by checking tests and gate output instead of reading every line.
- A symptom-and-recovery table for the ways a first feature usually goes wrong.
Which six steps does a Claude Code feature follow?
Section titled “Which six steps does a Claude Code feature follow?”The running example is a full-text search endpoint for a TypeScript REST API backed by PostgreSQL. Swap in your own ticket; the steps do not change.
| Step | What you do | Claude Code feature | Proof it worked |
|---|---|---|---|
| 1. Understand | Agree on acceptance criteria | Plan mode, @ file references | A numbered criteria list you approved |
| 2. Plan | Approve a step-by-step plan | Plan mode, /effort | An approved plan, saved to the repository right after approval |
| 3. Pin behaviour | Approve failing tests | Normal edits, test runner | Tests that fail for the right reason |
| 4. Implement | One slice at a time | Allow rules, hooks | Type check, lint, and tests green per slice |
| 5. Review | Review in a fresh context | /code-review, subagents | Findings list, each one fixed or dismissed |
| 6. Commit | Commit with evidence | In-session commit | Commit message plus a short evidence summary |
Before you start, check the prerequisite: initialise the project and write CLAUDE.md. If CLAUDE.md does not name your test, lint, and type-check commands, add them now. Claude runs whatever that file tells it to run.
Step 1: How do you get Claude to understand the ticket before it edits anything?
Section titled “Step 1: How do you get Claude to understand the ticket before it edits anything?”Start the session in plan mode, so Claude can read and search but cannot edit until you approve a plan:
claude --permission-mode plan -n search-endpointThe -n flag names the session, which makes it easy to find again tomorrow. Inside a running session, /plan or Shift+Tab switches to the same mode. If the real schema lives only in a running database rather than in migration files, connect a read-only database server first, as shown in MCP setup for Claude Code.
Edit the criteria until they say what you mean. They are the contract for everything that follows: the tests will encode them, and the review will check the diff against them. For a longer treatment of turning a ticket into testable criteria, see executable acceptance criteria.
Step 2: How do you get a plan you can actually approve?
Section titled “Step 2: How do you get a plan you can actually approve?”Ask for a plan that maps each step to the criteria it satisfies and to the check that proves it. A plan without checks is a to-do list; a plan with checks is something you can verify later without re-reading the code.
Push back on the plan while changing it is cheap:
Use a PostgreSQL GIN index on a tsvector column instead of LIKE, and add themigration as its own step before the query function.If the plan misses obvious constraints, raise the reasoning effort before you switch models: /effort high (one step above the default medium of Opus 5.5, the default model from v2.1.280; on models that already default to high, try xhigh). Deep reasoning covers when that pays off. When the plan is right, approve it and leave plan mode. Plan mode cannot edit repository files, so the plan exists only in the session until now. Make saving it the first instruction after approval:
Save the approved plan to docs/plans/search-endpoint.md. Do not implement anything yet.Saving the plan to a file matters more than it looks. The file survives /compact, /clear, and a new session, so Claude can re-read it instead of relying on conversation memory. Feature planning with Claude Code goes deeper on plan structure.
Step 3: Why write the failing tests before the implementation?
Section titled “Step 3: Why write the failing tests before the implementation?”The tests are the part of the change you read closely. If they encode the acceptance criteria correctly, a green run tells you the behaviour is right without reading every line of the implementation. That is the trade this workflow makes: you spend review attention on 60 lines of tests instead of 400 lines of code.
Check two things before you continue. Each criterion has a test, and each test fails for the right reason. Then tell Claude the tests are fixed:
These tests are now the specification. Do not modify, skip, or delete any of themfor the rest of this session. If you believe a test is wrong, stop and tell me why.Then commit the approved tests on your feature branch, so that you have a fixed reference to compare against later:
git add tests/api/search.test.tsgit commit -m "test: pin search endpoint behaviour"If your CI requires every commit to pass, squash this commit into the feature commit before you push. A prompt is a request, not a guarantee, so Step 5 checks that the tests stayed unchanged. For checks that the agent cannot edit at all, see protecting the oracle.
Step 4: How do you implement in slices without approving every command?
Section titled “Step 4: How do you implement in slices without approving every command?”Implement one plan step at a time and run the gates after each one. A type error found after one slice costs a minute; the same error found after five slices has spread through code that was built on it.
Google Cloud’s DORA team makes the same argument for small batches: “AI can easily generate massive blocks of code, which are hard to review and test. Enforcing the discipline of small batches counteracts this risk” (Nathen Harvey and Allison Park, Google Cloud blog, 2025-12-10).
Let Claude run your checks without prompting
Section titled “Let Claude run your checks without prompting”Add allow rules for your check commands to .claude/settings.json so that the gate step does not stop for approval each time. Use your project’s script names:
{ "permissions": { "allow": [ "Bash(npm run typecheck)", "Bash(npm run lint)", "Bash(npm test)", "Bash(npm test *)" ] }}From v2.1.283 (both release channels on 2026-10-12), interactive sessions (terminal and VS Code, on models auto mode supports) start in auto mode, where a classifier approves routine actions. Allow rules still make the gate commands predictable, and they matter most in Manual mode and in claude -p runs, which start in Manual (auto mode on third-party providers or with telemetry off, from v2.1.285). Bash(npm test *) covers npm test -- search and other argument forms; the separate Bash(npm test) entry covers the bare command. Configuration explains the rule syntax, and permissions and sandboxing covers what to allow and what never to allow.
To make the type check run after every edit without asking, add a PostToolUse hook. Hooks automation shows the configuration.
Repeat this prompt until every step is done. When a slice goes wrong, rewind instead of arguing: press Esc twice with an empty prompt (or run /rewind) to restore the code and conversation to the last good checkpoint, then give a different direction. Error recovery covers checkpoints in detail.
Check the running feature, not only the tests
Section titled “Check the running feature, not only the tests”Unit and integration tests can pass while the endpoint still misbehaves over HTTP, for example because of a missing route registration or a middleware that rewrites the response.
Step 5: How do you review the diff without reading every line?
Section titled “Step 5: How do you review the diff without reading every line?”The session that wrote the code is the weakest reviewer of it, because it shares the assumptions that produced the code. Review in a fresh context instead. In Claude Code 2.1.283, /code-review is a bundled skill that reviews your branch’s commits ahead of its upstream plus any uncommitted changes. It runs as a background subagent with its own context window, so it does not inherit the implementation conversation. With no upstream, it falls back to the diff against main; to review another target, pass a branch name or PR number, for example /code-review search-endpoint.
/code-reviewThen run the checks that the reviewer cannot see from the diff alone.
You now read four short things instead of the whole diff: the review findings, the test-file change list, the criteria-to-test mapping, and any unplanned files. Read the code only where one of them points. Fix or explicitly dismiss every finding before you commit.
For a high-risk change, /code-review ultra runs a cloud-hosted multi-agent review that reproduces each finding. After three free runs on Pro and Max it typically costs $5 to $25 per review in usage credits, and it is not available on Bedrock, Google Cloud, Microsoft Foundry, or to Zero Data Retention organizations.
Step 6: How do you commit so a reviewer can trust the change?
Section titled “Step 6: How do you commit so a reviewer can trust the change?”Ask Claude to commit in the session. It writes the message from the actual diff, and it can attach the evidence from Step 5.
Claude Code 2.1.283 has no claude commit subcommand. Commit in the session as above, run git commit yourself, or use headless mode from your shell. A claude -p run starts in Manual mode (auto mode on third-party providers or with telemetry off, from v2.1.285) and cannot prompt you, so allow the git commands it needs:
claude -p "Commit the staged changes with a Conventional Commits message" \ --allowedTools "Bash(git diff *)" "Bash(git commit *)"Branches, pull requests, and splitting a tangled diff into several commits are covered in version control with Claude Code. A full PR evidence pack is described in the evidence bundle.
Who signs off: you approve the acceptance criteria, the tests and the evidence summary. Your team’s reviewer checks the same evidence and reads the code where the evidence points. Neither of you needs to read every line to know the endpoint behaves as specified.
How do you keep a longer feature on track across sessions?
Section titled “How do you keep a longer feature on track across sessions?”A feature that spans several sittings stays coherent when its state lives in files, not in the conversation. The plan file from Step 2 and the tests from Step 3 are that state.
- Resume where you left off:
claude -ccontinues the most recent conversation in the current directory.claude -r search-endpointopens the session picker filtered by that search term. - Free up context:
/compact keep the plan file path, the acceptance criteria, and the failing testssummarises the conversation and keeps what you name. - Start clean:
/clear, thenRead docs/plans/search-endpoint.md and continue with the next unfinished step. - Point at exact files:
Add a category filter to @src/api/routes/search.ts following @src/api/routes/products.tsis safer than “update the search module”.
Split along the plan, not along the clock: schema and migration in one session, query and route in the next, review and commit in the last.
What breaks when you build a feature with Claude Code?
Section titled “What breaks when you build a feature with Claude Code?”| Symptom | Likely cause | Recovery |
|---|---|---|
| A 600-line diff you cannot judge | The prompt asked for the whole feature at once | Rewind with Esc Esc or /rewind, then run Step 4’s prompt one plan step at a time |
| Tests pass, but a test file changed after you approved it | Claude edited the test to match the code | Restore them from the test commit with git checkout TEST_COMMIT -- tests/api/search.test.ts (TEST_COMMIT is the hash of your test: commit), repeat the “tests are the specification” instruction, and rerun the slice |
| Tests pass, but the endpoint fails over HTTP | Tests mock the layer that is broken | Run the end-to-end prompt from Step 4, then add an integration test for the failing request |
| Claude edits files the plan did not name | Vague file references | Use @ references to exact paths and ask Claude to justify every unplanned file before continuing |
| New code ignores your conventions | CLAUDE.md does not describe them | Add the missing rule to CLAUDE.md, then tell Claude to re-read it and redo the slice |
| The same fix fails three times | Claude is stuck in one approach | Type “Stop. That approach is not working. List two alternatives and their trade-offs.” If it keeps looping, /clear and restart from the plan file |
| Claude forgets decisions made an hour ago | Context is full of old tool output | /compact with explicit keep instructions, or /clear and re-read the plan file |
Where to go next after your first Claude Code feature
Section titled “Where to go next after your first Claude Code feature”Working in another tool? The same loop is described for Codex in your first task and for Cursor in your first feature.
Did this guide help you?
One tap, no sign-in.
What will you do with it?
How did it read?
What got in the way? Pick any that apply
Your role?
Thanks. I read every answer. Michał Jaskólski
Did this guide help?
One tap each. Close whenever you like.
no sign-in