Why Folder Structure Matters
Understanding the folder structure of a Next.js project is like learning the blueprint of a building before you start decorating it. Every folder and file has a specific purpose, and knowing where things go prevents confusion as your project grows.
Let's go through every file and folder you'll find in a fresh Next.js (App Router) project.
Full Project Tree
When you create a new Next.js app with create-next-app, here's what you get:
my-nextjs-app/
│
├── app/ ← Core App Router directory
│ ├── favicon.ico ← Browser tab icon
│ ├── globals.css ← Global CSS styles
│ ├── layout.tsx ← Root layout (wraps all pages)
│ └── page.tsx ← Homepage ( / route)
│
├── public/ ← Static files (images, fonts, etc.)
│ ├── next.svg
│ └── vercel.svg
│
├── node_modules/ ← All installed dependencies (don't touch!)
│
├── .eslintrc.json ← ESLint configuration
├── .gitignore ← Files Git should ignore
├── next.config.mjs ← Next.js configuration
├── package.json ← Project metadata & scripts
├── package-lock.json ← Locked dependency versions
├── postcss.config.mjs ← PostCSS config (used by Tailwind)
├── README.md ← Project documentation
└── tailwind.config.ts ← Tailwind CSS configuration
The app/ Directory — The Heart of Your App
This is where all your pages, layouts, and components live in Next.js 13+ (App Router).
app/page.tsx — Your Homepage
This file renders at the root route /.
// app/page.tsx
export default function Home() {
return (
<main>
<h1>Welcome to My App</h1>
</main>
);
}
Rule: Every page.tsx file inside app/ automatically becomes a route!
app/page.tsx → /
app/about/page.tsx → /about
app/blog/page.tsx → /blog
app/blog/[slug]/page.tsx → /blog/:slug (dynamic)
app/layout.tsx — The Root Layout
This is the master wrapper that wraps around every page. It's the perfect place for:
- Navigation bars
- Footers
- Font imports
- Global metadata (title, description)
// app/layout.tsx
import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import './globals.css';
const inter = Inter({ subsets: ['latin'] });
export const metadata: Metadata = {
title: 'My Next.js App',
description: 'Built with Next.js',
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className={inter.className}>
{children} {/* ← Every page renders here */}
</body>
</html>
);
}
Think of layout.tsx like a picture frame — it stays constant while the {children} (page content) changes as you navigate.
app/globals.css — Global Styles
Contains CSS that applies to the entire app. Typically includes Tailwind's base directives:
/* app/globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Your custom global styles below */
body {
margin: 0;
font-family: sans-serif;
}
app/favicon.ico — Browser Tab Icon
Replace this file with your own .ico or .png file to customize the browser tab icon.
The public/ Directory — Static Assets
Anything placed in public/ is directly accessible via URL without importing it.
public/
├── logo.png → accessible at /logo.png
├── hero-image.jpg → accessible at /hero-image.jpg
└── fonts/
└── custom.woff2 → accessible at /fonts/custom.woff2
Example Usage in Code:
// Using an image from /public
<img src="/logo.png" alt="Logo" />
// Or with next/image (recommended)
import Image from 'next/image';
<Image src="/logo.png" alt="Logo" width={200} height={50} />
Never put sensitive data in public/. It's 100% publicly accessible.
package.json — Project Manifest
This file is the identity card of your Node.js project.
{
"name": "my-nextjs-app",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"next": "14.1.0",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"typescript": "^5",
"@types/node": "^20",
"@types/react": "^18",
"tailwindcss": "^3",
"eslint": "^8"
}
}
| Section | Purpose |
|---|
scripts | Commands you run with npm run <name> |
dependencies | Packages needed in production |
devDependencies | Packages only needed during development |
next.config.mjs — Next.js Configuration
Customize Next.js behavior here — image domains, redirects, environment variables, and more.
// next.config.mjs
const nextConfig = {
images: {
domains: ['images.unsplash.com', 'res.cloudinary.com'],
},
// Add more config as needed
};
export default nextConfig;
tailwind.config.ts — Tailwind CSS Config
Extend Tailwind's default theme — add custom colors, fonts, spacing, etc.
// tailwind.config.ts
import type { Config } from 'tailwindcss';
const config: Config = {
content: [
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
'./app/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {
colors: {
brand: '#6366f1', // Your custom brand color
},
},
},
plugins: [],
};
export default config;
.gitignore — Files Git Won't Track
These files/folders are automatically excluded from version control:
# dependencies
/node_modules
# next.js build output
/.next/
/out/
# environment variables (NEVER commit these!)
.env
.env.local
.env.production
Always add .env.local to .gitignore — it contains secret keys that should never be public.
The .next/ Folder (Auto-Generated)
When you run npm run dev or npm run build, Next.js creates a .next/ folder. This is the compiled output of your app.
.next/
├── cache/ ← Build cache for faster rebuilds
├── server/ ← Server-side rendering output
├── static/ ← Optimized static assets
└── types/ ← Auto-generated TypeScript types
Never edit files in .next/ — it's regenerated every build. Always listed in .gitignore.
Growing Your Project — Common Conventions
As your app grows, you'll add more folders inside app/:
app/
├── (marketing)/ ← Route group (doesn't affect URL)
│ ├── page.tsx → /
│ └── about/page.tsx → /about
├── (dashboard)/
│ ├── layout.tsx ← Dashboard-specific layout
│ └── dashboard/page.tsx → /dashboard
├── api/ ← API routes
│ └── users/route.ts → /api/users
├── components/ ← Reusable UI components
│ ├── Navbar.tsx
│ └── Footer.tsx
├── lib/ ← Utility functions, DB connections
│ └── db.ts
└── types/ ← TypeScript type definitions
└── index.ts
Watch the Folder Structure Walkthrough
This video by Codevolution visually walks through every file and folder in a fresh Next.js project.
Key Takeaways
app/page.tsx = homepage, every page.tsx creates a route
app/layout.tsx = wraps every page (nav, footer, fonts)
public/ = static files accessible via URL directly
package.json = project manifest, lists all dependencies
next.config.mjs = customize Next.js behavior
.next/ = auto-generated, never edit it manually
.env.local = secrets — never commit to Git!