Setup
Create a Project
npx create-next-app@latest my-app
The CLI asks a few questions. Recommended answers:
| Question | Answer |
|---|---|
| TypeScript? | Yes |
| ESLint? | No (next lint is deprecated in v16, use Biome or oxlint) |
| Tailwind CSS? | Yes |
src/ directory? | No (simpler for smaller projects) |
| App Router? | Yes |
| Turbopack for dev? | Yes (default in v16) |
| Import alias? | @/* (default) |
cd my-app
npm run dev
Open http://localhost:3000. The dev server uses Turbopack for fast refresh.
Project Structure
my-app/
app/
layout.tsx # Root layout (html, body, global providers)
page.tsx # Home page (/)
globals.css # Global styles, Tailwind imports
favicon.ico # Favicon
public/ # Static assets (images, fonts)
next.config.ts # Next.js configuration
tailwind.config.ts # Tailwind configuration
tsconfig.json # TypeScript configuration
package.json
Root Layout
// app/layout.tsx
import type { Metadata } from "next";
import "./globals.css";
export const metadata: Metadata = {
title: "My App",
description: "Built with Next.js",
};
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
Home Page
// app/page.tsx
export default function Home() {
return (
<main className="flex min-h-screen items-center justify-center">
<h1 className="text-4xl font-bold">Hello Next.js</h1>
</main>
);
}
Turbopack Dev Server
Turbopack is the default bundler since Next.js 16. It’s Rust-based and significantly faster than Webpack.
# Turbopack is used by default for `next dev`
npm run dev
# Explicitly enable (if on v15)
npx next dev --turbopack
| Metric | Webpack | Turbopack |
|---|---|---|
| Cold start | ~3-5s | ~1-2s |
| Fast Refresh | ~200-500ms | ~50-100ms |
| Route compile | ~500ms-2s | ~100-300ms |
Tip: Turbopack is for dev only. Production builds (
next build) still use Webpack in v15 and transitioning to Turbopack in v16+.
Tailwind CSS v4
New projects created with create-next-app use Tailwind CSS v4, which uses a CSS-first configuration approach.
/* app/globals.css */
@import "tailwindcss";
That’s it. No tailwind.config.ts needed for basic usage. Tailwind v4 auto-detects your source files.
Gotcha: If you’re following older tutorials, they’ll reference
tailwind.config.jswithcontentarrays andtheme.extend. Tailwind v4 doesn’t need any of that for standard setups. Only create a config if you need custom plugins or advanced theme overrides.
next.config.ts
// next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
// Common options:
};
export default nextConfig;
Common configuration options:
const nextConfig: NextConfig = {
// Enable image optimization for external sources
images: {
remotePatterns: [
{ protocol: "https", hostname: "images.example.com" },
],
},
// Environment variables available to the client
env: {
NEXT_PUBLIC_API_URL: process.env.API_URL,
},
// Redirects
async redirects() {
return [
{ source: "/old-page", destination: "/new-page", permanent: true },
];
},
};
Adding Your First Route
Create a new page by adding a page.tsx file in a new folder:
// app/about/page.tsx
export default function About() {
return (
<main className="p-8">
<h1 className="text-3xl font-bold">About</h1>
<p className="mt-4 text-gray-600">This is the about page.</p>
</main>
);
}
Visit http://localhost:3000/about. No imports, no router configuration. The filesystem is the router.
Scripts Reference
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
}
}
| Script | Purpose |
|---|---|
dev | Start dev server with Turbopack and hot reload |
build | Create production build |
start | Run production server (after build) |
lint | Run linter (deprecated in v16, consider alternatives) |
Next: First App | App Router