Creating a Next.js project: the App Router folder structure
This series builds one real project — a blog called devnotes, with a post listing, individual post pages, a comment form, and a working sitemap — across 22 parts using Next.js's App Router, the routing system every current Next.js project is built on. By the end you'll have shipped data fetching, SEO metadata, a Route Handler, a Server Action, and a live deployment. This part is just getting a project running and understanding what got generated.
Scaffolding the project
npx create-next-app@latest devnotesThe prompts that matter for this series: TypeScript — Yes, App Router — Yes (not the older Pages Router), src/ directory — No (this series keeps app/ at the project root, matching most real projects). The rest can take their defaults.
cd devnotes
npm run devVisit http://localhost:3000 and the default starter page confirms the project runs.
What create-next-app generated
devnotes/
app/
layout.tsx
page.tsx
globals.css
public/
next.config.ts
package.json
tsconfig.jsonapp/ is the App Router itself — every file inside it that's named page.tsx, layout.tsx, or a handful of other reserved names has special meaning to Next.js, covered across the next few parts. public/ serves static files directly at the site root (public/logo.png becomes /logo.png). next.config.ts is where project-wide configuration lives — image domains, redirects, headers — largely unused until later parts need it.
app/page.tsx: the homepage
// app/page.tsx
export default function Home() {
return <h1>devnotes</h1>;
}A page.tsx file makes its folder a route, and its default export is the component Next.js renders for that route. app/page.tsx specifically maps to / — the site root — because it sits directly inside app/ with no folder in between. Part 2 covers exactly how a folder structure turns into a URL structure.
app/layout.tsx: the required root shell
// app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}Every Next.js App Router project needs exactly one root layout.tsx — it's the only place <html> and <body> are allowed to appear, since every page eventually renders inside it. children is where the matched page's own content gets inserted; part 4 goes deeper on layouts, including nested ones scoped to just part of the site.
Renaming page.tsx to something else, like index.tsx out of habit from other frameworks. Next.js's App Router only recognizes the exact reserved filename page.tsx (or .jsx) — anything else in that folder is just a regular file Next.js won't route to at all.
Next: turning a folder structure into the blog's actual routes — a post list, individual post pages, and everything in between.