Next.js

Setting Up a Next.js Project

20 min Lesson 2 of 40

Prerequisites

Before we create our first Next.js project, ensure you have the following installed on your computer:

  • Node.js: Version 16.8 or later (check with node --version)
  • npm or yarn: npm comes with Node.js, or you can install yarn separately
  • Code Editor: Visual Studio Code is highly recommended
  • Terminal: Command line interface (Terminal on Mac/Linux, Command Prompt or PowerShell on Windows)
Pro Tip: If you don't have Node.js installed, download it from nodejs.org. The LTS (Long Term Support) version is recommended for most users.

Creating Your First Next.js Project

Next.js provides a command-line tool called create-next-app that sets up everything automatically. This is the recommended way to create a new Next.js application.

Using create-next-app

Open your terminal and run one of the following commands:

# Using npx (comes with npm)
npx create-next-app@latest my-next-app

# Using yarn
yarn create next-app my-next-app

# Using pnpm
pnpm create next-app my-next-app

The @latest flag ensures you're using the latest version of create-next-app. Replace "my-next-app" with whatever you want to name your project.

Interactive Setup

After running the command, you'll be prompted with several questions to configure your project:

✔ Would you like to use TypeScript? › No / Yes
✔ Would you like to use ESLint? › No / Yes
✔ Would you like to use Tailwind CSS? › No / Yes
✔ Would you like to use `src/` directory? › No / Yes
✔ Would you like to use App Router? (recommended) › No / Yes
✔ Would you like to customize the default import alias? › No / Yes

Let's understand each option:

  • TypeScript: Adds type safety to your JavaScript code (recommended for larger projects)
  • ESLint: Helps catch errors and enforce code style (highly recommended)
  • Tailwind CSS: A utility-first CSS framework (optional, based on preference)
  • src/ directory: Organizes your code in a separate src folder (recommended for larger projects)
  • App Router: The new routing system introduced in Next.js 13+ (recommended)
  • Import alias: Allows you to use custom import paths like @/components instead of ../components
For Beginners: If you're just starting out, we recommend answering "No" to TypeScript and Tailwind CSS, but "Yes" to ESLint and App Router. You can always add these features later.

Starting the Development Server

Once the installation is complete, navigate into your project directory and start the development server:

# Navigate to project directory
cd my-next-app

# Start the development server
npm run dev
# or
yarn dev
# or
pnpm dev

You should see output similar to this:

  ▲ Next.js 14.1.0
  - Local:        http://localhost:3000
  - Network:      http://192.168.1.5:3000

✓ Ready in 2.3s

Open your browser and navigate to http://localhost:3000. You should see the Next.js welcome page!

Hot Reload: The development server supports Fast Refresh, meaning any changes you make to your code will automatically appear in the browser without needing to manually refresh the page.

Understanding the Project Structure

Let's explore the files and folders that create-next-app generated for us. The structure depends on whether you chose the App Router or Pages Router:

App Router Project Structure (Next.js 13+)

my-next-app/
├── app/
│   ├── favicon.ico
│   ├── globals.css
│   ├── layout.js
│   └── page.js
├── public/
│   ├── next.svg
│   └── vercel.svg
├── node_modules/
├── .eslintrc.json
├── .gitignore
├── jsconfig.json
├── next.config.js
├── package.json
└── README.md

Key Files and Folders Explained

1. app/ Directory

This is where all your application code lives when using the App Router:

  • layout.js: The root layout that wraps all pages. Contains the HTML structure and global elements
  • page.js: The homepage component. This file represents the root route (/)
  • globals.css: Global CSS styles that apply to your entire application
  • favicon.ico: The small icon that appears in browser tabs
// app/page.js - Example homepage
export default function Home() {
  return (
    <main>
      <h1>Welcome to Next.js!</h1>
    </main>
  )
}
// app/layout.js - Root layout
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}

2. public/ Directory

Static files that can be served directly. Files in this folder are accessible from the root URL:

  • Images, fonts, and other static assets go here
  • Files are served at the root path, e.g., public/logo.png becomes /logo.png
  • Never put sensitive information here—everything is publicly accessible
Important: Don't name files in the public/ directory the same as files in your app/ or pages/ directory, as this can cause conflicts.

3. node_modules/

Contains all your project dependencies. This folder is automatically generated when you run npm install and should never be edited manually or committed to version control.

4. Configuration Files

package.json: The heart of your Node.js project. Contains metadata about your project and lists all dependencies.

{
  "name": "my-next-app",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "next": "14.1.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  }
}

next.config.js: Configuration file for customizing Next.js behavior. Initially mostly empty, but can be extended with many options.

/** @type {import('next').NextConfig} */
const nextConfig = {}

module.exports = nextConfig

