Next.jsBeginner8 min readUpdated

Next.js Folder Structure Explained for Beginners

By Mudassir Khan — Agentic AI Consultant & AI Systems Architect, Islamabad, Pakistan

Cover illustration for: Next.js Folder Structure Explained for Beginners

Section 01 · The tour

What every file in a fresh Next.js app does

If you just ran create-next-app and opened the folder in your editor, this is the map.

Quick answer

What is the Next.js folder structure? A Next.js project is built around the app folder. Folders inside app/ become URL routes. Each route has a page.tsx (the visible page) and optionally a layout.tsx (wraps the page with shared UI), loading.tsx (shown while data loads), and error.tsx (shown if something throws). Static files live in public/. Config files like next.config.js sit at the root.

Open the project you generated in the previous post. You will see a tree that looks roughly like this:

bash
my-first-app/
├── app/                  ← your pages and layouts live here
│   ├── favicon.ico
│   ├── globals.css       ← Tailwind directives + global styles
│   ├── layout.tsx        ← root layout (wraps every page)
│   └── page.tsx          ← the home page at /
├── public/               ← static assets served as is
│   ├── next.svg
│   └── vercel.svg
├── node_modules/         ← installed packages (do not edit)
├── .gitignore
├── eslint.config.mjs
├── next.config.ts        ← Next.js configuration
├── next-env.d.ts         ← auto generated, do not edit
├── package.json          ← dependencies and scripts
├── postcss.config.mjs    ← required by Tailwind
├── README.md
├── tailwind.config.ts
└── tsconfig.json         ← TypeScript config
Folder tree showing app, public, and config files of a fresh Next.js project.
Three buckets: code (app), static assets (public), and configuration at the root.

Section 02 · The app folder

The app folder is where you spend ninety percent of your time

Every page, every layout, every loading state, every error boundary lives here. The folder structure is the routing system.

The rule is short. A folder inside app/ becomes a URL segment. A file named page.tsx inside that folder makes the URL render a page. That is it.

bash
app/page.tsx                  →  /
app/about/page.tsx            →  /about
app/blog/page.tsx             →  /blog
app/blog/[slug]/page.tsx      →  /blog/anything-here
app/dashboard/settings/page.tsx → /dashboard/settings

The square brackets around [slug] mark a dynamic segment. Anything the user types in that part of the URL is passed to your page component as a prop. That is how you build blog posts, product pages, user profiles, and anything else with a variable URL.

No route configuration file

Other frameworks (React Router, plain Express, even old Next.js with the Pages Router) make you write a routes table. App Router throws that away. The folder structure IS the routes table. Rename a folder and you rename the URL.

Section 03 · Special files

The reserved file names you need to know

Next.js looks for files with specific names inside every route folder. These are the ones worth memorising.

Special files Next.js recognises inside any folder under app/.
File nameWhat it doesWhen you write it
page.tsxMakes the folder a visitable URL. Renders the page body.Every route you want users to visit.
layout.tsxWraps every page in this folder (and child folders) with shared UI: header, footer, nav.Once per section that shares chrome.
loading.tsxShown automatically while the page is fetching data on the server.Any route with slow data.
error.tsxCatches uncaught errors thrown by the page and shows a fallback UI.Production apps with real users.
not-found.tsxRenders when a dynamic route cannot find the requested resource.Dynamic routes like blog posts or product pages.
template.tsxLike layout, but a fresh instance is created on every navigation.Rarely. Use layout unless you need this.
route.tsDefines an HTTP endpoint instead of a page. Returns JSON, not JSX.API routes.

The most important pair is layout.tsx and page.tsx. Every Next.js app has a root layout at app/layout.tsx that wraps every page. It is also where you set the <html> and <body> tags. You cannot remove it.

tsx
// app/layout.tsx — wraps every page in the app
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <nav>{/* shared nav */}</nav>
        {children}
        <footer>{/* shared footer */}</footer>
      </body>
    </html>
  );
}

Section 04 · Server vs Client

Server Components vs Client Components, in plain English

This is the one Next.js concept that trips up everyone. Get it right once and you never have to think about it again.

Every component inside the app/ folder is a Server Component by default. That means it runs on the server, fetches data directly, and ships zero JavaScript to the browser.

tsx
// app/page.tsx — a Server Component (default)
export default async function HomePage() {
  // This fetch runs on the server, not the browser.
  const posts = await fetch("https://api.example.com/posts").then((r) => r.json());

  return (
    <main>
      {posts.map((p: any) => (
        <article key={p.id}>{p.title}</article>
      ))}
    </main>
  );
}

A Server Component cannot use useState, useEffect, browser APIs, or onClick. The moment you need any of those, you need a Client Component. You make one by writing the string "use client" as the very first line of the file:

tsx
"use client";

import { useState } from "react";

