Skip to main content

Featured Post

AI-Native SDLC for Web Development: A Step-by-Step Guide with Claude Code

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...

AI-Native SDLC for Web Development: A Step-by-Step Guide with Claude Code

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 WishlistItem table (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 /wishlist page (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 in CLAUDE.md so 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 dangerouslySetInnerHTML and 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

  1. Run /init and turn the output into a short, specific CLAUDE.md.
  2. Pick your next small feature and write its intent.md before any code.
  3. Use Plan Mode to write the spec.md, and have a human review it.
  4. Make sure typecheck, lint, and tests run with one command each, both locally and in CI.
  5. Add one hook: auto-format, or block one dangerous command.
  6. Turn on AI PR review, and add CODEOWNERS for your sensitive paths.
  7. 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

Popular posts from this blog

Understanding SQL Query Execution Order

When writing SQL queries, understanding the execution order is crucial for writing efficient and optimized code. Many beginners assume that queries execute in the order they are written, but in reality, SQL follows a specific sequence of execution. SQL Execution Order SQL queries run in the following order: 1️⃣ FROM + JOIN 2️⃣ WHERE 3️⃣ GROUP BY 4️⃣ HAVING 5️⃣ SELECT (including window functions) 6️⃣ ORDER BY 7️⃣ LIMIT Let’s break down each step with examples. 1. FROM + JOIN (Data Retrieval) The SQL engine first retrieves data from the specified table(s) and applies any JOIN operations. 🔹 Example: SELECT employees.name, departments.department_name FROM employees JOIN departments ON employees.department_id = departments.id; Here, the JOIN happens before any filtering ( WHERE ) or grouping ( GROUP BY ). 2. WHERE (Filtering Data) Once data is retrieved, the WHERE clause filters rows before aggregation occurs. 🔹 Example: SELECT * FROM employees WHERE salary > 50000 ; Thi...

Top 5 React.js Performance Optimization Techniques for 2025

React.js continues to dominate the front-end development landscape due to its flexibility, component-based architecture, and performance. However, as applications grow, performance issues can emerge, affecting user experience. Here are the top five performance optimization techniques every React developer should consider in 2024. 1. Use React.memo for Component Memoization React.memo is a higher-order component that prevents unnecessary re-renders by memoizing the result. It only re-renders when props change, improving performance for functional components that rely on the same data. import React from 'react';  const ExpensiveComponent = React.memo(({ data }) => {      console.log('Rendering ExpensiveComponent');      return <div>{data}</div>;  }); export default ExpensiveComponent; 2. Implement Code Splitting with React.lazy and Suspense Code splitting reduces the initial load time by splitting the code into smaller bundles. Re...

Best Practices for Securing Personal and Business Data in 2025

In today’s digital landscape, cybersecurity is more critical than ever. With increasing cyber threats, data breaches, and privacy concerns, individuals and businesses must take proactive steps to secure their data. This guide outlines the most effective security practices for 2025. 1. Implement Strong Authentication Measures Passwords alone are no longer sufficient to protect sensitive accounts. Instead, consider: ✅ Multi-Factor Authentication (MFA): Require users to verify their identity using an additional factor, such as an SMS code, authenticator app, or biometric authentication. ✅ Passkeys & Password Managers: Use passkeys where available and store strong, unique passwords in a secure password manager. 2. Encrypt Sensitive Data Encryption ensures that even if data is stolen, it remains unreadable without the decryption key. 🔹 Use end-to-end encryption (E2EE) for messages and emails. 🔹 Encrypt stored data on cloud services, external drives, and local machines. 🔹 Consider ...