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.

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.
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:
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.
When it finishes, enter the project folder and start the development server:
cd aplikasi-ku
npm run devThe 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.
The scaffolded App Router structure looks like this:
aplikasi-ku/
app/
globals.css
layout.tsx
page.tsx
public/
components/
next.config.mjs
package.json
tsconfig.json
eslint.config.mjsapp/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.
Open package.json and look at the scripts section:
"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.
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.
The create-next-app scaffold already configures TypeScript in strict mode and ESLint with built-in Next.js rules. Verify that both work:
npx tsc --noEmit
npm run lintIf 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.
In real projects, quality rules run automatically before a commit using husky and lint-staged. Install both tools:
npm install --save-dev husky lint-staged
npx husky initConfigure lint-staged in package.json so only staged files are checked:
"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.
Here's what to take away:
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.