How to Install Next.js: The Complete 2024 Guide
Master Next.js installation with this definitive guide. From zero to production-ready setup in minutes. Includes troubleshooting, best practices, performance tips, and everything you need to start building amazing web applications.

TL;DR - Quick Start
Just want to get started? Run this single command:
npx create-next-app@latest my-app
Answer the prompts (say "Yes" to TypeScript, ESLint, and App Router), then:
cd my-app && npm run dev
Visit http://localhost:3000 - You're done! š
For detailed explanations, keep reading...
Why Next.js?
Before diving into installation, let's understand why Next.js has become the go-to framework for modern web development:
- Server-Side Rendering (SSR): Better SEO and faster initial page loads
- Static Site Generation (SSG): Lightning-fast performance for static content
- Automatic Code Splitting: Faster page loads with optimized bundles
- Built-in Routing: File-system based routing - no configuration needed
- API Routes: Build your backend and frontend in one place
- Image Optimization: Automatic image optimization out of the box
- TypeScript Support: First-class TypeScript integration
- Excellent DX: Hot reload, error overlay, and amazing developer experience
Prerequisites Checklist
Before starting, ensure you have:
ā Node.js (Required)
Minimum Version: Node.js 18.17 or later Recommended: Latest LTS version (20.x or later)
Check your version:
node --version
# Should show v18.17.0 or higher
npm --version
# Should show 9.0.0 or higher
Don't have Node.js? Download it from nodejs.org
š” Pro Tip: Use nvm (Node Version Manager) to easily switch between Node.js versions for different projects.
ā Code Editor (Highly Recommended)
Best Choice: Visual Studio Code
Essential VS Code Extensions:
- ES7+ React/Redux/React-Native snippets - Code snippets
- Prettier - Code formatter
- ESLint - Linting support
- Tailwind CSS IntelliSense - Tailwind autocomplete
- Auto Rename Tag - Automatically rename paired HTML/JSX tags
- GitLens - Enhanced Git capabilities
ā Terminal/Command Line
- macOS/Linux: Built-in Terminal
- Windows: PowerShell, Command Prompt, or Windows Terminal
ā Basic Knowledge
- JavaScript/TypeScript fundamentals
- Basic React concepts (components, props, state)
- Command line basics
Installation Methods
Choose the method that best suits your needs:
| Method | Best For | Difficulty | Time | |--------|----------|------------|------| | Automatic (create-next-app) | Most users, quick start | ā Easy | 2 min | | Manual Installation | Custom setups, learning | āā Medium | 5 min | | Turbopack (Experimental) | Bleeding edge | āāā Advanced | 3 min |
Method 1: Automatic Installation (Recommended)
This is the fastest and easiest way to create a Next.js project.
Step 1: Run the Create Command
Open your terminal and execute:
# Using npx (comes with npm)
npx create-next-app@latest my-awesome-app
# Or specify the directory
npx create-next-app@latest .
š Note:
npxcomes bundled with npm (Node.js). No separate installation needed!
Step 2: Configuration Wizard
You'll be asked several questions. Here's what each means:
TypeScript - Would you like to use TypeScript?
ā
Recommended: YES
Why? TypeScript catches errors before runtime, provides better autocomplete, and makes refactoring safer.
ESLint - Would you like to use ESLint?
ā
Recommended: YES
Why? ESLint identifies code quality issues and enforces consistent coding standards.
Tailwind CSS - Would you like to use Tailwind CSS?
ā
Recommended: YES
Why? Utility-first CSS framework for rapid UI development. Highly optimized and tree-shakeable.
src/ Directory - Would you like to use src/ directory?
āŖ Optional: NO (simpler structure)
Why? Beginners should start with the default structure. Use src/ for larger projects to separate source code from configuration.
App Router - Would you like to use App Router?
ā
Recommended: YES
Why? The new App Router (Next.js 13+) offers React Server Components, improved layouts, and better data fetching. It's the future of Next.js.
Import Alias - Would you like to customize the default import alias?
āŖ Optional: NO (use default @/*)
Why? The default @/* alias works great. Only customize if you have specific needs.
Step 3: Installation Progress
You'll see output like this:
Creating a new Next.js app in /Users/you/my-awesome-app...
Using npm.
Installing dependencies:
- react
- react-dom
- next
Installing devDependencies:
- typescript
- @types/node
- @types/react
- @types/react-dom
- eslint
- eslint-config-next
ā Installation complete!
Step 4: Navigate to Your Project
cd my-awesome-app
Step 5: Start Development Server
npm run dev
Expected Output:
ā² Next.js 15.0.0
- Local: http://localhost:3000
- Network: http://192.168.1.100:3000
ā Ready in 1.2s
Step 6: View Your App
Open your browser and navigate to http://localhost:3000
š Congratulations! Your Next.js app is running!
Method 2: Manual Installation
For those who want more control or to understand what's happening under the hood.
Step 1: Create Project Directory
# Create and enter directory
mkdir my-nextjs-project
cd my-nextjs-project
Step 2: Initialize Package Manager
# Initialize with default settings
npm init -y
This creates a package.json file.
Step 3: Install Core Dependencies
# Install Next.js, React, and React DOM
npm install next@latest react@latest react-dom@latest
What gets installed:
next: The Next.js frameworkreact: React libraryreact-dom: React DOM rendering
Step 4: Install TypeScript (Optional but Recommended)
npm install --save-dev typescript @types/react @types/node
Step 5: Configure package.json Scripts
Edit your package.json and add these scripts:
{
"name": "my-nextjs-project",
"version": "1.0.0",
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"next": "^15.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"typescript": "^5.0.0",
"@types/node": "^20.0.0",
"@types/react": "^19.0.0"
}
}
Step 6: Create App Directory Structure
# Create the app directory (App Router)
mkdir app
# Or create pages directory (Pages Router - legacy)
# mkdir pages
Step 7: Create Root Layout
Create app/layout.tsx:
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'My Next.js App',
description: 'Built with Next.js',
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
{children}
</body>
</html>
)
}
Step 8: Create Your First Page
Create app/page.tsx:
export default function HomePage() {
return (
<div style={{ padding: '2rem', fontFamily: 'system-ui' }}>
<h1>Welcome to Next.js! š</h1>
<p>You just built your first Next.js app from scratch.</p>
<ul>
<li>ā
Server-side rendering enabled</li>
<li>ā
Automatic code splitting</li>
<li>ā
Hot module replacement</li>
<li>ā
TypeScript support</li>
</ul>
</div>
)
}
Step 9: Create TypeScript Config (Optional)
Create tsconfig.json:
{
"compilerOptions": {
"target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}
Step 10: Start Your Server
npm run dev
Next.js will automatically create missing configuration files on first run.
Package Manager Comparison
Different package managers offer different benefits:
npm (Default)
Pros:
- Comes with Node.js
- Most widely used
- Extensive documentation
Installation:
npx create-next-app@latest my-app
cd my-app
npm run dev
pnpm (Recommended for Large Projects)
Pros:
- 3x faster than npm
- Saves disk space with shared dependencies
- Strict dependency resolution
Installation:
# Install pnpm globally
npm install -g pnpm
# Create Next.js app
pnpm create next-app my-app
# Run development server
cd my-app
pnpm dev
Performance Comparison:
Install Time (100 dependencies):
npm: 45s
pnpm: 15s ā”
yarn: 25s
bun: 3s š
Yarn (Stable Alternative)
Pros:
- Faster than npm
- Deterministic installs
- Workspaces support
Installation:
# Create Next.js app
yarn create next-app my-app
# Run development server
cd my-app
yarn dev
Bun (Fastest - Experimental)
Pros:
- 15x faster than npm
- All-in-one runtime
- Native TypeScript support
Installation:
# Install Bun first
curl -fsSL https://bun.sh/install | bash
# Create Next.js app
bunx create-next-app my-app
# Run with Bun
cd my-app
bun dev
ā ļø Warning: Bun is still experimental. Use npm or pnpm for production projects.
Project Structure Explained
Understanding your Next.js project structure:
my-next-app/
āāā app/ # App Router directory (Next.js 13+)
ā āāā layout.tsx # Root layout (wraps all pages)
ā āāā page.tsx # Home page (route: /)
ā āāā about/
ā ā āāā page.tsx # About page (route: /about)
ā āāā api/
ā ā āāā hello/
ā ā āāā route.ts # API endpoint (POST /api/hello)
ā āāā globals.css # Global styles
ā āāā favicon.ico # Favicon
āāā public/ # Static files (served as-is)
ā āāā images/
ā āāā fonts/
āāā node_modules/ # Dependencies (auto-generated)
āāā .next/ # Build output (auto-generated)
āāā .env.local # Environment variables (gitignored)
āāā next.config.js # Next.js configuration
āāā package.json # Dependencies and scripts
āāā tsconfig.json # TypeScript configuration
āāā .eslintrc.json # ESLint configuration
āāā .gitignore # Git ignore rules
āāā README.md # Project documentation
Key Directories
app/ - Your Application Code
- File-based routing: Each folder = route segment
- Special files:
page.tsx- Page componentlayout.tsx- Layout wrapperloading.tsx- Loading UIerror.tsx- Error UInot-found.tsx- 404 pageroute.ts- API endpoints
public/ - Static Assets
- Served from root URL
- Example:
public/logo.pngā/logo.png - No processing, served as-is
- Use for: images, fonts, robots.txt, sitemap.xml
Configuration Files
next.config.js: Next.js settingstsconfig.json: TypeScript settings.env.local: Environment variables
Troubleshooting Common Issues
Issue 1: Port Already in Use
Error:
Error: listen EADDRINUSE: address already in use :::3000
Solutions:
Option A: Use Different Port
npm run dev -- -p 3001
# or
PORT=3001 npm run dev
Option B: Kill Process on Port 3000
# macOS/Linux
lsof -ti:3000 | xargs kill -9
# Windows (PowerShell)
netstat -ano | findstr :3000
taskkill /PID <PID_NUMBER> /F
# Windows (CMD)
for /f "tokens=5" %a in ('netstat -aon ^| find ":3000"') do taskkill /f /pid %a
Issue 2: Module Not Found
Error:
Module not found: Can't resolve 'react'
Solution:
# Delete node_modules and reinstall
rm -rf node_modules package-lock.json
npm install
# Or clear npm cache
npm cache clean --force
npm install
Issue 3: TypeScript Errors
Error:
Cannot find module '@/components/Header' or its corresponding type declarations
Solution:
Ensure your tsconfig.json has the correct path alias:
{
"compilerOptions": {
"paths": {
"@/*": ["./*"]
}
}
}
Issue 4: Node Version Incompatibility
Error:
error next@15.0.0: The engine "node" is incompatible with this module.
Solution:
# Check Node version
node --version
# Update Node.js using nvm
nvm install 20
nvm use 20
nvm alias default 20
# Or download latest from nodejs.org
Issue 5: Permission Errors (macOS/Linux)
Error:
EACCES: permission denied
Solution:
# Fix npm permissions (recommended)
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
# Then reinstall
npm install -g create-next-app
Issue 6: Slow Installation
Problem: npm install takes forever
Solutions:
# Use faster package manager
npm install -g pnpm
pnpm install
# Or clear cache
npm cache clean --force
npm install
# Use offline mode if dependencies are cached
npm install --offline
Next Steps: Building Your First Feature
1. Create a New Page
# Create about directory
mkdir app/about
# Create page file
touch app/about/page.tsx
// app/about/page.tsx
export default function AboutPage() {
return (
<div>
<h1>About Us</h1>
<p>Learn more about our company...</p>
</div>
)
}
Navigate to http://localhost:3000/about - Your page is live!
2. Add Styling with Tailwind CSS
If you installed Tailwind, update your page:
// app/page.tsx
export default function Home() {
return (
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100 p-8">
<div className="max-w-4xl mx-auto">
<h1 className="text-5xl font-bold text-gray-900 mb-4">
Welcome to Next.js
</h1>
<p className="text-xl text-gray-600 mb-8">
Build amazing web applications with React
</p>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<div className="bg-white p-6 rounded-lg shadow-md">
<h3 className="text-lg font-semibold mb-2">Fast</h3>
<p className="text-gray-600">Optimized for performance</p>
</div>
<div className="bg-white p-6 rounded-lg shadow-md">
<h3 className="text-lg font-semibold mb-2">Scalable</h3>
<p className="text-gray-600">Grows with your needs</p>
</div>
<div className="bg-white p-6 rounded-lg shadow-md">
<h3 className="text-lg font-semibold mb-2">Modern</h3>
<p className="text-gray-600">Latest React features</p>
</div>
</div>
</div>
</div>
)
}
3. Create an API Route
// app/api/hello/route.ts
import { NextResponse } from 'next/server'
export async function GET() {
return NextResponse.json({
message: 'Hello from Next.js API!',
timestamp: new Date().toISOString(),
})
}
export async function POST(request: Request) {
const data = await request.json()
return NextResponse.json({
message: 'Data received',
data,
})
}
Test it: http://localhost:3000/api/hello
4. Add Environment Variables
Create .env.local:
# .env.local
DATABASE_URL=postgresql://localhost:5432/mydb
API_KEY=your-secret-key-here
NEXT_PUBLIC_APP_URL=http://localhost:3000
Access in code:
// Server-side only
const dbUrl = process.env.DATABASE_URL
// Client and server (must start with NEXT_PUBLIC_)
const appUrl = process.env.NEXT_PUBLIC_APP_URL
š Security: Never commit
.env.localto Git! It's already in.gitignore.
Best Practices & Pro Tips
1. Use TypeScript Everywhere
// ā
Good: Type-safe props
interface ButtonProps {
label: string
onClick: () => void
variant?: 'primary' | 'secondary'
}
export default function Button({ label, onClick, variant = 'primary' }: ButtonProps) {
return <button onClick={onClick}>{label}</button>
}
// ā Avoid: Untyped props
export default function Button({ label, onClick, variant }) {
return <button onClick={onClick}>{label}</button>
}
2. Optimize Images
import Image from 'next/image'
// ā
Good: Next.js Image component
<Image
src="/hero.jpg"
alt="Hero image"
width={1200}
height={600}
priority // For above-the-fold images
/>
// ā Avoid: Regular img tag
<img src="/hero.jpg" alt="Hero image" />
3. Use Server Components by Default
// app/posts/page.tsx
// This is a Server Component by default (no 'use client')
async function getPosts() {
const res = await fetch('https://api.example.com/posts')
return res.json()
}
export default async function PostsPage() {
const posts = await getPosts()
return (
<div>
{posts.map(post => (
<article key={post.id}>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
</article>
))}
</div>
)
}
4. Implement Loading States
// app/posts/loading.tsx
export default function Loading() {
return (
<div className="flex items-center justify-center min-h-screen">
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500" />
</div>
)
}
5. Add Error Boundaries
// app/posts/error.tsx
'use client'
export default function Error({
error,
reset,
}: {
error: Error
reset: () => void
}) {
return (
<div>
<h2>Something went wrong!</h2>
<p>{error.message}</p>
<button onClick={reset}>Try again</button>
</div>
)
}
6. Configure Next.js Settings
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
domains: ['api.example.com'],
formats: ['image/avif', 'image/webp'],
},
env: {
CUSTOM_KEY: 'my-value',
},
experimental: {
serverActions: true,
},
}
module.exports = nextConfig
Performance Optimization Tips
1. Enable Turbopack (Experimental)
# Much faster than Webpack
npm run dev --turbo
Update package.json:
{
"scripts": {
"dev": "next dev --turbo"
}
}
2. Use Dynamic Imports
import dynamic from 'next/dynamic'
// Load heavy component only when needed
const HeavyComponent = dynamic(() => import('@/components/HeavyComponent'), {
loading: () => <p>Loading...</p>,
ssr: false, // Disable server-side rendering if not needed
})
3. Implement Route Handlers for API
// app/api/users/route.ts
import { NextResponse } from 'next/server'
export async function GET() {
// Fetch users from database
const users = await db.users.findMany()
return NextResponse.json(users, {
headers: {
'Cache-Control': 'public, s-maxage=60, stale-while-revalidate=300',
},
})
}
4. Enable Image Optimization
<Image
src="/large-image.jpg"
alt="Optimized image"
width={800}
height={600}
quality={75} // Default is 75, lower for smaller files
placeholder="blur" // Show blur while loading
blurDataURL="/placeholder.jpg"
/>
Deployment Quick Start
Deploy to Vercel (Easiest)
# Install Vercel CLI
npm install -g vercel
# Deploy
vercel
Build for Production
# Create production build
npm run build
# Test production locally
npm start
FAQ
Q: Can I use Next.js with JavaScript instead of TypeScript?
A: Yes! Just answer "No" to TypeScript during setup, or create .js files instead of .ts/.tsx.
Q: What's the difference between App Router and Pages Router? A: App Router (Next.js 13+) is the new routing system with React Server Components. Pages Router is the legacy system. Use App Router for new projects.
Q: Do I need to know React to use Next.js? A: Yes, Next.js is built on React. You should understand React basics (components, props, state, hooks) before learning Next.js.
Q: Can I use Next.js for static sites?
A: Absolutely! Next.js excels at static site generation. Use output: 'export' in next.config.js for fully static sites.
Q: How do I add a database? A: Install a database client (Prisma, Mongoose, etc.) and connect it in your API routes or Server Components.
Q: Is Next.js free? A: Yes! Next.js is open-source and free. Vercel (the company behind Next.js) offers free hosting with generous limits.
Conclusion
You've now learned everything you need to install and set up Next.js! Whether you chose the automatic or manual installation, you're ready to build amazing web applications.
Key Takeaways:
ā
Use create-next-app for fastest setup
ā
Enable TypeScript for better code quality
ā
Use App Router for modern features
ā
Install Tailwind CSS for rapid styling
ā
Configure ESLint for clean code
ā
Set up environment variables properly
ā
Optimize images with next/image
ā
Use Server Components by default
What's Next?
- Build your first feature
- Explore the Next.js documentation
- Join the Next.js community
- Deploy your first app to Vercel
- Learn about data fetching patterns
- Master server and client components
Additional Resources
Official Documentation
- Next.js Docs - Official documentation
- Next.js Learn - Interactive tutorial
- Next.js Examples - 300+ examples
Community & Support
- Next.js Discord - Get help from the community
- Next.js GitHub - Report issues, contribute
- Next.js Reddit - Discussions and questions
Video Tutorials
- Next.js Crash Course - YouTube tutorials
- Vercel YouTube - Official videos
Deployment
- Vercel - Deploy in seconds (recommended)
- Netlify - Alternative hosting
- AWS Amplify - AWS hosting
Ready to build something amazing? Start coding and don't forget to share your first Next.js project! š
Questions or stuck on something? Drop a comment below and I'll help you out!