Next.js Getting Started

Set up a Next.js project and start building pages and API routes quickly.

TL;DR

  1. 01Create a new Next.js project using create-next-app command.
  2. 02Pages go in the app folder and routes are file-based.
  3. 03Run npm run dev to start the development server.

Tips

  1. 01Start with create-next-app for fastest setup — it includes all necessary configurations and best practices.

Warnings

  1. 01Remember that files in the app folder automatically become routes — organize carefully to avoid unexpected routes.

Installation

  • Create a new Next.js project.
    npx create-next-app@latest my-app
    cd my-app
    npm run dev
  • Answer prompts to configure TypeScript, ESLint, etc.
  • Dev server runs at http://localhost:3000.
  • Use --ts flag to skip prompts and create a TypeScript project.
    npx create-next-app@latest my-app --ts --app --tailwind
  • Install dependencies and start the dev server in one step.
    npm install && npm run dev

Project Structure

  • Pages in app folder become routes automatically.
    my-app/
      app/
        page.tsx        # / route
        about/
          page.tsx      # /about route
        blog/
          [slug]/
            page.tsx    # /blog/:slug route
      public/           # Static files
      package.json
  • Each page.tsx file is a route.
  • Place static assets like images in the public folder.
    public/
      logo.png          # /logo.png
      favicon.ico       # /favicon.ico
  • The layout.tsx at the root wraps every page in the app.
    // app/layout.tsx
    export default function RootLayout({ children }) {
      return <html lang="en"><body>{children}</body></html>;
    }
  • Use the app/api folder to create API route handlers.
    // app/api/health/route.ts
    export async function GET() {
      return Response.json({ status: "ok" });
    }

Creating a Page

  • Create a simple page component.
    // app/page.tsx
    export default function Home() {
      return (
        <main>
          <h1>Welcome to Next.js</h1>
          <p>Get started by editing this page</p>
        </main>
      );
    }
  • Pages are server components by default.
    // app/about/page.tsx
    export default function About() {
      return <h1>About Us</h1>;
    }
  • Fetch data inside a server page using async/await.
    export default async function Blog() {
      const posts = await getPosts();
      return <ul>{posts.map(p => <li key={p.id}>{p.title}</li>)}</ul>;
    }
  • Add metadata to set the page title and description.
    export const metadata = {
      title: "Home",
      description: "Welcome to my Next.js site"
    };
  • Create a client component for interactive pages.
    "use client";
    import { useState } from "react";
    
    export default function Counter() {
      const [count, setCount] = useState(0);
      return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
    }

Building and Deployment

  • Build for production and start the server locally to verify the output.
    npm run build
    npm start
    # Route           Size   First Load JS
    # /               3 kB         87 kB  ← aim for < 130 kB
  • Check the build output table after every build — First Load JS above 130 kB signals bundle bloat.
    npm run build 2>&1 | grep "First Load JS"
    # Flag any route above 130 kB for optimisation
  • Deploy to Vercel in seconds — it auto-detects Next.js and requires no config.
    npm install -g vercel
    vercel  # auto-detected, deployed immediately
  • Set environment variables before the first deployment — .env.local is not deployed.
    vercel env add DATABASE_URL production
    vercel env add NEXT_PUBLIC_API_URL production
  • Set output:standalone in next.config.js when building a Docker image — reduces image size by excluding node_modules.
    // next.config.js
    module.exports = { output: "standalone" };

Essential Add-ons

  • Add Tailwind CSS for utility-first styling — available as a prompt option in create-next-app.
    npm install -D tailwindcss postcss autoprefixer
    npx tailwindcss init -p
  • Use the Link component for client-side navigation — never use plain <a> tags for internal routes.
    import Link from "next/link";
    
    export default function Nav() {
      return <nav><Link href="/about">About</Link></nav>;
    }
  • Use Prisma as your database ORM — integrates directly with Server Components and Server Actions.
    npm install prisma @prisma/client
    npx prisma init
    npx prisma db push  # sync schema to database
  • Add NextAuth.js or Clerk for authentication — both integrate with the App Router middleware.
    npm install next-auth
    # or
    npm install @clerk/nextjs
  • Use next/image for optimised images — automatically serves WebP and prevents layout shift.
    import Image from "next/image";
    <Image src="/hero.jpg" alt="Hero" width={1200} height={600} priority />

FAQ