What you'll build
A real web app β a page you can open in any browser β built with Next.js, without writing the code by hand. You'll describe what you want in plain English and let Claude Code do the typing. This part takes you from nothing to the app running on your own machine. Putting it online comes next, in Part 2.
Install a few tools β describe your app to Claude Code β preview it locally β iterate. That's this whole part. Deploy is Part 2.
The tools you'll meet
Claude Code
An AI coding assistant in your terminal. You talk; it writes and edits files.
Next.js
The framework your app is built with. Claude Code sets it up for you.
Node.js
The engine that runs your app while you build. You install it once.
Git & GitHub
Where your code lives. You'll need it when you deploy in Part 2.
Before you start
- A Claude account at claude.ai (Pro or Max includes Claude Code).
- A GitHub account at github.com β for later.
Install Node.js
Install the LTS build from nodejs.org, then check it in your terminal (Mac: β+Space β "Terminal"; Windows: PowerShell):
node --version # should print v22.x.x or similar
Step 2
Install Claude Code
npm install -g @anthropic-ai/claude-code
mkdir my-first-app && cd my-first-app
claude # follow the login link the first time
The terminal isn't scary. It's a text box for commands β and Claude Code can run most of them for you when you ask.
Ask Claude Code to build your app
Describe the purpose and the vibe; let it make the technical choices:
> Create a new Next.js app in this folder using TypeScript and the
App Router. Build a one-page personal site with a hero, an "about"
section, a list of projects as cards, and a contact footer. Clean
dark theme, blue accent. Then start the dev server so I can see it.
It creates the files, installs what it needs, and asks before running commands β say yes.
What Claude Code actually runs
Behind that one request, it runs the same commands a developer would type by hand β and asks before each:
npx create-next-app@latest . --typescript --app # scaffold the Next.js project here
npm install # download the libraries it needs
npm run dev # start the dev server
# β Local: http://localhost:3000
You don't have to remember any of these β Claude Code picks and runs them. Seeing them helps you follow along, and recognize them when it asks for permission.
Step 4Run it locally β and stop here
npm run dev
# β Local: http://localhost:3000
Open http://localhost:3000. Leave it running β
the page refreshes on every edit. Keep asking for changes until you like it.
This is the finish line for Part 1: a working app on your
machine. You don't need to deploy anything yet.
What all these files are: the Next.js layout
my-first-app/
ββ app/ # your pages live here
β ββ layout.tsx # shared shell around every page
β ββ page.tsx # the homepage β "/"
β ββ globals.css # site-wide styles
β ββ about/
β ββ page.tsx # the about page β "/about"
ββ public/ # images & static files, served as-is
ββ package.json # dependencies + dev/build scripts
ββ node_modules/ # installed libraries (never edit)
- Folders in
app/become URLs. A folder with apage.tsxis a page. layout.tsxis the frame β nav, footer, fonts on every page.public/is for assets β droplogo.pngthere, use it at/logo.png.
Don't memorize it. Ask Claude Code "give me a tour of my project."
npm, yarn, pnpm β what are these?
You keep typing npm. It's a package
manager β it downloads the open-source libraries your app depends on
(into node_modules/) and runs your project's
scripts. There are three common ones; they do the same job, just faster or
tidier:
| Tool | What it is | Install a package | Run a script |
|---|---|---|---|
npm | Ships with Node.js β the default, always there. | npm install x | npm run dev |
yarn | An early faster alternative; still widely used. | yarn add x | yarn dev |
pnpm | Fastest, saves disk space (shared package store). | pnpm add x | pnpm dev |
Which should you use? As a beginner, stick with npm β it's built in and every tutorial assumes it. Pick one per project and don't mix them (each writes its own lock file β package-lock.json, yarn.lock, or pnpm-lock.yaml β that pins exact versions so everyone gets the same install).
What's in package.json?
package.json is your project's ID card β the one
file that says what your app is called, what it depends on, and what commands
it can run. Every package manager reads it:
// package.json
{
"name": "my-first-app",
"scripts": { // the commands you can run
"dev": "next dev", // npm run dev β start locally
"build": "next build", // npm run build β production build
"start": "next start",
"lint": "eslint"
},
"dependencies": { // libraries your app needs to run
"next": "^15.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": { // tools needed only while developing
"typescript": "^5",
"eslint": "^9"
}
}
- scripts β shortcuts you run with
npm run <name>(that's wherenpm run devcomes from). - dependencies β packages shipped with your app; devDependencies β tools only used while building (linters, types).
- The
^means "compatible newer versions are OK"; the lock file records the exact versions actually installed.
You rarely edit it by hand. npm install some-lib adds the dependency for you β or just ask Claude Code, "add and set up <library>."
Make it look designed, not default
Claude Code has Skills for design β ask for them by name so your app doesn't look templated:
frontend-design
Distinctive typography, spacing, and visual identity.
shadcn
Ready-made, accessible UI components that already look sharp.
> Use your frontend-design skill to give this a stronger visual
identity β deliberate type, generous spacing, one accent color.
Avoid a generic "AI landing page" look.
Start from a template β especially for dashboards
You don't have to build the layout from scratch. A template is a ready-made skin β the sidebar, top bar, cards, tables, and charts already arranged β so you just drop in your content and data. Dashboards are mostly the same furniture every time, which is exactly where a template saves the most work.
And yes β there are gallery pages you browse exactly like PrimeVue's templates showcase: preview a design, then clone it and start editing. The best for a Next.js + React app:
shadcn/ui blocks β
A gallery of copy-in "blocks" β including full dashboard layouts (sidebar, cards, data tables).
Tremor β
React components built for dashboards: KPI cards, charts, and tables, consistent out of the box.
Vercel Templates β
Clone a whole admin/SaaS starter β many are one-click deploy β and start editing.
Coming from PrimeVue? Its React sibling PrimeReact has the same templates gallery, and it works in Next.js too. Other free galleries worth a browse: Flowbite, Preline, and MUI templates.
Tell Claude Code to build on one instead of starting from a blank page. Notice how much of the thinking happens in the prompt β every line below closes off a decision you'd otherwise have to undo later:
> Goal: turn this into a dashboard.
Shell: a left sidebar for navigation, a top bar with the page
title, and a main content area β plain Tailwind, no second UI
library.
Data parts with Tremor: four stat cards across the top, a line
chart of events over time, and a recent-activity table below it.
Style: take every color, spacing value and radius from the @theme
block in app/globals.css. Don't invent new ones.
Data: seed realistic event-log rows β timestamp, source, level,
message β so the chart and table have something to show. I'll
wire the real API in Part 5.
Constraints: put the shell in one <DashboardLayout> component so
every page can reuse it, and make it work down to phone width.
Build the dashboard page only. Show me it before going further.
Once you like it, roll it out β and keep the agent on a short leash while it touches pages that already work:
> Now move the existing pages onto it: wrap each one in
<DashboardLayout>, swap any hand-rolled cards for Tremor's Card,
and delete the CSS that's now unused. One page at a time β show
me each before you start the next.
Why start from a skin: the fiddly part of a dashboard is the responsive layout and consistent spacing. Let a template own that, and spend your time on the content and data that make it yours. Ask Claude Code "what dashboard templates fit this?" and it'll pick one and wire it up.
Every one of those galleries is built on the same two things, and they do completely different jobs. A few minutes here saves a lot of confusion later β especially because you are already using one of them.
Tailwind CSS β how the styling gets written
The traditional way to style a page is two files: you invent a class name in your
HTML, then write the rules for it in a stylesheet. Tailwind deletes
the invention step. It gives you hundreds of tiny single-purpose classes β
flex, p-6,
rounded-xl β and you compose the design directly on the
element:
// The traditional way β two files, and a name you had to think up
<div class="price-card"> β¦ </div>
// styles.css
.price-card {
display: flex;
gap: 0.75rem;
padding: 1.5rem;
border-radius: 0.75rem;
background: #1a2236;
}
// Tailwind β the same card, one file, nothing to name
<div class="flex gap-3 p-6 rounded-xl bg-slate-800"> β¦ </div>
It looks noisy the first time you see it, and that reaction is normal. What you get back is worth the noise: the styling is where the element is. To change how something looks you edit that line β you never go hunting through a stylesheet wondering which rule is winning, and deleting a component deletes its CSS with it.
This is why it pairs so well with Claude Code. "Make the cards tighter and give them a border" is a single-line edit in a single file. With hand-written CSS the agent has to find the right rule, check nothing else depends on it, and guess at specificity β that's where styling changes go wrong.
You already have it. create-next-app sets up TypeScript, Tailwind, ESLint, the App Router and Turbopack by default β so those classes in the code Claude Code just wrote for you are Tailwind. Nothing to install.
There is no tailwind.config.js any more. Tailwind v4 moved configuration into your CSS: @import "tailwindcss"; in app/globals.css, and your own colors and fonts in a @theme block. Older tutorials will confidently tell you to edit a config file that your project doesn't have.
Tremor β the dashboard parts Tailwind doesn't give you
Tailwind styles things. It does not give you things β there is no
chart class, because a chart is not a style, it's a
component. Tremor is a set of React components built for dashboards:
KPI cards, charts, and data tables. Because it's built on Tailwind, it
inherits the same spacing and color scale as the rest of your app instead of looking
bolted on.
import { Card, LineChart } from '@tremor/react';
<Card>
<LineChart data={revenue} index="month" categories={['eur']} />
</Card>
// ~4 lines for a chart that is responsive, themed, and has tooltips
How the pieces stack
Every gallery above sits somewhere on this ladder:
your app app/page.tsx β your content and your data
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
components shadcn/ui β buttons, dialogs, tables, forms
(pick one) Tremor β KPI cards, charts, dashboard tables
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Tailwind CSS the utility classes both are built out of
Pick one component library and stay there. shadcn/ui and Tremor overlap β both have cards and tables. Installing three libraries gets you three design systems arguing with each other in the same page. Choose by what you're building: a dashboard leans Tremor, a general app leans shadcn/ui.
A good way to learn Tailwind is to make the agent teach you from your own code:
> Explain the Tailwind classes on this component line by line in
plain English. Then pull the repeated ones into a reusable
<StatCard> component so I'm not copying the same 12 classes.
How to prompt for web development
Good prompts answer four things β goal, context, style, constraints:
> Build a homepage for a coffee roaster called "Ember". Sections:
hero with tagline, short "our story", three product cards with
price, footer with address + Instagram. Warm palette (browns,
cream), rounded corners. Must look great on a phone.
- Show, don't just tell: "make it feel like stripe.com β clean, lots of air."
- Describe problems, not CSS: "the text is too close to the edge on mobile."
- One change at a time, and ask for options when exploring.
Give the project a CLAUDE.md
Drop a CLAUDE.md at the repo root so Claude Code
knows your conventions every session (/init
scaffolds one for you):
# CLAUDE.md
## What this is
Personal / marketing site. Next.js (App Router) + TypeScript. No backend yet.
## Commands
- Dev / Build / Lint: npm run dev / build / lint (dev on :3000)
## Structure
- app/ routes (folder + page.tsx = a URL)
- app/layout.tsx shared shell (nav, fonts)
- public/ static assets, served at /
- components/ reusable UI
## Conventions
- Dark theme, blue accent. Reuse tokens in app/globals.css β don't hardcode colors.
- One component per file; keep them small.
## Verify
Run the dev server; check the changed page on desktop + mobile.
β¦and a DESIGN.md for the look
CLAUDE.md tells the agent how you build.
DESIGN.md
tells it how you look β a single file at the repo root holding your colors,
type scale, spacing and component rules, in a format agents read natively. It solves
the problem you hit around page four: the new page is fine on its own, but it doesn't
match the three you already have.
It's an open format from Google Labs β text, Git-versionable, readable by Claude Code, Cursor or Copilot alike. And you don't have to write one from scratch: getdesign.md is a catalog of a few hundred DESIGN.md files reverse-engineered from real products, so you can start from a visual language that already works.
Steps to implement it
- Pick a starting point. Browse the catalog at getdesign.md/design-md and grab the analysis whose feel is closest to what you're after β or skip the catalog and have Claude Code write one from your existing pages (step 3).
-
Save it as
DESIGN.mdat the repo root, next toCLAUDE.md. YAML front matter carries the tokens an agent can act on; the prose below explains the intent:--- name: Ember colors: primary: "#1A1C1E" tertiary: "#B8422E" neutral: "#F7F5F2" typography: h1: { fontFamily: Public Sans, fontSize: 3rem } body-md: { fontFamily: Public Sans, fontSize: 1rem } rounded: { sm: 4px } spacing: { sm: 8px } --- ## Overview β the sections the spec expects, in this order ## Colors ## Typography ## Layout ## Elevation & Depth ## Shapes ## Components ## Do's and Don'ts -
Point Claude Code at it β once, in plain English:
That last sentence is the important one: it makes the design brief stick across sessions instead of being a one-off instruction.> Read DESIGN.md and restyle the homepage to match it exactly β its colors, type scale, spacing and radii. Don't invent values that aren't in the file. Then add a line to CLAUDE.md telling future sessions to follow DESIGN.md for anything visual. -
Check it's valid. The official linter catches broken token
references and flags contrast that fails accessibility checks:
$ npx @google/design.md lint DESIGN.md -
Turn the tokens into Tailwind. This is where it meets the
section above β export your tokens and paste them into the
@themeblock inapp/globals.css, and your DESIGN.md colors become real utility classes:$ npx @google/design.md export --format json-tailwind DESIGN.md -
Commit it. Like
CLAUDE.md, its whole value is being in the repo β every future session, and every teammate's agent, inherits the same visual language for free.
No catalog, no problem. Ask Claude Code to work backwards from what you've already built: "Read my components and app/globals.css, then write a DESIGN.md that documents the design system I actually have." You get an honest brief instead of an aspirational one β and it'll surface the inconsistencies you'd drifted into.
Two caveats. The spec is young β Google Labs published it as a draft in April 2026, so expect the format to move. And a catalog entry is a starting point, not a brand: shipping a pixel-accurate copy of Stripe's design system gives you Stripe's identity, not your own. Take the structure, then change the colors and type until it's yours.
Let Claude Code see your app in the browser
Up to now you've been the messenger: you look at
localhost:3000, spot something wrong, describe it, and
copy the console error back into the terminal. The
Chrome integration
removes that round trip. Claude Code drives a real Chrome window β it opens your app,
clicks through it, reads the console, and then fixes the code that caused the error,
in one go.
Two pieces have to meet: the Claude in Chrome extension in your
browser, and Claude Code started with the --chrome flag.
- Install the extension β Claude in Chrome from the Chrome Web Store (v1.0.36 or newer).
-
Start Claude Code with the browser attached. The first launch shows
a one-time dialog explaining how site permissions work:
$ claude --chrome -
Ask it to go and look. Leave
npm run devrunning in its own terminal first:
The first browser action asks permission to use the> Open localhost:3000, click through every link in the nav, and tell me if anything 404s or throws a console error.claude-in-chromeskill β approve it and a new tab opens. -
Use
/chromewhen something's off. It shows the connection status β you want Status: Enabled and Extension: Installed β and lets you manage site permissions or reconnect if the extension goes idle during a long session.
This is where the last two sections pay off. Once it can see the page, "does it match?" becomes a question it can answer itself: "Open localhost:3000, compare it against DESIGN.md, and list every place the spacing or color doesn't match the tokens." Same for responsiveness β "check it at phone width and tell me what breaks."
What you need: Chrome or Edge (other Chromium browsers like Brave and Arc work too), a direct Anthropic plan β Pro, Max, Team or Enterprise β and to be signed in with /login. An API key won't work; the extension can't authenticate with one. Not supported inside WSL.
It's your real browser, with your real logins. That's what makes it useful and what makes it worth a moment's thought: the agent can act on any site you're signed into. Keep the extension's site permissions to the sites you actually want it touching, and treat a page's content as untrusted input β text on a web page can try to instruct the agent. For a beginner building on localhost, none of this bites; it matters the day you point it at the open web.
Tired of the flag? Run /chrome and pick Enabled by default. The trade-off is that browser tools are then always loaded, which uses more of your context window β so if sessions start feeling short, turn it back off and use --chrome only when you need it.
Tips for working with Claude Code
- Work in small steps β one change, look, next.
- Commit often β ask Claude Code to save progress to git; it's your undo.
- Give it the error β paste error messages; fixing them is what it's best at.
- Ask it to explain β "what does this file do?" is how you learn while building.
Next up β Part 2: Platforms: Vercel, Supabase & the AWS Alternatives β get it online. Then Part 3 decides how many repos you keep and how each one deploys, and Part 4 lays the AWS base layer underneath. (Want to level up how you drive Claude Code? That's the capstone, Part 13.)