
Building your first simple web page
Project scaffold, dev server, iterate-by-screenshot — end-to-end.
What we’re building
One page. Hero, three feature cards, CTA, footer. Locally served by a dev server. Deployable to Vercel or Netlify with two clicks. Total time: 60-90 minutes if it’s your first time, 20 minutes after the second.
The point isn’t the page. The point is the loop — how you brief, scaffold, iterate, and ship a real artifact with an agent. The same loop scales to multi-page sites, dashboards, internal tools, and product UIs. The only thing that changes is the size of the brief and the count of screenshots.
If you’ve never run a dev server, never edited a JSX file, never deployed anything — this lesson is the right starting point. The agent does the heavy lifting; you do the looking.
The scaffold + dev server, in one paragraph
Modern web frameworks ship a one-line scaffold command that creates a working project with a default homepage. For Next.js, it’s npm create next-app@latest with a few flags. The agent runs the command, you confirm the dev server is running by visiting http://localhost:3000, and from that point on every edit shows up in your browser the moment you save the file.
The dev server is the iteration medium. Edit a file, save, the browser reloads with the new state. This is what lets the screenshot loop work — the gap between “agent edited” and “you see the result” is one keystroke and one second. Without that loop, agent-built UI is guesswork.
- Default scaffold flags: TypeScript on, Tailwind on, App Router on, ESLint off (we’ll add it later if needed)
- Dev server command:
npm run devfrom the project folder - What to look for: “Ready in X.Xs” in the terminal, default welcome page at localhost:3000
Three ways the first build fails
The patterns that turn a 30-minute build into a three-hour fight. Hover any card to see the diagnosis.
The scaffold drift
The blind iteration
The phantom feature
The fix in all three: locked stack, screenshot loop, explicit definition of done. Without these, the agent improvises in the dark and the build drifts. With them, the build converges in 5-10 short loops.
The screenshot loop
The diagnostic is one prompt — pasted at the start of the build session. After scaffold, every revision happens through this loop until the page matches the brief.
We're going to iterate on this page by screenshot.
Each turn:
1. I make changes (or you propose them)
2. I refresh the dev server
3. I paste a screenshot of the current state
4. You tell me, in one short paragraph:
- What you see vs what you expected
- The specific element that's wrong (if any)
- The smallest edit that would fix it
Don't propose multi-file refactors mid-loop. One issue,
one edit, screenshot, next. We're done when the screenshot
matches the brief.The single move that prevents "agent edits in the dark" — agent sees actual output, not its own intent.
Most operators try to describe visual issues in words. Don’t. Words for visual issues are slow and lossy. Screenshots are precise. The agent reads the screenshot, identifies the specific element that’s wrong, proposes the smallest possible edit. Three loops gets you to a publishable page; ten loops gets you to a polished one.
Annotated transcript
A real conversation: operator scaffolds a Next.js landing page, hits a grid layout bug, fixes it via screenshot loop. Click any pinned annotation to expand the “why this turn matters” commentary.
Three operator turns, three agent turns. Result: working dev server, structure shipped, one layout bug found and fixed via screenshot.
- operator
I want to build a simple landing page for my new tool. One page, hero section, three feature cards, a CTA, a footer. I've never built a Next.js app before.
- agent
Two pins before we scaffold:
1. Stack lock — I'll use Next.js 16, TypeScript strict, Tailwind v4, no other dependencies unless you approve. I'll add this constraint to your CLAUDE.md so every future session inherits it.
2. Definition of done — "landing page" means: hero with headline + subhead + primary CTA, three feature cards in a grid, footer with links, mobile-responsive at 720px, deploys cleanly to Vercel or Netlify. Confirm or correct.After the pins I'll scaffold, start the dev server, and we'll iterate by screenshot.
- operator
Confirmed on both. Go.
- agent
Scaffolding now.
npm create next-app@latest my-landing -- --ts --tailwind --app --no-eslint --no-src-dir --turbopack cd my-landing npm run devDev server is running at http://localhost:3000. You should see the default Next.js welcome page. Take a screenshot and paste it back — I want to confirm what you're seeing matches what I expect before I edit anything.
- operator
[pastes screenshot of default Next.js welcome page]
- agent
Scaffold confirmed. Now I'll replace
app/page.tsxwith the landing page.First pass — I'll write the structure (hero, three cards, footer) with placeholder copy. After you screenshot, we'll iterate on copy and styling separately. Splitting structure from style is the fastest loop.
[delivers ~80 lines of TSX with hero, feature grid, footer; uses Tailwind utility classes for layout]
Save and refresh. Screenshot back when you have it.
- operator
[screenshot — page renders, layout works, but feature cards are stacked vertically on desktop instead of in a grid]
- agent
I see it — the cards container needs
md:grid-cols-3but I wrotegrid-cols-3which only kicks in if the parent is a grid. The cards are using flex-column instead.One-line fix in
app/page.tsx:- <div className="flex flex-col gap-6"> + <div className="grid gap-6 md:grid-cols-3">Refresh and screenshot. If it's right, we move to copy.
Build brief template — copy and paste
Save in a snippets file. Paste before any web-build session. Customize the goal and the definition-of-done; the stack lock and screenshot-loop sections are reusable.
Build brief: <one-line description of what we're building>
GOAL
----
<2-3 sentences: who this is for, what it does,
where it lives>
STACK (locked)
--------------
- Next.js 16 (App Router, Turbopack)
- TypeScript strict
- Tailwind v4
- No other dependencies without my approval
DEFINITION OF DONE
------------------
- <visible element 1: e.g. "hero with headline + subhead + CTA">
- <visible element 2>
- <visible element 3>
- <interactive: e.g. "form validates 3 fields, submits, shows success">
- <responsive: e.g. "mobile-friendly at 720px breakpoint">
- <deploy: e.g. "deploys cleanly to Netlify, no console errors">
PROCESS
-------
- You scaffold + start dev server
- I confirm with screenshot before any edits
- Iterate structure-first, style-second
- One issue per screenshot loop
- Walk the definition-of-done before declaring shipped
The definition of done is the most-skipped section and the one that matters most for first builds. Without it, “done” is whatever the agent renders and you eyeball-approve. With it, “done” is checkable.
Prompt kit
Three prompts for scaffolding, locking the stack, and defining done. Save in your CLAUDE.md or a personal snippets file.
We're going to iterate on this page by screenshot.
Each turn:
1. I make changes (or you propose them)
2. I refresh the dev server
3. I paste a screenshot of the current state
4. You tell me, in one short paragraph:
- What you see vs what you expected
- The specific element that's wrong (if any)
- The smallest edit that would fix it
Don't propose multi-file refactors mid-loop. One issue,
one edit, screenshot, next. We're done when the screenshot
matches the brief.Add this section to my CLAUDE.md so every session
inherits the same stack constraints:
## Stack (locked)
- Framework: Next.js 16 (App Router, Turbopack)
- Language: TypeScript strict
- Styling: Tailwind v4
- No other dependencies without explicit approval
- No framework upgrades or migrations without explicit approval
- No "best practice" rewrites of working code
If you think a new dependency or framework change is
warranted, surface it as a question. Don't add it
unilaterally.Before writing any code for <feature>, draft the
definition of done as a 5-7 item checklist:
- Visible behavior (what the user sees)
- Interactive behavior (what the user can do)
- Validation / error states
- API or data dependencies
- Mobile / responsive behavior
- Accessibility minimum (keyboard, alt text)
- Deploy condition (lints, type-checks, builds)
Show me the checklist. I confirm or correct. Only then
do you write code. After delivery, we walk through the
checklist together — you mark each item done or surfaced.Apply this — your first real page
60-90 minute exercise. One page. Locked stack. Screenshot loop. Walk the checklist.
Your first agent-built page
Each step takes 10-20 minutes. Progress saves automatically.
- 01Pick the simplest real page you'd actually use. Personal landing, project page, link-in-bio. One page.Don't pick the dream project. Pick the page you'd link from your email signature next week.
- 02Lock the stack in your CLAUDE.md before scaffolding.Use the second prompt in the kit. Five minutes now saves an hour of framework drift later.
- 03Have the agent scaffold and start the dev server. Screenshot the default page back before any edit.This catches scaffold failures early. If the dev server isn't running, fix that before you touch any file.
- 04Iterate structure-first, style-second. One issue per screenshot loop.Don't ask for "make it look better." Ask for "the cards should be 3-across on desktop." Specific issues, surgical edits.
- 05Walk the definition-of-done checklist before declaring shipped.If any item was skipped, the agent surfaces it. You decide whether to ship anyway or close the gap.