// app/components/counter.tsx — a Client Component
export function Counter() {
  const [count, setCount] = useState(0);
  return (
    <button onClick={() => setCount(count + 1)}>
      Clicked {count} times
    </button>
  );
}
Diagram showing a Server Component on the server passing data to a Client Component that runs in the browser.
The server fetches data and renders. The client takes over for anything interactive.

A simple rule that works

Default to Server Components. Only add 'use client' when you need state, an event handler, or a browser only API. The Server Component can still render a Client Component inside it; the boundary just needs to be clear.

Section 05 · public folder

The public folder: where images and static files live

Anything in here is served as a static file at the root of your site.

Drop an image at public/logo.png and it is reachable at /logo.png in the browser. You do not import it; you reference the URL directly:

tsx
import Image from "next/image";

export default function Header() {
  return (
    <Image src="/logo.png" alt="Company logo" width={120} height={40} />
  );
}

The <Image> component is the recommended way to use images. It handles lazy loading, responsive sizing, and modern formats (AVIF, WebP) for you. For SVG and favicons, a plain <img> tag is fine.

Section 06 · Config

The config files at the root, briefly

You do not need to touch most of these on day one. Knowing what each is for stops them from being intimidating later.

Root level config files in a fresh Next.js app.
FilePurposeEdit often?
package.jsonLists your dependencies and scripts (dev, build, start, lint).Yes, every time you add a library.
next.config.tsNext.js configuration. Image domains, redirects, custom Webpack, env, experimental flags.Sometimes.
tsconfig.jsonTypeScript compiler config. Path aliases, strictness, target.Rarely.
tailwind.config.tsTailwind theme, plugins, content paths.When you customise the design system.
eslint.config.mjsESLint rules and plugins.Almost never on day one.
postcss.config.mjsRequired so Tailwind's PostCSS plugin runs at build time.No.
.gitignoreFiles Git should not track (node_modules, .next, .env).When you add new build artefacts.
next-env.d.tsAuto generated TypeScript references for Next.js types.Never. It is regenerated.

Section 07 · Route grouping

Two patterns you will use as the app grows

Route groups and private folders are the two App Router conventions worth learning before you build a second page.

Route groups: folder names in (parentheses)

A folder wrapped in parentheses is not part of the URL. Use this to group related routes that share a layout without affecting the path. app/(marketing)/about/page.tsx still renders at /about, but you can give the (marketing) folder its own layout.tsx that wraps every marketing page.

Private folders: names starting with _

A folder whose name starts with an underscore is invisible to the router. Use it for component files that should live near a route but should not become a URL. app/dashboard/_components/chart.tsx is a perfect home for a chart used only on the dashboard.

You will pick up dynamic routes ([slug]), catch all routes ([...slug]), parallel routes (@modal), and intercepting routes when you need them. You do not need them on day one. The patterns above cover the first ten or twenty pages of almost any project.

Section 08 · Next steps

What to build first

The fastest way to lock in this mental model is to build something tiny.

Open the next post in this series, Build a Calculator in Next.js Step by Step. You will create a new route, write your first Client Component, and put the folder structure rules above to work in under an hour. After that, the form tutorial shows the same patterns applied to the most common UI in any web app.

If you are evaluating Next.js for a larger build, the agentic AI consulting service covers how production Next.js apps are scoped, including which folder patterns scale and which break the moment you have a real team.

Section 09 · Questions

Frequently asked questions

The common questions beginners ask about App Router and the project layout.

What is the difference between App Router and Pages Router?

App Router is the new system based on the app folder, with Server Components by default. Pages Router is the older system based on the pages folder, with Client Components by default. Pages Router still works but is in maintenance mode. Every new Next.js tutorial assumes App Router.

Can I have both app and pages folders in the same project?

Yes, Next.js supports both at once for migration. In practice, do not start a new project with both. Pick App Router and stay there.

Where do I put my reusable components?

Two common patterns work. Put global components in a components folder next to app at the root, like src/components/. Put route specific components inside the route folder using the _components private folder convention. Both are valid.

Why does the page show 'Hydration failed' sometimes?

It means the HTML the server rendered does not match what the client tried to render. The usual cause is using a browser API like Date.now or Math.random in a Server Component without guarding it. Move that code into a Client Component or compute it deterministically.

Do I have to use TypeScript with Next.js?

No, but you should. The whole ecosystem is typed, error messages are clearer, and refactoring is far safer. The cost of learning TypeScript on day one is small; the cost of switching to it later is huge.

Written by Mudassir Khan

Agentic AI consultant and AI systems architect based in Islamabad, Pakistan. CEO of Cube A Cloud. 38+ agentic AI launches delivered for global founders and CTOs.

View agentic AI consulting service

Related service

Agentic AI Consulting

See scope & pricing →

More on this topic

Need an AI systems architect?

Book a 30-minute architecture call. I will sketch the high-level design for your use case and give you an honest view of the trade-offs.

Book a strategy call →