Next.js Getting Started

Set up a Next.js project, add pages and layouts, and run the dev server in minutes.

TL;DR

  1. Create a project with npx create-next-app@latest and accept the defaults.
  2. Add a route by creating a page.tsx file inside app.
  3. Run npm run dev and open localhost:3000 to see changes.

Create a Project

    create-next-app

    Scaffold a new app with TypeScript, Tailwind, and the App Router ready to go.

    npx create-next-app@latest my-app
    cd my-app
    npm run dev

    Start the local dev server with Turbopack and instant fast refresh.

    npm run dev
    # open http://localhost:3000
    npm run build

    Create the production build, then serve it with the built-in Node.js server.

    npm run build
    npm run start

Pages and Layouts

    app/page.tsx

    Export a default component from this file to render the home page.

    // app/page.tsx
    export default function Page() {
      return <h1>Hello, Next.js</h1>;
    }
    app/about/page.tsx

    Add a folder with a page.tsx file to create a route at that path.

    // app/about/page.tsx -> /about
    export default function About() {
      return <h1>About us</h1>;
    }
    app/layout.tsx

    Wrap every page in shared UI; the root layout renders the html and body tags.

    export default function RootLayout({
      children,
    }: {
      children: React.ReactNode;
    }) {
      return (
        <html lang="en">
          <body>{children}</body>
        </html>
      );
    }
    <Link>

    Move between pages without a full page reload by using the Link component.

    import Link from 'next/link';
    
    export default function Nav() {
      return <Link href="/about">About</Link>;
    }
    'use client'

    Add this line to a file when the component needs state or event handlers.

    'use client';
    import { useState } from 'react';
    
    export default function Counter() {
      const [n, setN] = useState(0);
      return (
        <button onClick={() => setN(n + 1)}>
          Clicked {n}
        </button>
      );
    }
    async Page

    Fetch data right inside a page, because pages are Server Components by default.

    const API = 'https://api.example.com';
    
    export default async function Page() {
      const res = await fetch(`${API}/posts`);
      const posts = await res.json();
      return <p>{posts.length} posts</p>;
    }

API Routes and Config

    route.ts

    Export a function named after an HTTP method to create an API endpoint.

    // app/api/hello/route.ts
    export async function GET() {
      return Response.json({ message: 'Hello' });
    }
    next.config.ts

    Set project-wide options in this file at the root of the project.

    import type { NextConfig } from 'next';
    
    const nextConfig: NextConfig = {
      poweredByHeader: false,
    };
    
    export default nextConfig;
    .env.local

    Store secrets here; only names starting with NEXT_PUBLIC_ reach the browser.

    # .env.local
    DATABASE_URL="postgres://..."
    NEXT_PUBLIC_SITE_NAME="My App"

Tips

  1. Accept the create-next-app defaults for TypeScript, Tailwind, and the App Router unless your team already uses something else.
  2. Upgrade next, react, and react-dom together, because each Next.js release expects a matching version of React.

Warnings

  1. Next.js 16 needs Node.js 20.9 or newer, so npm run dev fails on older versions of Node.
  2. Hooks like useState only work in files marked 'use client', because pages are Server Components by default.

In Practice

FAQ