Learn / Frameworks / Next.js / Full-stack Project Structure

Next.js · Lesson 15 of 15

Full-stack Project Structure

Lay out a production App Router project and keep server code off the client.

  • Advanced
  • 16 min read
  • 3 objectives

Before this lessonLesson 14: Images, Fonts and Performance

What you will learn

  • Split app, components, lib
  • Mark server-only modules
  • Compose a feature folder

Your Progress

0 of 15 lessons 0%

  • Lessons0 / 15
  • Completed0
  • Est. time left~ 4 hours

Create a free account to keep your progress on every device.

A durable App Router project keeps routing in app/, reusable UI in components/, and server-only code in lib/ or colocation folders that never get imported from the client.

A layout that scales

app/
  (marketing)/          # public layout
  (app)/                # signed-in layout
    dashboard/
components/             # presentational, safe for client or server
features/
  posts/
    actions.ts          # "use server"
    queries.ts          # db reads
    ui/                 # feature-specific components
lib/
  db.ts
  auth.ts
  server-only.ts

Mark server-only modules

// lib/db.ts
import "server-only";
import { PrismaClient } from "@prisma/client";
export const db = new PrismaClient();

If a Client Component imports this file, the build fails instead of leaking secrets.

Colocate a feature

A posts feature can own its actions, queries and UI. Pages in app/ stay thin: fetch, pass props, render.

// app/posts/page.tsx
import { getPublishedPosts } from "@/features/posts/queries";
import { PostList } from "@/features/posts/ui/post-list";

export default async function Page() {
  const posts = await getPublishedPosts();
  return <PostList posts={posts} />;
}
Course completeYou finished Next.jsReview the full course or pick your next one.