Skip to main content

Understanding the Next.js Project Structure

4/28
Chapter 1 Next.js 15 Foundations

Understanding the Next.js Project Structure

14 min read Lesson 4 / 28

Organizing a Scalable Next.js Project

Good project structure becomes critical as applications grow. Next.js is unopinionated about organization outside of the app/ directory, so conventions matter.

my-app/
├── app/
│   ├── (auth)/
│   │   ├── login/page.tsx
│   │   └── register/page.tsx
│   ├── (dashboard)/
│   │   ├── layout.tsx
│   │   └── dashboard/page.tsx
│   ├── api/
│   │   └── posts/route.ts
│   ├── layout.tsx
│   └── page.tsx
├── components/
│   ├── ui/              # Low-level UI primitives
│   │   ├── button.tsx
│   │   └── input.tsx
│   └── posts/           # Feature-specific components
│       ├── post-card.tsx
│       └── post-list.tsx
├── lib/
│   ├── db.ts            # Database client
│   ├── auth.ts          # Auth configuration
│   └── utils.ts         # Shared utilities
├── types/
│   └── index.ts         # Shared TypeScript types
└── actions/
    └── posts.ts         # Server Actions

TypeScript Path Aliases

The @/* alias configured in tsconfig.json makes imports clean:

// Without alias (fragile relative paths)
import { Button } from '../../../components/ui/button';

// With alias (always works, regardless of file depth)
import { Button } from '@/components/ui/button';
import { db } from '@/lib/db';
import type { Post } from '@/types';

Colocation Pattern

Keep components close to where they are used. Private components that are only used on one page can live beside that page:

app/
└── dashboard/
    ├── page.tsx
    ├── _components/         # Underscore = private, not routable
    │   ├── stat-card.tsx
    │   └── recent-activity.tsx
    └── _lib/
        └── queries.ts

Type Definitions

Define shared types in one place:

// types/index.ts
export interface Post {
    id: string;
    title: string;
    slug: string;
    content: string;
    publishedAt: Date | null;
    author: Author;
}

export interface Author {
    id: string;
    name: string;
    email: string;
    avatar: string | null;
}

A well-organized project structure reduces cognitive load and makes onboarding new team members significantly faster.