Initial Setup
Ready to set up Next.js? This guide walks through installing Next.js with TypeScript, creating your first project, and understanding the development environment.
Prerequisites: You should understand React fundamentals before starting with Next.js.
Prerequisites Check
Before installing Next.js, verify you have the required tools.
Step 1: Check Node.js version
node --versionRequired: Node.js 18.18 or later
If not installed: Download from nodejs.org (LTS version recommended)
Step 2: Check npm version
npm --versionRequired: npm 9 or later (comes with Node.js)
Step 3: Verify React knowledge
Next.js is built on React. Ensure you understand:
- React components - Function components, JSX syntax
- Props - Passing data between components
- State - useState hook for local state
- Effects - useEffect hook for side effects
- Event handling - onClick, onChange, onSubmit
Not familiar? Complete React Initial Setup and Quick Start first.
Create Next.js Project
Use create-next-app to scaffold a new Next.js project with TypeScript.
Step 1: Run create-next-app
npx create-next-app@latest my-nextjs-appInteractive prompts (recommended selections):
✔ Would you like to use TypeScript? … Yes
✔ Would you like to use ESLint? … Yes
✔ Would you like to use Tailwind CSS? … Yes
✔ Would you like to use `src/` directory? … No
✔ Would you like to use App Router? … Yes (recommended)
✔ Would you like to customize the default import alias (@/*)? … NoWhy these choices:
- TypeScript - Type safety and better tooling
- ESLint - Catch errors early
- Tailwind CSS - Utility-first styling
- No src/ directory - Simpler structure for beginners
- App Router - Modern Next.js architecture (replaces Pages Router)
- Default import alias - Clean imports with @/components/…
Step 2: Navigate to project
cd my-nextjs-appStep 3: Install dependencies (if not auto-installed)
npm installProject Structure
Understanding the App Router file structure.
my-nextjs-app/
├── app/ # App Router directory
│ ├── favicon.ico # Site favicon
│ ├── globals.css # Global styles
│ ├── layout.tsx # Root layout (wraps all pages)
│ └── page.tsx # Home page (/)
├── public/ # Static assets
│ ├── next.svg # Next.js logo
│ └── vercel.svg # Vercel logo
├── node_modules/ # Dependencies
├── .eslintrc.json # ESLint configuration
├── .gitignore # Git ignore rules
├── next.config.ts # Next.js configuration
├── package.json # Project metadata and scripts
├── tailwind.config.ts # Tailwind CSS configuration
├── tsconfig.json # TypeScript configuration
└── README.md # Project documentationKey directories:
- app/ - All routes and components (App Router)
- public/ - Static files served from root URL
- node_modules/ - Installed packages (don’t edit)
Key files:
- app/layout.tsx - Root layout wrapping all pages
- app/page.tsx - Home page component
- next.config.ts - Next.js build configuration
- tsconfig.json - TypeScript compiler options
- package.json - Dependencies and scripts
Understanding Default Files
Examining the generated files to understand Next.js structure.
app/layout.tsx - Root Layout
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
{children}
</body>
</html>
);
}Key points:
- Root layout - Wraps all pages in application
- Metadata export - Sets page title and description
- Font optimization - Next.js optimizes Google Fonts
- children prop - Renders page content
- Server Component - No ‘use client’ directive (default)
app/page.tsx - Home Page
import Image from "next/image";
export default function Home() {
return (
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
<main className="flex flex-col gap-8 row-start-2 items-center sm:items-start">
<Image
className="dark:invert"
src="/next.svg"
alt="Next.js logo"
width={180}
height={38}
priority
/>
<ol className="list-inside list-decimal text-sm text-center sm:text-left font-[family-name:var(--font-geist-mono)]">
<li className="mb-2">
Get started by editing{" "}
<code className="bg-black/[.05] dark:bg-white/[.06] px-1 py-0.5 rounded font-semibold">
app/page.tsx
</code>
.
</li>
<li>Save and see your changes instantly.</li>
</ol>
{/* More content... */}
</main>
</div>
);
}Key points:
- Default export - Function component as default export
- Server Component - Renders on server by default
- next/image - Optimized image component
- Tailwind classes - Utility-first styling
next.config.ts - Configuration
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
/* config options here */
};
export default nextConfig;Common configuration options:
const nextConfig: NextConfig = {
// Enable strict mode for better debugging
reactStrictMode: true,
// Image optimization domains
images: {
domains: ["example.com"],
},
// Environment variables exposed to browser
env: {
CUSTOM_KEY: process.env.CUSTOM_KEY,
},
// Redirects
async redirects() {
return [
{
source: "/old-path",
destination: "/new-path",
permanent: true,
},
];
},
};tsconfig.json - TypeScript Configuration
{
"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", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}Key settings:
- strict: true - Enable all strict type checking
- paths - Import alias (@/components/Button)
- jsx: preserve - Next.js handles JSX transformation
- next plugin - TypeScript language service plugin
First Development Run
Starting the development server and viewing your application.
Step 1: Start development server
npm run devExpected output:
▲ Next.js 15.1.0
- Local: http://localhost:3000
- Environments: .env
✓ Starting...
✓ Ready in 2.3sStep 2: Open browser
Navigate to http://localhost:3000
You should see:
- Next.js welcome page
- Next.js logo
- Links to documentation and examples
- Instructions to edit app/page.tsx
Step 3: Make a change
Edit app/page.tsx:
export default function Home() {
return (
<div className="flex flex-col items-center justify-center min-h-screen">
<h2>Welcome to Next.js</h2>
<p>Edit app/page.tsx and save to reload</p>
</div>
);
}Save the file - Browser automatically reloads with changes (Fast Refresh)
Step 4: Stop development server
Press Ctrl+C in terminal
Development Scripts
Understanding package.json scripts for Next.js development.
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
}
}Script explanations:
npm run dev:
- Starts development server on port 3000
- Enables Fast Refresh (instant updates on save)
- Shows detailed error messages
- Not optimized for production
npm run build:
- Creates optimized production build
- Generates static HTML for static pages
- Optimizes JavaScript bundles
- Required before deploying
npm run start:
- Starts production server
- Serves optimized build
- Must run
npm run buildfirst
npm run lint:
- Runs ESLint to check code quality
- Catches common errors and anti-patterns
- Enforces Next.js best practices
IDE Setup (VS Code)
Recommended VS Code extensions for Next.js development.
Step 1: Install VS Code extensions
- ES7+ React/Redux/React-Native snippets - React code snippets
- Tailwind CSS IntelliSense - Tailwind class autocomplete
- TypeScript Error Translator - Readable TypeScript errors
- ESLint - Real-time linting
- Prettier - Code formatter - Automatic code formatting
Step 2: Configure VS Code settings
Create .vscode/settings.json:
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"typescript.tsdk": "node_modules/typescript/lib"
}Benefits:
- Format on save - Consistent code style
- Auto-fix ESLint - Fix linting errors automatically
- TypeScript SDK - Use project’s TypeScript version
Step 3: Create .prettierrc
{
"semi": true,
"trailingComma": "es5",
"singleQuote": false,
"printWidth": 80,
"tabWidth": 2
}Environment Variables
Setting up environment variables for development and production.
Step 1: Create .env.local
# Database
DATABASE_URL="postgresql://localhost:5432/mydb"
# API Keys (never commit to git)
NEXT_PUBLIC_API_URL="http://localhost:3000/api"
API_SECRET_KEY="your-secret-key"Step 2: Access environment variables
// Server-side (Server Components, API Routes, Server Actions)
const secretKey = process.env.API_SECRET_KEY;
// Client-side (must prefix with NEXT_PUBLIC_)
const apiUrl = process.env.NEXT_PUBLIC_API_URL;Important rules:
- NEXTPUBLIC* prefix - Exposed to browser (use for public values only)
- No prefix - Server-side only (secure values)
- .env.local - Never commit to git (add to .gitignore)
- .env.example - Commit template without actual values
Step 3: Create .env.example
# Database
DATABASE_URL=""
# API Keys
NEXT_PUBLIC_API_URL=""
API_SECRET_KEY=""Commit this file to show required environment variables without exposing secrets.
Verification Checklist
Ensure your Next.js development environment is properly configured.
Step 1: Verify installation
- Node.js 18.18+ installed
- npm 9+ installed
- Next.js project created with TypeScript
- Dependencies installed successfully
Step 2: Verify project structure
- app/ directory exists
- app/layout.tsx exists (root layout)
- app/page.tsx exists (home page)
- next.config.ts exists
Step 3: Verify development server
-
npm run devstarts without errors - http://localhost:3000 loads in browser
- Editing app/page.tsx triggers Fast Refresh
- Changes appear in browser automatically
Step 4: Verify tooling
- TypeScript provides autocomplete
- ESLint shows warnings in editor
-
npm run lintexecutes successfully -
npm run buildcreates .next directory
All checked? You’re ready for Quick Start.
Common Issues
Troubleshooting common Next.js installation problems.
Issue: Node.js version too old
Error: “Next.js requires Node.js 18.18 or later”
Solution:
# Check current version
node --version
# Install latest LTS from nodejs.org
# Or use nvm (Node Version Manager)
nvm install --lts
nvm use --ltsIssue: Port 3000 already in use
Error: “Port 3000 is already in use”
Solution:
# Option 1: Stop other process using port 3000
lsof -ti:3000 | xargs kill
# Option 2: Use different port
npm run dev -- -p 3001Issue: Module not found errors
Error: “Cannot find module ‘@/components/…’”
Solution:
# Delete node_modules and reinstall
rm -rf node_modules
rm package-lock.json
npm installIssue: TypeScript errors in editor
Error: Red squiggly lines in .tsx files
Solution:
# Restart TypeScript server in VS Code
# Command Palette (Cmd/Ctrl+Shift+P) -> "TypeScript: Restart TS Server"
# Or ensure correct TypeScript version
npm install --save-dev typescript@latestNext Steps
Environment configured? Continue your Next.js journey:
- Quick Start - Build first Next.js application with Server Components and Server Actions
- Overview - Understand Next.js architecture and concepts
Need React fundamentals?
- React Initial Setup - Set up React development environment
- React Quick Start - Learn React basics first