Next.js Folder Structure Explained for Beginners
When you open a freshly scaffolded Next.js project for the first time, the folder structure can feel unfamiliar, especially if you're coming from plain React or a different framework. Files like layout.tsx, page.tsx, and folders like app/, public/, and lib/ each carry specific meaning to Next.js — they aren't arbitrary names, they're conventions the framework actively reads and reacts to.
Understanding this structure early prevents a lot of later confusion. Where you place a file directly determines whether it becomes a route, a shared layout, a static asset, or an internal utility. This lesson walks through every major folder generated by create-next-app and explains exactly what role it plays.
Learning Objectives
- Identify the purpose of every major folder in a default Next.js project.
- Understand how the app/ directory relates to routing.
- Distinguish between public/, components/, and lib/ and know what belongs where.
- Recognize special files like layout.tsx, page.tsx, and globals.css.
- Organize a growing project using conventional folder patterns.
Core Definitions
- app/: The root directory for the App Router, where folder structure maps directly to URL routes.
- public/: A folder for static assets (images, fonts, favicon) served directly at the root URL path without any processing.
- components/: A conventional (not framework-required) folder for reusable UI components shared across pages.
- lib/: A conventional folder for utility functions, API clients, or shared logic not tied to UI rendering.
- page.tsx: A special file inside app/ that marks a folder as a publicly accessible route and defines what renders for it.
- layout.tsx: A special file that defines shared UI (like a navbar or footer) wrapping a page and its nested routes.
- globals.css: A global stylesheet typically imported once in the root layout to apply site-wide styles.
Detailed Explanation
At the root of a Next.js project, you'll find configuration files like next.config.js, package.json, and tsconfig.json (if using TypeScript) — these control build behavior, dependencies, and type checking, and rarely need manual editing when starting out.
The app/ folder is the heart of routing in the App Router. Next.js reads this folder's structure to generate your site's URLs. A folder named app/about/ with a page.tsx file inside becomes accessible at yoursite.com/about. The root app/page.tsx becomes your homepage at yoursite.com/. This is called file-based routing, and it means you rarely write manual route configuration — the folder structure IS the routing configuration.
Alongside page.tsx, you'll often see layout.tsx. A layout wraps its page and any nested pages with shared UI, such as a navigation bar or footer, without re-rendering that shared UI on every navigation — this is one of the App Router's key performance advantages over the older Pages Router.
The public/ folder holds static files — images, fonts, robots.txt, favicon.ico — that Next.js serves directly at the root URL without any transformation. A file at public/logo.png is accessible directly at yoursite.com/logo.png.
components/ and lib/ are not required by Next.js itself — the framework doesn't look for these folders specifically — but they're strong community conventions. components/ holds reusable UI pieces like buttons, cards, and modals that get imported into pages. lib/ holds non-UI logic: database connection helpers, API request functions, formatting utilities, and constants. Keeping this separation makes projects easier to navigate as they grow.
Diagram Description
Visualize a folder tree:
my-app/
├── app/
│ ├── layout.tsx (shared layout wrapping all pages)
│ ├── page.tsx (homepage → '/')
│ ├── globals.css (global styles)
│ └── about/
│ └── page.tsx (about page → '/about')
├── public/
│ ├── logo.png (→ served at '/logo.png')
│ └── favicon.ico
├── components/
│ ├── Navbar.tsx
│ └── Button.tsx
├── lib/
│ ├── db.ts
│ └── formatDate.ts
├── next.config.js
├── package.json
└── tsconfig.json
Comparison Table
| Folder / File | Required by Next.js? | Purpose |
|---|---|---|
| app/ | Yes (App Router) | Defines routes via folder structure; holds pages and layouts |
| app/page.tsx | Yes, per route | Marks a folder as a visitable route and defines its content |
| app/layout.tsx | Yes, at root | Shared UI wrapping a page and its nested routes |
| public/ | Yes (convention) | Static assets served directly at the root URL |
| components/ | No (community convention) | Reusable UI components shared across pages |
| lib/ | No (community convention) | Utility functions, API clients, shared non-UI logic |
| next.config.js | Yes | Project-wide configuration for builds, images, redirects, etc. |
Next.js Practical Example
// app/layout.tsx — shared layout wrapping every page
import './globals.css';
import Navbar from '@/components/Navbar';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<Navbar />
{children}
</body>
</html>
);
}
// app/page.tsx — homepage content
export default function HomePage() {
return <h1>Welcome Home</h1>;
}
// app/about/page.tsx — becomes accessible at /about
export default function AboutPage() {
return <h1>About Us</h1>;
}
// components/Navbar.tsx — a reusable component, not a route
export default function Navbar() {
return (
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
);
}
RootLayout in app/layout.tsx wraps every page in the app with a shared Navbar and imports the global stylesheet once. Because layout.tsx wraps children, both HomePage (app/page.tsx) and AboutPage (app/about/page.tsx) automatically render inside this shared shell without needing to import the Navbar themselves. Note that Navbar.tsx lives in components/, not app/ — placing it inside app/ would risk Next.js treating its folder as a route, whereas components/ is purely for import, with no routing behavior attached.
Industry Examples
- E-commerce sites organize app/ into folders like app/products/[id]/ for dynamic product pages, while keeping reusable elements like ProductCard and PriceTag in components/.
- SaaS dashboards keep API request logic and authentication helpers in lib/ (e.g., lib/api.ts, lib/auth.ts) separate from UI code in components/ and app/.
- Marketing agencies keep all brand assets — logos, hero images, downloadable PDFs — inside public/ so they're directly linkable without any build processing.
- Content-heavy sites like blogs and documentation platforms use nested app/ folders such as app/blog/[slug]/ to map cleanly to their content structure.
- Large teams enforce folder conventions like components/ui/ for design-system primitives and components/features/ for feature-specific components, layered on top of Next.js's own app/ routing convention.
Interview Questions and Answers
Q1. What determines the URL routes in a Next.js App Router project?
The folder structure inside the app/ directory directly determines routes. A folder app/contact/ containing a page.tsx file becomes accessible at /contact. This is called file-based routing, and no manual route configuration file is required.
Q2. What is the difference between page.tsx and layout.tsx?
page.tsx defines the unique content for a specific route and makes that folder publicly accessible as a URL. layout.tsx defines shared UI, like navigation or footers, that wraps a page and all of its nested routes without re-rendering on every navigation.
Q3. What is the public/ folder used for, and how are its files accessed?
The public/ folder stores static assets like images, fonts, and favicons that Next.js serves directly at the root URL without processing. A file at public/logo.png is accessed directly at /logo.png in the browser, without needing to reference the public/ prefix.
Q4. Are components/ and lib/ required by Next.js?
No, neither folder is a Next.js convention that the framework specifically looks for. They are widely adopted community conventions: components/ for reusable UI pieces and lib/ for non-UI utility logic, kept separate from the routing-sensitive app/ directory.
Q5. What would happen if you placed a component file directly inside the app/ directory instead of components/?
If the file follows a special naming convention like page.tsx, layout.tsx, or route.ts within its own folder, Next.js may treat it as part of routing. Regular non-special-named files inside app/ subfolders are generally fine, but the strong convention is to keep purely reusable UI outside app/ in components/ to avoid ambiguity and keep routing folders clean.
MCQs With Answers
1. Which folder determines the URL routes of a Next.js App Router project?
- public/
- components/
- app/
- lib/
Answer: C. app/
Explanation: The app/ directory's folder structure is read directly by Next.js to generate routes; each folder with a page.tsx becomes an accessible URL.
2. A file at public/banner.jpg is accessible in the browser at:
- /public/banner.jpg
- /banner.jpg
- /static/banner.jpg
- /assets/banner.jpg
Answer: B. /banner.jpg
Explanation: Files inside public/ are served directly at the root URL path, so public/banner.jpg is accessed at /banner.jpg without the 'public' prefix.
3. What is the role of layout.tsx in the App Router?
- Defines a unique page's content
- Provides shared UI wrapping a page and its nested routes
- Stores static images
- Configures the build process
Answer: B. Provides shared UI wrapping a page and its nested routes
Explanation: layout.tsx wraps a page and any nested routes with shared UI, like a navbar, without re-rendering that shared UI on every navigation.
4. Which folder is a community convention rather than a Next.js routing requirement?
- app/
- components/
- app/page.tsx
- app/layout.tsx
Answer: B. components/
Explanation: components/ is not read by Next.js for routing purposes; it's a widely adopted convention for organizing reusable UI, unlike app/ which directly powers routing.
5. What makes a folder inside app/ publicly accessible as a route?
- Adding any .tsx file inside it
- Adding a page.tsx file inside it
- Adding it to next.config.js
- Naming the folder 'route'
Answer: B. Adding a page.tsx file inside it
Explanation: A folder only becomes an accessible route when it contains a page.tsx file; folders without one are not directly visitable URLs.
Common Mistakes to Avoid
- Placing static images inside components/ or app/ instead of public/, causing them to not be served correctly at a direct URL.
- Assuming components/ and lib/ are special Next.js folders the framework enforces, when they're actually just conventions.
- Forgetting that a folder inside app/ without a page.tsx file is not a visitable route, even if it contains other files.
- Duplicating the Navbar or Footer inside every page instead of placing it once in layout.tsx.
- Referencing public/ in the file path when linking assets, e.g. writing /public/logo.png instead of the correct /logo.png.
Interview Notes
- app/ is read directly by Next.js for routing; its folder structure maps to URL paths.
- page.tsx makes a folder a visitable route; layout.tsx provides shared wrapping UI without re-rendering on navigation.
- public/ serves static files directly at the root URL, without a 'public' prefix in the path.
- components/ and lib/ are community conventions, not Next.js requirements, for organizing UI and utility code respectively.
- Root-level config files like next.config.js, package.json, and tsconfig.json control build and project-wide settings.
Key Takeaways
- Next.js's app/ folder is not just organizational — its structure directly generates your site's routes.
- layout.tsx and page.tsx are special, framework-recognized files with distinct responsibilities: shared wrapping UI versus unique page content.
- public/ is the only place for assets meant to be served at a direct, unprocessed URL.
- components/ and lib/ keep reusable UI and utility logic cleanly separated from routing-sensitive app/ code, a pattern that scales well as projects grow.
Summary
The default Next.js project structure is built around meaningful conventions rather than arbitrary folder names. The app/ directory directly powers routing through file-based routing, where page.tsx marks a route and layout.tsx defines shared wrapping UI. The public/ folder serves static assets directly at the root URL. components/ and lib/, while not enforced by Next.js itself, are strong community conventions for organizing reusable UI and utility logic respectively. Understanding what each folder does — and doesn't do — is essential before building out routes and features in later lessons.