Handbooks / Next.js / Chapter 1
Project Setup and TypeScript
7 pages · ~5 min✓ Reviewed
Start here. Next up: Server and Client Components.
Next.js Project Setup Overview
1. What create-next-app Does
- create-next-app is the official scaffolder
- Generates
package.json, config files, starterapp/ - Then installs dependencies
routes and UI
framework behaviour
types and aliases
runtime values
2. Mental Model
- The folder tree under app/ IS the routing table
- Config files only tune how it is built and served
- Never read non-public env vars in Client Components
3. Scripts
| Script | Does |
|---|---|
npm run dev | hot-reload server |
npm run build | production build |
npm run start | serves the build |
npm run lint | runs ESLint |
- Generates? package.json, configs, starter app/; app/ routes, next.config builds
- Why folders? Each folder is a URL segment; page.tsx makes it public
- dev/build/start? Hot reload; compile for production; serve that build
start serves what build produced, so run build first.
Running create-next-app
1. Scaffold
- No name or flags → interactive prompts
- Covers TypeScript, ESLint, Tailwind,
src/, App Router, alias (default@/*) - Package manager flag sets the installer and the lockfile
npx create-next-app@latest my-app
npx create-next-app@latest my-app --ts --eslint --tailwind --src-dir --app --import-alias "@/*" --use-pnpmLine 2 skips every prompt; --js replaces --ts
| Flag | Lockfile |
|---|---|
--use-npm | package-lock.json |
--use-pnpm | pnpm-lock.yaml |
--use-yarn | yarn.lock |
--use-bun | bun.lock |
2. Run and mistakes
cd my-app && npm run dev
npm run dev -- -p 4000Serves on http://localhost:3000; -p changes the port
App Directory Structure
1. Routes and Special Files
app/is the App Router root: each folder is a URL segment- Public only with page.tsx or route.ts
public/logo.pngis served at/logo.png- Optional
src/holdsapp/; configs stay at the root
| File | Role |
|---|---|
layout.tsx | Shared shell, persists |
page.tsx | Route UI |
loading.tsx | Suspense fallback |
error.tsx | Error boundary, Client Component |
not-found.tsx | 404 UI |
2. Organising Folders
| Folder |
|---|
next.config, TypeScript and Path Aliases
1. next.config
- next.config.ts (or .js/.mjs) at the project root
- Exports an object typed
NextConfig - Read at server start: restart the dev server
import type { NextConfig } from 'next' const config: NextConfig = { typedRoutes: true, output: 'standalone', images: { remotePatterns: [{ hostname: 'cdn.site.com' }] }, } export default config
| Option | Use |
|---|---|
images.remotePatterns | allow external image hosts |
redirects() / rewrites() | async, return arrays |
output: 'standalone' | self-contained Docker build |
env, reactStrictMode | inline values, extra dev checks |
2. TypeScript and Aliases
ESLint and Environment Variables
1. ESLint Setup
eslint.config.mjsis the flat config; runnpm run lint- Extends next/core-web-vitals:
no-img-element,no-html-link-for-pages - Add next/typescript for TS rules
- Lints
app,pages,components,srcby default
...compat.extends("next/core-web-vitals", "next/typescript")
extends list
2. Env Files and Exposure
| Priority | File | Use |
|---|---|---|
| 1 | process env | shell or host |
| 2 | .env.$(NODE_ENV).local | local, per mode |
| 3 | .env.local | secrets, git-ignored, skipped in test |
| 4 |
Setup Cheat Sheet
1. Scaffold and Layout
npx create-next-app@latest my-app
npm run dev # port 3000
npm run build
npm run start
npm run lint- app/ routes, public/ static,
src/optional - Root
layout.tsxis required page.tsxmakes a route public
2. Special Files
| Name | Role |
|---|---|
layout / page | shell / route UI |
loading / error | fallback / boundary |
not-found | 404 UI |
(group) | hidden from URL |
_private | not routed |
[slug] | dynamic segment |
3. Config, TypeScript, Env
Check yourself
.env has NEXT_PUBLIC_API=a and .env.local has NEXT_PUBLIC_API=b. What does npm run dev use?
- b:
.env.localranks above.env - Order: process env,
.env.development.local,.env.local,.env.development,.env
app/blog/ holds only Post.tsx and Card.tsx. Why does /blog return 404?
- No
page.tsxorroute.ts, so the folder is not a public route - Add
app/blog/page.tsx
A Client Component runs process.env[name] with name set to "NEXT_PUBLIC_URL". Why is it undefined in the browser?
- Next.js inlines only literal reads at build time
- Write
process.env.NEXT_PUBLIC_URLdirectly, then rebuild