In my previous post I summarized Anthropic's AI-Native SDLC Playbook, which explains how to redesign the software lifecycle once AI agents can write code faster than your process can absorb it. This post is the practical follow-up: how to actually apply it to a web development project, step by step, with files you can copy into your own repo.
Throughout this post I'll use one running example: a Next.js + TypeScript e-commerce app that needs a new "Wishlist" feature. The same steps work for React + Node, Vue, Laravel, Django, or any other web stack. Only the commands change.
The workflow at a glance
Each stage ends by committing a file, and the next stage starts by reading it:
Plan → docs/intent/wishlist.md (what and why)
Design → docs/specs/wishlist.md (how)
Build → code + tests (guided by CLAUDE.md and Skills)
Test → passing tests + CI evals
Deploy → PR with AI review findings → human approval → CI/CD
Maintain → metrics/incidents → a new intent.md → back to Plan
Step 0: Set up the repo for agents
Install Claude Code, open your project, and run /init. It scans the codebase and creates a starting CLAUDE.md. Then edit that file by hand. It's the most important file in this workflow, because Claude reads it at the start of every session.
A good CLAUDE.md for a web app is short and specific:
# Project: ShopFront (Next.js 15, App Router, TypeScript)
## Commands
- Dev server: npm run dev
- Type check: npm run typecheck
- Lint: npm run lint
- Unit tests: npm test (Vitest)
- E2E tests: npm run test:e2e (Playwright)
## Conventions
- Server Components by default; add "use client" only when needed
- Data access only through src/lib/db/* (Prisma). Never query from components
- Styling: Tailwind. No inline style objects
- Every new API route needs input validation with zod
- Every new UI feature needs at least one Playwright test
## Gotchas
- Auth session comes from getSession() in src/lib/auth.ts, not from cookies directly
- Prices are stored in cents (integers). Never use floats for money
## Before you say a task is done
Run typecheck, lint and tests. Fix failures instead of skipping them.
Commit it. From now on, when a reviewer catches a mistake Claude repeats, add a line here rather than correcting it again in chat. This file is how your team's knowledge builds up over time.
Step 1 (Plan): Capture the request as intent.md
Requirements usually arrive scattered across a Slack thread, a support ticket, and a meeting note. Paste them into Claude and ask:
Summarize these notes into docs/intent/wishlist.md with: problem, users affected,
goals, non-goals, success metrics and open questions. Don't propose a solution yet.
The result looks like this:
# Intent: Wishlist
## Problem
Users can't save products for later; 18% of support tickets ask for it.
## Goals
- Logged-in users can add/remove products to a wishlist
- Wishlist persists across devices
## Non-goals
- Sharing wishlists, guest wishlists (later)
## Success metrics
- 10% of active users save at least one item within 30 days
- No regression in product page LCP (stay under 2.5s)
## Open questions
- Max items per wishlist?
Human gate: the product owner reviews the file, answers the open questions, and merges it. Nobody writes code until this is approved.
Step 2 (Design): Write the spec in Plan Mode
Switch Claude Code into Plan Mode (press Shift+Tab until it shows plan mode). In this mode Claude can read your code and propose a plan, but it can't edit files. Then ask:
Read docs/intent/wishlist.md and the existing cart feature.
Propose a design in docs/specs/wishlist.md: data model, API routes,
components, edge cases, and a test plan. Follow CLAUDE.md conventions.
A good web spec includes:
- Data model: a
WishlistItemtable (userId, productId, createdAt) with a unique constraint - API:
GET/POST/DELETE /api/wishlist, with zod validation and auth required - UI: a heart button on the product card (client component), plus a
/wishlistpage (server component) - Edge cases: a product that gets deleted, double clicks, a user who isn't logged in
- Test plan: unit tests for the API and a Playwright test for add → view → remove
Human gate: a senior developer reviews the spec. Fixing a design mistake here costs minutes. Fixing it after the code is written costs days.
Step 3 (Build): Implement against the spec
Now let Claude build it:
Implement docs/specs/wishlist.md. Write the tests first, then the code.
Run typecheck, lint and tests after each part.
3a. Turn repeated tasks into Skills
If your team builds the same kind of thing again and again (API routes, forms, pages), save the recipe as a Skill. A Skill is a folder containing a SKILL.md file. Claude loads it automatically whenever a task matches its description.
.claude/skills/new-api-route/SKILL.md
---
name: new-api-route
description: Use when creating a new Next.js API route in this project.
---
1. Create the route in src/app/api/<name>/route.ts
2. Validate input with a zod schema in src/lib/schemas/<name>.ts
3. Check auth with getSession(); return 401 if missing
4. Use src/lib/db helpers only. No raw Prisma in the route
5. Add tests in src/app/api/<name>/route.test.ts covering 200, 400, 401
Now every API route Claude writes follows your team's pattern, not just whatever pattern is most common online.
3b. Use subagents and parallel sessions for independent work
Front-end and back-end work can often run in parallel. Use separate git worktrees so the sessions don't overwrite each other's changes:
git worktree add ../shop-wishlist-api -b wishlist-api
git worktree add ../shop-wishlist-ui -b wishlist-ui
# run one Claude Code session in each folder
You can also define reusable subagents in .claude/agents/, for example an accessibility-reviewer that checks new components for labels, focus states, and color contrast. Claude can hand work to a subagent without filling up the main session's context.
Step 4 (Test): Give Claude a feedback loop
Claude does its best work when it can check its own output. For web projects, that means:
- Fast checks:
typecheck,lint, and unit tests, which are listed inCLAUDE.mdso Claude runs them - Browser checks: Playwright tests that click through the real UI
- Visual checks: let Claude take a screenshot of the page (for example with the Playwright MCP server) and compare it against the design
Then make quality checks continuous by running them in CI on every push, not only at the end of a sprint:
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npm ci
- run: npm run typecheck
- run: npm run lint
- run: npm test
- run: npx playwright install --with-deps
- run: npm run test:e2e
- run: npx lhci autorun # Lighthouse budget: fails if LCP/CLS regress
The Lighthouse step ties back to the success metric in intent.md ("no regression in LCP"). That's the playbook's idea of evals: automated checks that measure what you said mattered.
Step 5 (Deploy): AI review, hooks as gates, humans where it matters
5a. Hooks: rules enforced while the agent works
Hooks are shell commands that Claude Code runs automatically at specific points. Here's a .claude/settings.json that formats every file Claude edits and blocks a few dangerous commands:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "npx prettier --write \"$CLAUDE_PROJECT_DIR\"/src --log-level silent" }
]
}
],
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-dangerous.sh" }
]
}
]
}
}
#!/bin/bash
# .claude/hooks/block-dangerous.sh
# Exit code 2 blocks the command, and the message is sent back to Claude.
cmd=$(jq -r '.tool_input.command')
if echo "$cmd" | grep -qE 'prisma migrate reset|git push --force|rm -rf /|DROP TABLE'; then
echo "Blocked by project policy: $cmd" >&2
exit 2
fi
exit 0
That's governance as the agent acts, not in a review meeting a week later.
5b. AI in the PR review loop
Run /install-github-app inside Claude Code to connect the Claude GitHub app to your repo. Claude can then review every pull request automatically, and you can mention @claude in PR comments to ask questions or request fixes. Tell it what to look for in web code:
- Missing auth checks or input validation on API routes
- XSS risks such as
dangerouslySetInnerHTMLand unescaped user content - Client components that could be server components, and large bundle imports
- Accessibility issues: missing labels, missing alt text, non-semantic buttons
Human gate: people still approve the merge. Point their attention at what the AI flagged, plus anything high-risk such as payments, auth, personal data, and database migrations. Add a CODEOWNERS file so those paths always require a named human reviewer.
5c. CI/CD
After merge, the pipeline deploys as usual (for example Vercel, Netlify, or your own pipeline). Use preview deployments per PR so reviewers can click through the feature, and a feature flag so the Wishlist can be rolled out gradually.
Step 6 (Maintain): Close the loop
After release, compare production data with the success metrics you wrote in Step 1:
- Analytics: are 10% of users saving items?
- Web Vitals: did the product page LCP stay under 2.5s?
- Error tracking: any new errors from
/api/wishlist?
When something breaks a target, don't just patch it. Ask Claude to turn the incident or metric into a new docs/intent/*.md. For example: "Wishlist button causes layout shift on mobile". That file goes back to Step 1, and the loop starts again with full history in git.
Final folder structure
shopfront/
├── CLAUDE.md
├── CODEOWNERS
├── .claude/
│ ├── settings.json # hooks
│ ├── hooks/block-dangerous.sh
│ ├── skills/new-api-route/SKILL.md
│ └── agents/accessibility-reviewer.md
├── docs/
│ ├── intent/wishlist.md
│ └── specs/wishlist.md
├── .github/workflows/ci.yml
└── src/...
Your first-week checklist
- Run
/initand turn the output into a short, specificCLAUDE.md. - Pick your next small feature and write its
intent.mdbefore any code. - Use Plan Mode to write the
spec.md, and have a human review it. - Make sure typecheck, lint, and tests run with one command each, both locally and in CI.
- Add one hook: auto-format, or block one dangerous command.
- Turn on AI PR review, and add
CODEOWNERSfor your sensitive paths. - After release, check the metrics and write the next
intent.md.
Final thoughts
None of this requires a big migration. Start with CLAUDE.md and intent.md on a single feature, and add hooks, Skills, and AI review as your team gets comfortable. The goal isn't to remove developers from the process. It's to spend their time on the decisions that need human judgment, and let the agent handle the rest.
Further reading: The AI-Native SDLC Playbook (Anthropic Academy) · Claude Code documentation · Part 1 on this blog.
Comments
Post a Comment