Next.js Installation Guide: Create Your First Project in 2026
Before You Start: Node.js Requirements
Next.js 15 requires Node.js 18.18.0 or later. Before installing anything, verify your Node version:
1node -v
If you see a version below 18.18.0, update Node.js first:
1# Using nvm (recommended) 2nvm install 20 3nvm use 20 4 5# Or download from nodejs.org
Pro Tip: Always use the LTS (Long Term Support) version of Node.js for production projects. As of 2026, Node.js 20+ is the sweet spot.
Installing Next.js with create-next-app
The official way to scaffold a Next.js project is through create-next-app — a CLI tool that sets up everything automatically.
Step 1: Run the Create Command
1npx create-next-app@latest my-next-app
You'll see an interactive prompt. Here's what each option means and what to choose:
✔ Would you like to use TypeScript? … Yes
→ TypeScript adds type safety. Always choose Yes for production apps.
✔ Would you like to use ESLint? … Yes
→ Catches bugs early. Essential for code quality.
✔ Would you like to use Tailwind CSS? … Yes
→ Utility-first CSS framework. Speeds up styling dramatically.
✔ Would you like to use the `src/` directory? … No
→ Keep it simple. The `app/` directory at root is fine for most projects.
✔ Would you like to use App Router? … Yes
→ The modern routing system. This is the future of Next.js.
✔ Would you like to use Turbopack for `next dev`? … Yes
→ Next-gen bundler. 700x faster than Webpack in large projects.
✔ Would you like to customize the import alias (`@/*`)? … Yes
→ Lets you write `import { Button } from '@/components/Button'` instead of relative paths.
What Happens Behind the Scenes?
create-next-app does all of this automatically:
- Downloads Next.js, React, and ReactDOM
- Configures TypeScript compiler settings
- Sets up ESLint with Next.js recommended rules
- Initializes Tailwind CSS with PostCSS
- Creates the
app/directory with a starter layout - Configures the
@/import alias intsconfig.json
Understanding Your New Project Structure
After installation, your project looks like this:
my-next-app/
├── app/ ← Your application code
│ ├── layout.tsx ← Root layout (wraps every page)
│ ├── page.tsx ← Home page (route: /)
│ └── globals.css ← Global styles
├── public/ ← Static assets (images, fonts, etc.)
│ └── file.svg
├── components/ ← Reusable UI components
├── lib/ ← Utility functions
├── node_modules/ ← Dependencies
├── .next/ ← Build output (auto-generated)
├── next.config.ts ← Next.js configuration
├── tsconfig.json ← TypeScript configuration
├── eslint.config.mjs ← ESLint rules
├── tailwind.config.ts ← Tailwind customization
├── postcss.config.mjs ← CSS processing
└── package.json ← Project metadata & scripts
Let's break down the critical files you need to understand.
Deep Dive: Key Configuration Files
1. package.json
This is your project's DNA. It lists dependencies and defines scripts.
1{ 2 "name": "my-next-app", 3 "version": "0.1.0", 4 "private": true, 5 "scripts": { 6 "dev": "next dev --turbopack", 7 "build": "next build", 8 "start": "next start", 9 "lint": "next lint" 10 }, 11 "dependencies": { 12 "next": "15.x.x", 13 "react": "^19.0.0", 14 "react-dom": "^19.0.0" 15 }, 16 "devDependencies": { 17 "typescript": "^5.x.x", 18 "@types/node": "^20.x.x", 19 "@types/react": "^19.x.x", 20 "tailwindcss": "^4.x.x", 21 "eslint": "^9.x.x", 22 "eslint-config-next": "15.x.x" 23 } 24}
| Script | Command | What It Does |
|---|---|---|
dev | next dev --turbopack | Starts development server with Turbopack |
build | next build | Creates optimized production build |
start | next start | Serves the production build |
lint | next lint | Runs ESLint to check code quality |
2. next.config.ts
The brain of your Next.js app. This is where you configure images, redirects, rewrites, and more.
1import type { NextConfig } from "next"; 2 3const nextConfig: NextConfig = { 4 // Enable React Strict Mode (catches potential problems) 5 reactStrictMode: true, 6 7 // Image optimization settings 8 images: { 9 domains: ['images.unsplash.com', 'cdn.example.com'], 10 formats: ['image/webp', 'image/avif'], 11 }, 12 13 // Redirects example 14 async redirects() { 15 return [ 16 { 17 source: '/old-blog/:slug', 18 destination: '/blog/:slug', 19 permanent: true, 20 }, 21 ]; 22 }, 23 24 // Environment variables exposed to the browser 25 env: { 26 API_URL: process.env.API_URL, 27 }, 28}; 29 30export default nextConfig;
3. tsconfig.json
TypeScript's rulebook. It tells the compiler how to handle your code.
1{ 2 "compilerOptions": { 3 "target": "ES2017", 4 "lib": ["dom", "dom.iterable", "esnext"], 5 "allowJs": true, 6 "skipLibCheck": true, 7 "strict": true, 8 "noEmit": true, 9 "esModuleInterop": true, 10 "module": "esnext", 11 "moduleResolution": "bundler", 12 "resolveJsonModule": true, 13 "isolatedModules": true, 14 "jsx": "preserve", 15 "incremental": true, 16 "plugins": [{ "name": "next" }], 17 "paths": { 18 "@/*": ["./*"] 19 } 20 }, 21 "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 22 "exclude": ["node_modules"] 23}
Key settings explained:
"strict": true— Enforces strict type checking. Never disable this."paths": { "@/*": ["./*"] }— Enables the@/import alias."jsx": "preserve"— Lets Next.js handle JSX transformation.
4. eslint.config.mjs
ESLint configuration using the new flat config format (ESLint v9+).
1import { dirname } from "path"; 2import { fileURLToPath } from "url"; 3import { FlatCompat } from "@eslint/eslintrc"; 4 5const __filename = fileURLToPath(import.meta.url); 6const __dirname = dirname(__filename); 7 8const compat = new FlatCompat({ 9 baseDirectory: __dirname, 10}); 11 12const eslintConfig = [ 13 ...compat.extends("next/core-web-vitals", "next/typescript"), 14 { 15 rules: { 16 // Custom rules 17 "no-console": "warn", // Warn on console.log 18 "@typescript-eslint/no-unused-vars": "error", 19 }, 20 }, 21]; 22 23export default eslintConfig;
This ensures your code follows Next.js best practices and catches bugs before they reach production.
The app/ Directory: App Router Explained
The app/ directory is the heart of modern Next.js. Unlike the old pages/ router, the App Router uses file-system based routing with Server Components by default.
app/
├── layout.tsx ← Root layout (required)
├── page.tsx ← Home page (/)
├── about/
│ └── page.tsx ← About page (/about)
├── blog/
│ ├── page.tsx ← Blog listing (/blog)
│ └── [slug]/
│ └── page.tsx ← Dynamic route (/blog/hello-world)
├── api/ ← API routes
│ └── hello/
│ └── route.ts ← API endpoint (/api/hello)
├── loading.tsx ← Loading UI
└── error.tsx ← Error boundary
Root Layout (app/layout.tsx)
Every page in your app is wrapped by this layout. It's perfect for global navigation, fonts, and metadata.
1import type { Metadata } from "next"; 2import { Inter } from "next/font/google"; 3import "./globals.css"; 4 5const inter = Inter({ subsets: ["latin"] }); 6 7export const metadata: Metadata = { 8 title: "My Next.js App", 9 description: "Built with Next.js 15 and App Router", 10}; 11 12export default function RootLayout({ 13 children, 14}: Readonly<{ 15 children: React.ReactNode; 16}>) { 17 return ( 18 <html lang="en"> 19 <body className={inter.className}> 20 <nav> 21 <a href="/">Home</a> 22 <a href="/about">About</a> 23 </nav> 24 {children} 25 </body> 26 </html> 27 ); 28}
The public/ Directory
Anything you put here is served at the root of your domain.
public/
├── images/
│ ├── logo.png
│ └── hero.jpg
├── favicon.ico
└── robots.txt
Access them directly:
1// In your component 2<img src="/images/logo.png" alt="Logo" /> 3 4// Or use Next.js Image component for optimization 5import Image from "next/image"; 6 7<Image 8 src="/images/hero.jpg" 9 alt="Hero" 10 width={1200} 11 height={600} 12 priority 13/>
Rule: Only put static files here. Source code belongs in
app/orcomponents/.
Turbopack: The New Development Bundler
Turbopack is Next.js's next-generation bundler written in Rust. It's the successor to Webpack and significantly faster.
Why Turbopack Matters
| Metric | Webpack | Turbopack |
|---|---|---|
| Cold start | ~3-5 seconds | ~300ms |
| File changes | ~200ms | ~10ms |
| Large projects | Slower | Consistently fast |
How to Use It
Turbopack is enabled by default in new projects via the --turbopack flag in package.json:
1"scripts": { 2 "dev": "next dev --turbopack" 3}
If you have an older project, simply add the flag:
1next dev --turbopack
Note: Turbopack is for development only. Production builds still use the optimized Next.js compiler.
Running Your Project
Development Server
Start coding with hot reloading:
1cd my-next-app 2npm run dev
You'll see:
▲ Next.js 15.x.x (Turbopack)
- Local: http://localhost:3000
- Network: http://192.168.x.x:3000
Open http://localhost:3000 in your browser. Every file change automatically refreshes the page.
What happens during npm run dev?
- Turbopack bundles your code
- TypeScript compiles in the background
- ESLint runs on save
- Hot Module Replacement (HMR) updates the browser instantly
Production Build
When you're ready to deploy, create an optimized build:
1npm run build
This command:
- Compiles TypeScript to JavaScript
- Optimizes images automatically
- Generates static HTML for SSG routes
- Bundles CSS and JavaScript
- Creates a
.next/folder with production-ready files
You'll see output like:
Route (app) Size First Load JS
┌ ○ / 5.23 kB 89.4 kB
├ ○ /_not-found 873 B 89.4 kB
└ ○ /about 3.12 kB 87.3 kB
○ (Static) prerendered as static HTML
○= Statically generated (fastest)λ= Server-side rendered (dynamic)ƒ= API route
Production Server
Serve your built application:
1npm run start
This starts a Node.js server that serves your optimized app. In production, you'll typically run:
1# Build first 2npm run build 3 4# Then start 5npm run start
For deployment: Platforms like Vercel, Netlify, and AWS Amplify run
npm run buildautomatically. You only neednpm run startfor self-hosted servers.
Complete Command Reference
| Command | Purpose | When to Use |
|---|---|---|
npx create-next-app@latest | Create new project | Starting a new app |
npm run dev | Start dev server with Turbopack | Daily development |
npm run build | Create production build | Before deploying |
npm run start | Serve production build | Production environment |
npm run lint | Check code with ESLint | Before committing code |
npm install <package> | Add dependencies | Adding libraries |
Practical Example: Building a Complete Page
Let's put it all together. Here's a real-world example of a blog page using everything we've learned:
File: app/blog/page.tsx
1import Link from "next/link"; 2import Image from "next/image"; 3import { Metadata } from "next"; 4 5// Metadata for SEO 6export const metadata: Metadata = { 7 title: "Blog | My Next.js App", 8 description: "Read the latest articles on web development", 9}; 10 11// Mock data (in real app, fetch from API or database) 12const posts = [ 13 { 14 id: 1, 15 title: "Getting Started with Next.js", 16 excerpt: "Learn the fundamentals of Next.js framework...", 17 image: "/images/nextjs.jpg", 18 date: "2026-08-15", 19 }, 20 { 21 id: 2, 22 title: "Mastering TypeScript", 23 excerpt: "Type-safe JavaScript for scalable applications...", 24 image: "/images/typescript.jpg", 25 date: "2026-08-10", 26 }, 27]; 28 29export default function BlogPage() { 30 return ( 31 <main className="max-w-4xl mx-auto px-4 py-12"> 32 <h1 className="text-4xl font-bold mb-8">Latest Articles</h1> 33 34 <div className="grid gap-8"> 35 {posts.map((post) => ( 36 <article 37 key={post.id} 38 className="border rounded-lg overflow-hidden hover:shadow-lg transition" 39 > 40 <Image 41 src={post.image} 42 alt={post.title} 43 width={800} 44 height={400} 45 className="w-full h-48 object-cover" 46 /> 47 <div className="p-6"> 48 <time className="text-sm text-gray-500">{post.date}</time> 49 <h2 className="text-xl font-semibold mt-2"> 50 <Link href={`/blog/${post.id}`} className="hover:text-blue-600"> 51 {post.title} 52 </Link> 53 </h2> 54 <p className="text-gray-600 mt-2">{post.excerpt}</p> 55 </div> 56 </article> 57 ))} 58 </div> 59 </main> 60 ); 61}
File: app/blog/[id]/page.tsx (Dynamic Route)
1import { notFound } from "next/navigation"; 2import Image from "next/image"; 3 4interface Props { 5 params: Promise<{ id: string }>; 6} 7 8export default async function BlogPost({ params }: Props) { 9 const { id } = await params; 10 11 // In real app: fetch from API or database 12 const post = await fetch(`https://api.example.com/posts/${id}`, { 13 cache: "force-cache", // Static generation 14 }).then((res) => res.json()); 15 16 if (!post) { 17 notFound(); // Shows 404 page 18 } 19 20 return ( 21 <article className="max-w-2xl mx-auto px-4 py-12"> 22 <Image 23 src={post.image} 24 alt={post.title} 25 width={1200} 26 height={600} 27 priority 28 className="rounded-lg mb-8" 29 /> 30 <h1 className="text-3xl font-bold mb-4">{post.title}</h1> 31 <div className="prose lg:prose-xl">{post.content}</div> 32 </article> 33 ); 34}
Common Issues & Solutions
| Problem | Solution |
|---|---|
Port 3000 is already in use | Run npx next dev -p 3001 to use a different port |
TypeScript errors on build | Check tsconfig.json has "strict": true and fix type issues |
Images not loading | Ensure images are in public/ or use external domains in next.config.ts |
ESLint errors prevent build | Run npm run lint to see issues, or temporarily disable in next.config.ts with eslint.ignoreDuringBuilds: true |
Module not found | Check your @/ alias in tsconfig.json paths |
Checklist: Your First Next.js Project
- Node.js 18.18+ installed
- Project created with
create-next-app - TypeScript enabled
- App Router selected
- Turbopack running (
npm run dev) - Understood
package.jsonscripts - Explored
next.config.ts - Created a page in
app/ - Added an image to
public/ - Built for production (
npm run build) - Verified build output in
.next/
What's Next?
Now that your project is set up, in the next module we'll explore:
- Routing deep dive — Nested layouts, route groups, parallel routes
- Data fetching — Server Components, caching strategies, revalidation
- Styling — Tailwind CSS, CSS Modules, and global styles
- API Routes — Building your backend inside Next.js
Your mission: Create a new Next.js project right now, run the dev server, and modify the home page. Change the title, add a new route, and explore the file structure. The best way to learn is by doing!