Back to docs
03Week 1

Next.js Scaffolding

From zero to a running React application in minutes

Creating a New Project

Run this command in your terminal to create a new Next.js project:

npx create-next-app@latest my-portfolio

You’ll be asked a series of questions. Here are the recommended answers:

✔ Would you like to use TypeScript? → Yes
✔ Would you like to use ESLint? → Yes
✔ Would you like to use Tailwind CSS? → Yes
✔ Would you like to use `src/` directory? → No
✔ Would you like to use App Router? → Yes
✔ Would you like to customize the default import alias? → No

Tip: Always say Yes to TypeScript and Tailwind. TypeScript catches errors before they happen. Tailwind lets you style directly in your JSX without switching files. Claude handles both of these for you.

Project Structure — File by File

After creation, your project looks like this:

my-portfolio/
├── app/
│   ├── layout.tsx        ← Root layout (wraps every page)
│   ├── page.tsx           ← Home page (localhost:3000)
│   ├── globals.css        ← Global styles + Tailwind imports
│   └── favicon.ico        ← Browser tab icon
├── public/
│   └── images/            ← Static files (images, fonts, etc.)
├── components/            ← Reusable UI components (you create this)
├── package.json           ← Project config + dependencies
├── tailwind.config.ts     ← Tailwind customization
├── tsconfig.json          ← TypeScript config
├── next.config.js         ← Next.js config
└── node_modules/          ← Installed packages (don't touch)

Routing — Files ARE Routes

In Next.js, the file system is the router. Every page.tsx file inside the app/ directory becomes a URL route automatically.

FileURL
app/page.tsx/
app/about/page.tsx/about
app/projects/page.tsx/projects
app/projects/[slug]/page.tsx/projects/anything
app/blog/page.tsx/blog

Creating a New Page

To create a new page, create a folder inside app/ and add a page.tsx file:

// app/about/page.tsx

export default function AboutPage() {
  return (
    <div className="max-w-2xl mx-auto p-8">
      <h1 className="text-4xl font-bold mb-4">About Me</h1>
      <p className="text-gray-600">
        I'm a designer learning to ship with code.
      </p>
    </div>
  )
}

Save the file and visit http://localhost:3000/about — your new page is live.

The layout.tsx File

The layout.tsx file wraps every page with shared UI — navigation, footer, global styles. It’s like a frame around your pages.

// app/layout.tsx

import "./globals.css"

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>
        <nav className="p-4 border-b">
          <a href="/" className="font-bold">My Portfolio</a>
        </nav>
        {children}
      </body>
    </html>
  )
}

Components — Reusable UI Pieces

Components are functions that return JSX. They live in the components/ folder and can be imported into any page.

// components/Button.tsx

interface ButtonProps {
  label: string
  variant?: "primary" | "ghost"
  onClick?: () => void
}

export function Button({ label, variant = "primary", onClick }: ButtonProps) {
  const styles = variant === "primary"
    ? "bg-gray-900 text-white hover:bg-gray-800"
    : "border border-gray-300 text-gray-700 hover:bg-gray-50"

  return (
    <button
      onClick={onClick}
      className={`px-4 py-2 rounded-lg font-medium transition-colors ${styles}`}
    >
      {label}
    </button>
  )
}

Use it in any page:

// app/page.tsx
import { Button } from "@/components/Button"

export default function HomePage() {
  return (
    <div className="p-8">
      <Button label="Click me" variant="primary" />
      <Button label="Cancel" variant="ghost" />
    </div>
  )
}

Tip: The @/ alias points to your project root. So @/components/Button means /components/Button.tsx from the project root. This is configured automatically by create-next-app.

npm Scripts

These commands are defined in package.json and run common tasks:

CommandWhat It Does
npm run devStart the development server at localhost:3000
npm run buildBuild the project for production deployment
npm startRun the production build locally
npm run lintCheck for code quality issues
npm installInstall all dependencies from package.json

Hot Reload

When you run npm run dev, Next.js watches your files for changes. Every time you save a file, the browser updates automatically — no manual refresh needed. This is called hot reload (or Hot Module Replacement / HMR).

Warning: TypeScript errors can stop hot reload. If your browser stops updating, check the terminal for red error messages. Fix the error, save, and hot reload will resume.

Importing Images and Assets

Put images in the public/ folder. Reference them with a path starting from /:

// Using a standard img tag
<img src="/images/hero.jpg" alt="Hero image" />

// Using Next.js Image component (optimized)
import Image from "next/image"

<Image
  src="/images/hero.jpg"
  alt="Hero image"
  width={800}
  height={400}
  className="rounded-xl"
/>

The Next.js Image component automatically optimizes images for performance — lazy loading, responsive sizing, and modern formats.