.eslintrc.json: ESLint configuration for code quality checks.

.gitignore: Tells Git which files to ignore (like node_modules and .next).

jsconfig.json or tsconfig.json: Configures JavaScript/TypeScript compiler options and path aliases.

Understanding package.json Scripts

The scripts section in package.json defines commands you can run with npm run:

Development Script

npm run dev

Starts the development server with Fast Refresh. Use this while developing your application. The server watches for file changes and automatically reloads.

Build Script

npm run build

Creates an optimized production build of your application. This command:

  • Compiles your code
  • Optimizes assets
  • Generates static pages (if using SSG)
  • Creates a production-ready .next folder

Start Script

npm run start

Starts the production server. You must run npm run build before using this command. Use this to test your production build locally.

Lint Script

npm run lint

Runs ESLint to check your code for potential errors and style issues.

Development Workflow: While developing, keep npm run dev running in one terminal. When you're ready to deploy, run npm run build to create the production build, then test it with npm run start.

The .next Directory

After running npm run dev or npm run build, you'll notice a new .next folder appears. This is Next.js's build output directory:

  • Contains compiled and optimized code
  • Should never be edited manually
  • Automatically added to .gitignore
  • Can be deleted and regenerated at any time

Creating Your First Custom Page

Let's modify the homepage to create something custom. Open app/page.js and replace the content with:

export default function Home() {
  return (
    <main style={{ padding: '2rem' }}>
      <h1>Hello Next.js!</h1>
      <p>This is my first Next.js application.</p>
      <button onClick={() => alert('Welcome!')}>
        Click Me
      </button>
    </main>
  )
}

Save the file and watch your browser automatically update with the new content. That's Fast Refresh in action!

Adding Global Styles

You can modify global styles in app/globals.css. This file is imported in your root layout and applies to all pages:

/* app/globals.css */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: system-ui, -apple-system, sans-serif;
  background-color: #f5f5f5;
  color: #333;
}

h1 {
  color: #0070f3;
}

Installing Additional Packages

You can install additional npm packages anytime using npm, yarn, or pnpm:

# Install a package
npm install package-name

# Install as dev dependency
npm install --save-dev package-name

# Uninstall a package
npm uninstall package-name

For example, to add the popular date library date-fns:

npm install date-fns

Environment Variables

Next.js has built-in support for environment variables. Create a .env.local file in your project root:

# .env.local
API_URL=https://api.example.com
NEXT_PUBLIC_SITE_NAME=My Next.js App
Important: Environment variables prefixed with NEXT_PUBLIC_ are exposed to the browser. Variables without this prefix are only available on the server side.

Access environment variables in your code:

// Server-side only
const apiUrl = process.env.API_URL

// Available in browser too
const siteName = process.env.NEXT_PUBLIC_SITE_NAME
Security Warning: Never expose sensitive information (API keys, database passwords) using the NEXT_PUBLIC_ prefix. These variables are embedded in the browser bundle and visible to anyone.

Common Development Commands

Here are some useful commands you'll use frequently:

# Clear Next.js cache (if you encounter issues)
rm -rf .next

# Clear node_modules and reinstall (fixes many dependency issues)
rm -rf node_modules package-lock.json
npm install

# Update Next.js to latest version
npm install next@latest react@latest react-dom@latest

# Check for outdated packages
npm outdated

Troubleshooting Common Issues

Port Already in Use

If port 3000 is already taken, you can specify a different port:

npm run dev -- -p 3001

Module Not Found Errors

If you get module not found errors, try:

  1. Delete node_modules and package-lock.json
  2. Run npm install again
  3. Restart your development server

Fast Refresh Not Working

If changes aren't reflecting automatically:

  • Check for syntax errors in your code
  • Ensure you're editing files inside the app/ or pages/ directory
  • Try stopping and restarting the dev server
Practice Exercises:
  1. Create a new Next.js project using create-next-app with your preferred settings
  2. Start the development server and view your application in the browser
  3. Modify the homepage to display your name and a brief introduction
  4. Add some custom styles to globals.css and see them applied
  5. Create a .env.local file with a NEXT_PUBLIC_WELCOME_MESSAGE variable and display it on your page
  6. Install a package like date-fns and use it to display the current date
  7. Run npm run build to create a production build and test it with npm run start

Summary

In this lesson, you learned how to set up a Next.js project from scratch using create-next-app. We explored the project structure, understanding each file and folder's purpose. You learned about the package.json scripts for development, building, and starting your application. We also covered how to customize your project, add global styles, install packages, and use environment variables.

With your development environment ready, you're now prepared to start building with Next.js. In the next lesson, we'll dive deep into Next.js's file-based routing system and learn how to create multiple pages in your application.