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 --version

Required: Node.js 18.18 or later

If not installed: Download from nodejs.org (LTS version recommended)

Step 2: Check npm version

npm --version

Required: 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-app

Interactive 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 (@/*)? … No

Why 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-app

Step 3: Install dependencies (if not auto-installed)

npm install

Project 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 documentation

Key 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 dev

Expected output:

  ▲ Next.js 15.1.0
  - Local:        http://localhost:3000
  - Environments: .env

 ✓ Starting...
 ✓ Ready in 2.3s

Step 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 build first

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

  1. ES7+ React/Redux/React-Native snippets - React code snippets
  2. Tailwind CSS IntelliSense - Tailwind class autocomplete
  3. TypeScript Error Translator - Readable TypeScript errors
  4. ESLint - Real-time linting
  5. 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 dev starts 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 lint executes successfully
  • npm run build creates .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 --lts

Issue: 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 3001

Issue: Module not found errors

Error: “Cannot find module ‘@/components/…’”

Solution:

# Delete node_modules and reinstall
rm -rf node_modules
rm package-lock.json
npm install

Issue: 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@latest

Next 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?

Last updated