Build your website with Claude Code
This is a process, not a template. It teaches someone how to build a website they'd be proud of — in their own taste, with their own content, on whatever stack fits — using Claude Code as the builder. You supply the framework and the moves; they supply the vision.
Everything rests on one shift: the person is the director, Claude is the crew. They decide how it should feel and what's good enough; Claude scaffolds, writes, styles, verifies, and ships. Your job when running this skill is to pull the taste out of them, turn it into instructions Claude can execute, get something live fast, and then loop.
The one rule that governs everything: get a real, ugly, live site first, then improve it in small steps you can see. A site that's live on day one and iterated 50 times beats a masterpiece that never ships.
The mindset (say this out loud early)
- You direct, Claude builds. The person never has to write code — or even know the words. They describe feelings ("warmer", "this feels cramped", "too corporate") and point; Claude translates into pixels.
- Live first, pretty later. Deploy an empty shell before styling anything, so you debug the pipeline once, while there's nothing to break.
- Codify taste into files. Once they like a look, write it down as a design system both they and Claude read every session — that's what stops the site from drifting.
- Small, visible steps. One coherent change at a time; look at it; commit it. Big invisible changes are where sites go to die.
- Close the loop. Ship early, put it in front of real people, feed what they say straight back to Claude as the next to-do list.
- When stuck, ask Claude. Every step below — creating accounts, fixing a red terminal error, a confusing host screen — is something to hand back to Claude, not to solve alone. "I've never done this, walk me through it" and "here's a screenshot of what I see" are the two most useful things the person can say.
How to use this skill
Work the phases roughly in order, but they're not a rigid waterfall — Phase 4 (the iteration loop) is the engine that runs continuously underneath the others:
Phase 0 → 1 frame it and get it live · Phase 2 → 3 make it yours and fill it in ·
Phase 5 → 6 make it memorable and listen · Phase 4 runs the whole time.
Each phase gives you the goal, the moves, a copy-paste prompt for the person to hand Claude, and the one trap that most often wrecks it. Deeper material lives in the reference files — pull them in when a phase gets real.
Permission to stop. A calm one-page site — their name, one line about them, one link — is a real, finished website. If they're done after Phase 4, they're done. Phases 5–6 are for when they want more, not a bar they must clear.
Before you start (Claude can help with all of this)
The person needs four free things in place before Phase 1. All of it can be set up by asking Claude to walk them through it — don't assume they've done any of it:
- Claude Code, installed and open in a folder for the project.
- Node.js + npm (for most modern stacks) — Claude can check with
node -vand install it. - A GitHub account (free) — where the code lives and what the host watches.
- A hosting account — Vercel, Netlify, or Cloudflare Pages (free tiers are generous; some ask for a card even on free — no charge for a normal personal site).
If any of this is unfamiliar, the very first prompt should be:
I've never set up a coding project before. Check whether Node, npm, and git are installed on
my machine, and walk me through — one step at a time — installing anything missing and
creating free GitHub and [Vercel/Netlify] accounts. Tell me exactly what to click, and wait
for me at each step.
Quick start (a live site in an afternoon)
If the person wants momentum now:
- Draw out the taste brief. Ask the five Phase 0 questions; write the answers into a
short
BRIEF.md. (~15 min) - Scaffold + deploy an empty shell. Pick a stack + a push-to-deploy host (if unsure, say Next.js + Vercel and move on), generate the starter with its official CLI, push to GitHub, connect the host, and confirm the blank site is live at a real URL. (~30 min, more the first time — account signups and connecting GitHub to the host add ~20–30 min)
- Add the guardrail file. Create
AGENTS.mdtelling Claude to read the installed framework docs before writing code (Phase 1). (~2 min) - Build just the hero. One screen: their name, one line about them, one call to action, colors from the brief. Look at it in the browser. (~20 min)
- Nudge and commit. "make the heading bigger", "warmer background", commit, push — it's live. (~15 min)
They now have a real website at a real URL. Everything after is improvement — the easy part. (Timings assume the accounts above already exist; first-time setup adds time, and that's normal, not failure.)
Phase 0 — Frame it: taste and scope
Goal: be able to describe, in plain words and pictures, how the site should feel and what pages it needs — before a single component is built.
Moves
- Interview the person. Don't design yet; extract. Ask these five:
- Who is it for, and what do you want them to do or feel? (hire you, buy this, read your writing, "take me seriously", "see that I'm fun")
- Name the vibe in 2–3 words. ("warm and editorial", "clean and technical", "loud and playful", "quiet and expensive", "dark and brutalist"). Push for feelings, not features.
- Show me what you love. URLs of 2–3 sites, and screenshots, moodboards, or any image that captures the feeling — most people's taste is visual, not verbal, so let them paste pictures. And one site they hate. Steal structure and mood, never content.
- What's the one thing this site must nail? (the writing, the visuals, the work samples, being fast)
- What pages/sections do you actually need? Resist scope creep — most personal sites are Home + one or two more.
- Write the answers into a
BRIEF.mdat the repo root — the north star you and Claude check against. If they gave images, note what to take from each.
Prompt to hand Claude
Before we build anything, interview me about the website I want. Ask me, one at a time: who
it's for and what I want visitors to feel or do; the vibe in 2–3 words; sites I love (I'll
paste links AND screenshots/moodboard images — react to the images too) plus one I hate; the
single thing this site must nail; and what pages I actually need. Then write my answers into a
BRIEF.md as my north star. Don't write any site code yet.
The trap: starting to build before anyone can describe the feeling. If they can't name the vibe or show a picture of it, Claude defaults to generic-SaaS-template and every later fix fights that gravity. Get the feeling — in words or images — first.
Phase 1 — Foundation: get an empty site live, then guardrail it
Goal: a blank but real site, already deployed to a real URL with auto-deploy wired up — so every later change ships for free — plus a guardrail that keeps Claude on ground truth.
You don't need to know how to do any of this. Claude gives you the exact clicks and commands and waits while you do them. When a screen confuses you, screenshot it and paste it back — that's the whole workflow, not a failure.
Moves
- Pick the stack and host up front (table below). Prefer a host by the same people as the framework so defaults just work. Any lane is fine; the worst choice is spending a day choosing.
- Scaffold with the framework's official CLI, not by hand.
- Deploy the empty template first. Push to GitHub, connect the host, confirm the blank site is live before touching code — so you debug the pipeline while nothing else can break.
- Attach a custom domain early if they have one (it's the real address; the free
*.host.appURL is temporary). DNS — the setting that points a domain name at the site — can take a few hours to take effect, so start it early. No domain yet? The host URL is a fine place to begin; buy one later. - Add the ground-truth guardrail. Write an
AGENTS.md(and a one-lineCLAUDE.mdthat just says@AGENTS.md) telling any AI agent the installed framework may be newer than its training data, and to read the real docs innode_modules/<framework>/dist/docsbefore writing code. This one file prevents a whole class of hallucinated-API bugs. - Keep secrets out of git from the start. A
.gitignoreshould exclude env files and build output; never commit API keys or private addresses — keep them in the host's environment settings. Ask Claude to set this up with the repo. - Write down the deploy facts Claude can't infer: production URL, host, which branch auto-deploys, the exact repo slug, any gotchas. Save to a notes/memory file — the live domain usually isn't discoverable from the code.
- Set up local preview + a health check: a run config (or documented
devcommand + port) and a one-line check that the local URL returns HTTP 200, so you can look before you push.
Decision table — pick a lane and move on
| If the site is… | Reasonable default stack | Host |
|---|---|---|
| A portfolio / personal site / resume | Next.js or Astro | Vercel / Netlify |
| Mostly writing / a blog | Astro or Next.js | Vercel / Netlify |
| A single landing / marketing page | Astro or Vite + React | Netlify / Cloudflare Pages |
| Something you want to hand-edit as plain files | Plain HTML + CSS (no build step) | Netlify / CF / GitHub Pages |
| "I don't know, just make it work" | Next.js + Vercel | Vercel |
(The last row picks Next.js + Vercel only because it's the most-documented path for Claude to lean on — every lane above is equally legitimate.)
Prompt to hand Claude
Scaffold a brand-new [Next.js / Astro / plain HTML+CSS] site with its official tool, keep the
starter untouched, then walk me through: git init + first commit (with a .gitignore that
excludes env/secrets), creating a GitHub repo, and connecting [Vercel / Netlify] so every push
to main auto-deploys. Confirm the empty site is live at a real URL before we write any code.
Then create an AGENTS.md telling any AI agent the installed framework may be newer than its
training data and to READ the docs in node_modules/[framework]/dist/docs before writing code,
plus a CLAUDE.md containing just `@AGENTS.md`. Finally save my production URL, host, deploy
branch, and repo to a notes file. Give me exact clicks and wait for me at each step.
The trap: building the whole site before deploying once (then you're debugging code and pipeline at once), or trusting the model's memory of a fast-moving framework instead of pinning it to the installed docs.
→ Media, size limits, encoding commands, verifying production: references/PLAYBOOK.md.
Phase 2 — Codify your design language
Goal: a written, machine-readable design system — color, type, spacing, motion, voice — that both the person and Claude read every session, so every new page stays on-brand instead of drifting into five slightly different looks.
Do this after you have one page you actually like, not before. You extract the system from something good; you don't invent it in a vacuum.
Moves
- Name the mood in words first, then derive every rule from it. Two short phrases; if two moods are in tension, that tension becomes a rule. (One real build's phrases were "warm editorial calm + playful pixel craft" — but a "quiet and expensive" or "loud and brutalist" site would name its own and derive very different rules.)
- Use color deliberately and consistently. A restrained palette — often a single accent — keeps hierarchy legible and is the safe default. But if the taste is maximalist, retro, or brutalist, a multi-color system is a legitimate choice. The rule isn't "exactly one accent"; it's that every color has a defined role and gets used the same way everywhere.
- Color as role-named tokens, not hexes sprinkled in markup. Express soft text and borders as one ink color at reduced opacity, rather than inventing five near-identical greys.
- Pair type by role, not by face (body/UI, headings/"voice", mono, display). Reference the role so the actual font can change later without a rewrite.
- Fix a spacing rhythm and a z-index ladder, and write "don't invent new values."
- State a motion philosophy that fits the mood: cheap ambient loops in CSS, interactive
feedback in a JS lib; gate non-essential motion behind
prefers-reduced-motion. - Set an accessible baseline (it's part of quality, not an add-on): body text contrast ≥ 4.5:1, real heading order, visible focus states, semantic landmarks, alt text on meaningful images. A bold/dark palette is exactly where contrast quietly fails.
- Write voice & tone down as design — copy is part of the look (sentence case? playful? plain words? no corporate filler?).
- Codify it in two committed files: a prose
DESIGN_SYSTEM.md(principles + component recipes + a build checklist) and atokensfile (the raw values). Mark it going-forward only — extracted from existing pages, not a migration target — so Claude doesn't "helpfully" refactor working code. - Wire it into context: reference both files from
CLAUDE.md/AGENTS.md(and a memory note) so they load every session. A design system Claude never reads does nothing. - (Advanced) Add a per-surface reskin mechanism — a
data-themeattribute that remaps shared utility classes to a scoped token family — so sub-sections feel distinct on one skeleton.
Prompt to hand Claude
I like how [page] looks now. Extract a design system from it into DESIGN_SYSTEM.md plus a
tokens file. First help me name the mood in 2–3 words, then derive everything from it:
principles; color used deliberately with defined roles (a restrained/one-accent palette is the
safe default, but if my taste is maximalist/brutalist keep it multi-color and consistent);
color as role-named tokens with soft text as one ink at reduced opacity; type by ROLE not face;
a spacing rhythm + z-index ladder with "don't invent new values"; a motion philosophy that
respects prefers-reduced-motion; an accessible baseline (contrast, focus, headings, alt text);
voice & tone; and copy-paste component recipes. Mark it going-forward-only — document what's
there, don't retrofit. Then reference both files from CLAUDE.md so you load them every session.
The trap: over-abstracting before you have anything you like (arbitrary rules you'll fight), inconsistent color (every page a new palette), or writing the doc but never wiring it into Claude's context so it freelances anyway.
→ A fill-in-the-blank design-system + tokens template: references/DESIGN-SYSTEM-TEMPLATE.md.
Phase 3 — Fill it in: content, template, copy, and being findable
Goal: structure the site so adding the next project / post / page is cheap, write the actual words, and make sure the site is reachable and shareable — not just pretty.
Moves
- Map the information architecture first. What pages exist, and what's the hero of each? A common shape: Home (teaser) → Work/Projects list → per-item detail pages → About → Contact. Sketch it before building.
- Model the repeatable content type (a "project" or "post": title, year, summary, cover, body). Define it once, build one strong template, then clone + theme per entry rather than hand-crafting each page. Reuse the chrome — one nav, one footer, one image-placeholder (a nice dashed "image goes here" box beats broken images while assets are gathered).
- Write the actual copy. The words are usually the hardest, most personal part. Have Claude draft the hero line, the about paragraph, and each project summary from the brief, then the person edits to sound like them. Use copy stubs so unfinished sections read as intentional.
- Give visitors one real way to reach you. A
mailto:link or a tiny form (reuse the zero-infra relay from Phase 6). A portfolio whose job is "hire me" must not ship unreachable. - Make it findable and shareable. Per-page
<title>+ meta description, an Open Graph / social share image (so a pasted link doesn't look broken in Slack/iMessage), and a favicon. Cheap, high-visibility, and easy to forget.
Prompt to hand Claude
Help me outline the pages my [portfolio/blog] needs and the hero of each. Then define a
reusable content type for a [project/post] and build ONE strong detail template I can
duplicate, with shared nav/footer and a dynamic route for the list, plus a nice
image-placeholder for missing media. Draft the hero line, about paragraph, and project
summaries from my BRIEF.md so I can edit them. Add a contact method (mailto or a small form),
and give every page a title + meta description + an Open Graph share image, plus a favicon.
The trap: hand-crafting every page (the 2nd and 3rd project should be near-free clones); or shipping a beautiful site with no contact link, no share image, and placeholder copy.
→ Content-model patterns, SEO/meta specifics, reusable components: references/PLAYBOOK.md.
Phase 4 — The iteration loop (the engine)
Goal: a fast, tight rhythm — change → verify → look → commit — that runs under every other phase. This is how the work actually happens.
Moves
- Keep a dev server + browser preview running the whole time. After each change, confirm it's still live (HTTP 200) and look at it — on a phone width too, not just desktop (most portfolio traffic is mobile). The 200 check proves liveness, not correctness; your eyes and a mobile check are the real QA.
- Iterate in small taste nudges. "8px tighter." "warmer background." "straighten this card on hover." One coherent change at a time.
- Commit each nudge with a plain-English message; push often (it auto-deploys). Small commits mean easy undo and a legible history.
- Branch + PR for bigger additions so main stays shippable.
- The person's job is to look and react. No vocabulary needed — "feels off", "too much", "more like that other site" is enough. Claude proposes specifics; they approve or nudge again.
Prompts to hand Claude
Start the dev server and keep it running. After every change, confirm the route returns 200
and show me a screenshot at BOTH desktop and phone width before moving on. One change at a
time, then stop so I can look.
This section feels cramped — more breathing room around the heading — show me before/after.
The trap: big, unreviewed changes. If Claude rewrites five components before the person looks and it's wrong, you can't tell which part is wrong. Keep steps small and visible.
→ The verify routine, mobile checks, commit conventions: references/PLAYBOOK.md.
Phase 5 — Add one signature interaction (optional delight)
Goal: one moment where the site stops feeling like a template and feels like this person made it. Entirely optional — a clean, calm site is already complete.
Framework note: the persistence details below (a
mountedflag, "hydration") apply only if the stack server-renders (Next, SvelteKit). On a static or plain-HTML site there's no hydration step — just read saved state on load. If any term here is unfamiliar, that's fine: describe the effect you want and let Claude pick the technique.
Moves
- Ship the calm version first. Delight goes on top of a finished, on-brand site.
- Pick exactly ONE (maybe two), usually on the hero. Ask: what small thing could a visitor do here that says something about this person? (It doesn't have to be whimsical — for a "quiet and expensive" brand, delight might be one restrained, buttery hover transition.)
- Deliberately don't animate everything else. Restraint is what makes the one thing read as intentional.
- Make it declarative/reusable where the same flavor recurs (e.g. a
data-*attribute that opts any element into an effect), so adding it elsewhere is one attribute, not new code. - Gate accessibility up front: disable it under
prefers-reduced-motionand on touch devices, so those visitors get the clean static site. Never let core content depend on it. - Persist one meaningful piece of state as the payoff if it fits (a counter that only ever grows, saved locally, migrated not reset) — so a repeat visit feels different.
- Add a small, warm, self-dismissing hint so people discover it.
Prompt to hand Claude
My site is otherwise done and on-brand. Suggest 3 simple signature interactions for my hero
that fit [what my work/personality is about], ranked easiest first — something a visitor can
DO. Then build the one I pick: on-brand using existing tokens, disabled under
prefers-reduced-motion and on touch devices, with a small dismissible hint. Don't touch the
rest of the page. (If you hit anything technical, just handle it — I don't need the details.)
For a beginner who wants the 20-minute version: a pure-CSS hover flourish on the hero (a gentle tilt or glow), no JS, off under reduced-motion.
The trap: animating everything (nothing feels special and reading suffers), or making the interaction load-bearing so the site breaks when it's disabled.
→ Persistence lifecycle, a11y gates, the reusable-effect pattern: references/PLAYBOOK.md.
Phase 6 — Ship, listen, and feed it back
Goal: turn "is this any good?" into concrete, located to-dos for the next iteration — using real people, not guesses.
Moves
- Share the live URL early and often. (You've had one since Phase 1.)
- Add lightweight analytics — one privacy-friendly script (e.g. Plausible, Fathom, PostHog, or Microsoft Clarity; pick per your privacy stance), loaded after the page is interactive so it doesn't slow first paint — so you learn what visitors actually do without asking.
- Post a short privacy note if you add analytics or session recording (what you collect, that you don't sell it; a minimal cookie/consent notice where EU/UK/California visitors are likely, and mask sensitive fields in any recordings). "Privacy-friendly" is a setting, not a guarantee.
- Add an active feedback channel when it's worth it: a "comment mode" where a visitor clicks any element and leaves a note right where they see the issue. Anchor each note to a stable page element + a fractional position (not raw pixels) so it replays at any screen size.
- Keep it zero-infra. Hold notes in the browser and relay them to your inbox through a small backend endpoint Claude writes and the host runs for you (a serverless function) using any no-account form/email relay (FormSubmit, Formspree, Web3Forms) — no database, no accounts, your address kept server-side. Most relays send one activation email on the first submission — you must click its link once or notes silently never arrive. Test the whole path after deploy.
- Do a quick quality pass before calling it done: run Lighthouse (or the host's built-in report), confirm images have sizes set (so layout doesn't jump), and re-check mobile.
- Feed feedback straight back into Claude. Paste the digest in as the next iteration's to-do list — each note is already a located edit. This handoff is the whole point; feedback that never re-enters the build loop is wasted.
Prompt to hand Claude
Add a privacy-friendly analytics script (your pick of Plausible / Fathom / PostHog / Clarity)
to my site, loaded after the page is interactive, and add a short privacy note page. [When
ready:] build a lightweight "comment mode" so visitors can click any element and leave a note;
anchor each note to a stable element + fractional position (not pixels); store notes in the
browser; and add a small backend endpoint that emails them to me via a no-account relay
(FormSubmit/Formspree) with no database — keep my email server-side, and remind me to click the
relay's one-time activation email. Then run a Lighthouse pass and fix the top issues.
And to close the loop:
Here's the feedback digest from my live site: [paste]. Turn each note into a concrete to-do
grouped by page, then fix them one at a time, showing me each change.
The trap: over-engineering the backend (a DB + accounts + dashboard to maintain), skipping the privacy note, or collecting feedback and never pasting it back to Claude.
→ DOM-anchoring, the relay + replay pattern, privacy details: references/PLAYBOOK.md.
Operating Claude Code well (runs through everything)
- Put durable rules in
CLAUDE.md/AGENTS.md: conventions, "read X before writing", "don't retrofit existing pages", the design-system pointer. These load every session. - Let Claude keep memory of decisions so it doesn't relitigate them — "the design system is going-forward-only", "never reset the visitor counter", "production is at this URL". Just say "remember that …".
- Curate an allowlist of safe, repeated commands (dev-server health checks, git, build) so you're not approving the same thing 50 times.
- When something breaks, that's normal — screenshot the error or paste the terminal output to Claude and let it diagnose. A red error is a prompt, not a dead end.
- Use the browser preview to verify visually, and plan mode before big changes so you approve the approach before code is written.
- Direct with specifics. "Make the hover use the accent color and settle over 300ms" lands better than "make it nicer". When something's wrong, say what feels wrong.
→ Example CLAUDE.md rules and memory entries: references/PLAYBOOK.md.
Build checklist
- Framed: the vibe is named in words/images and the pages are listed (
BRIEF.md). - Live: an empty shell is deployed to a real URL with auto-deploy on push.
- Guardrailed:
AGENTS.mdpoints Claude at the installed docs; secrets are gitignored; deploy facts are written down. - On-system:
DESIGN_SYSTEM.md+ tokens exist, color is deliberate and role-named, referenced fromCLAUDE.md; accessible baseline met (contrast, focus, alt text, headings). - Filled in: one reusable template (new entries are clones); real copy, not lorem; a working contact method; per-page title + meta + Open Graph image + favicon.
- Looping: dev server always on; changes verified (200 + eyes, desktop and mobile) and committed small.
- (Optional) alive: one signature interaction, gated for reduced-motion + touch.
- Listening: analytics + a privacy note; a way to collect feedback; a Lighthouse pass; feedback fed back to Claude.
Reference files
Read these when a phase gets real — they hold the depth the spine above leaves out:
| File | Read it when… |
|---|---|
references/PLAYBOOK.md | You want the full per-phase depth: pitfalls, the verify + mobile routine, media/encoding, SEO/meta, a11y and persistence details, example CLAUDE.md rules. |
references/DESIGN-SYSTEM-TEMPLATE.md | You're on Phase 2 and want a fill-in-the-blank DESIGN_SYSTEM.md + tokens to adapt to any taste. |
references/PROMPTS.md | You want the full copy-paste prompt library, grouped by phase, with variations. |