Suggest an editImprove this articleRefine the answer for “How does app differ from pages in Next.js?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)In short: `app` is the **modern, powerful, and "correct" path**, `pages` is the **old, familiar, and still working** one. **Key point:** `pages` is the legacy router with data fetched through `getServerSideProps`/`getStaticProps` and no nested layouts, while `app` is the main, recommended router with Server Components by default, nested layouts, streaming, and server actions.Shown above the full answer for quick recall.Answer (EN)ImageIn short: `app` **is the modern, powerful, and "correct" path**, `pages` **is the old, familiar, and still working** one. Now let's break it down **clearly and without filler**, so it's clear *when and why*. --- ## General In **Next.js** there are **two routers**: | | `pages` | `app` | | --- | --- | --- | | Status | legacy | **main (recommended)** | | Approach | React + SPA | **React Server Components** | | Year introduced | ~2016 | **2023+** | | Future | still supported | **this is where development goes** | ### How it works ``` pages/ ├─ index.tsx → / ├─ blog.tsx → /blog └─ users/[id].tsx → /users/1 ``` ### Characteristics - everything is a **Client Component** - data through `getServerSideProps`, `getStaticProps` - no nested layouts - no streaming - no server actions - `_app.tsx`, `_document.tsx` - workarounds for globality ```ts export async function getServerSideProps() { return { props: { data } } } ``` --- ## App Router (`app/`) - the modern standard   ### How it works ``` app/ ├─ layout.tsx ├─ page.tsx → / ├─ blog/ │ └─ page.tsx → /blog └─ users/[id]/ └─ page.tsx → /users/1 ``` ### Key differences - **Server Components by default** - nested `layout.tsx` - streaming + loading states - server actions (no API) - parallel routes / slots - route groups `(auth)` - harder mentally --- ## The main architectural difference ### `pages` > **Page = component** ### `app` > **Page = tree of segments** > (layout → loading → error → page) --- ## Working with data ### `pages` ```ts getServerSideProps getStaticProps getInitialProps ``` ### `app` ```ts const data = await fetch(...) const data = await prisma.task.findMany() ``` Directly **in the component**, with no wrappers. --- ## Layouts ### `pages` - global `_app.tsx` - no nesting ### `app` ```txt app/ ├─ layout.tsx # global └─ dashboard/ └─ layout.tsx # only for /dashboard/* ``` --- ## Performance | | pages | app | | --- | --- | --- | | JS in the browser | a lot | **less** | | SSR | yes | **yes (smarter)** | | Streaming | no | **yes** | | Partial render | no | **yes** | --- ## Server Actions (killer feature of `app`) ```ts "use server"; export async function submit(formData: FormData) { await prisma.task.create(...) } ``` - no API - no fetch - type-safe - faster `pages` **does not have this**.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.