Learning Next.js - Starting a Next.js Project
Episode 3 of 24

Learning Next.js - Starting a Next.js Project

This episode guides you through creating your first Next.js project with create-next-app, understanding the basic folder structure, running the development server with hot reload, and setting up TypeScript, ESLint, and lint-staged for code quality from the start.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Enough theory from episodes 1 and 2 — now it's time to put your hands on the keyboard. Episode 3 guides you through creating your first Next.js project from scratch: using create-next-app, understanding the generated folder structure, running the development server, and setting up code quality with TypeScript, ESLint, and lint-staged.

You'll reuse this pattern over and over — for personal projects, work, and open-source contributions. After this episode, you'll have a clean project foundation ready to grow in the episodes that follow.

Creating a Project with create-next-app

The Command and Flags

The official and easiest way is to use create-next-app. The following command creates a project named aplikasi-ku with TypeScript, ESLint, App Router, Tailwind, and an import alias:

Create a Next.js project
npx create-next-app@latest aplikasi-ku \
  --typescript \
  --eslint \
  --tailwind \
  --app \
  --src-dir \
  --import-alias "@/*"

Read the interactive output carefully: questions like Turbopack and React Compiler can be answered as needed. The command npx create-next-app@latest automatically grabs the latest version from npm, so without @latest you risk using a cached older version.

Verifying the Scaffold

When it finishes, enter the project folder and start the development server:

Run the development server
cd aplikasi-ku
npm run dev

The development server will run at http://localhost:3000. Open that address in your browser — you'll see the Next.js welcome page. Press Ctrl + C in the terminal to stop the server.

Basic Folder Structure

Project File Map

The scaffolded App Router structure looks like this:

Next.js project structure
aplikasi-ku/
  app/
    globals.css
    layout.tsx
    page.tsx
  public/
  components/
  next.config.mjs
  package.json
  tsconfig.json
  eslint.config.mjs
  • app/page.tsx is the main page at /.
  • app/layout.tsx is the root layout of the whole application.
  • app/globals.css holds global styles and Tailwind directives.
  • public/ holds static assets like images and the favicon.
  • next.config.mjs is the center of framework configuration.
  • tsconfig.json and eslint.config.mjs manage TypeScript and linting.

The components/ folder may not exist in the basic scaffold; you can create it yourself to hold shared components.

Scripts in package.json

Open package.json and look at the scripts section:

Scripts in package.json
"scripts": {
  "dev": "next dev",
  "build": "next build",
  "start": "next start",
  "lint": "next lint"
}

npm run dev starts the development server, npm run build creates a production build, npm run start runs the built output, and npm run lint checks code quality.

Running the Development Server

Hot Reload and Fast Refresh

The main advantage of the development server is fast refresh: when you change a file, only the changed component is updated in the browser without a full page reload, and local state is preserved. Try changing the text in app/page.tsx and saving — the change appears instantly at http://localhost:3000 without manual refresh.

Hot reload only applies in development mode. In a production build, code changes require a rebuild. This is why production workflows always involve a CI/CD pipeline — the topic of episode 19.

TypeScript, ESLint, and lint-staged

TypeScript and ESLint

The create-next-app scaffold already configures TypeScript in strict mode and ESLint with built-in Next.js rules. Verify that both work:

Type checking and linting
npx tsc --noEmit
npm run lint

If there are no errors, your project is healthy. npx tsc --noEmit checks types without producing JavaScript files, while npm run lint catches code pattern issues.

Pre-commit with lint-staged

In real projects, quality rules run automatically before a commit using husky and lint-staged. Install both tools:

Install husky and lint-staged
npm install --save-dev husky lint-staged
npx husky init

Configure lint-staged in package.json so only staged files are checked:

lint-staged configuration
"lint-staged": {
  "*.ts": "eslint --fix",
  "*.tsx": "eslint --fix"
}

With this configuration, every time you run git commit, ESLint automatically checks and fixes the TypeScript files included in the commit — preventing dirty code from entering history.

Closing

Here's what to take away:

  • create-next-app creates a complete project with one command.
  • The App Router produces the app, public, and config file structure.
  • The development server provides fast refresh for quick feedback.
  • TypeScript, ESLint, and lint-staged keep quality high from the start.
  • Verify project health with tsc and lint regularly.
  • Know the dev, build, start, and lint scripts in package.json.

In the next episode, episode 4, we'll discuss routing and navigation — how the App Router determines URLs, how to create dynamic routes and catch-all routes, navigating between pages with the Link component, and the metadata API for SEO. Your project will start having more than one page.