Next.js vs Nest.js: One Serves Pages, One Serves APIs
Next.js renders and serves pages; Nest.js organises server-side business logic. Here's when a single Next.js app is enough — and the exact signals that mean you've outgrown it.

next.js vs nest.js trips up more planning meetings than it should. The names are two letters apart, but the jobs are different: Next.js renders and serves pages; Nest.js organises server-side business logic. If you pick wrong before the first sprint, you either bolt a full API framework onto a page renderer or stuff a domain model into route handlers that were never meant to hold it.
Next.js vs Nest.js: The One-Line Difference
Next.js is a React framework that renders and serves pages. Nest.js is a Node.js backend framework that structures server-side APIs. That is the whole decision in one sentence. Everything else — route handlers, modules, deployment — follows from which of those two jobs you actually have.
What Does Next.js Actually Do?
Next.js's superpower is server-side rendering: it ships HTML from the server so the browser does less work. Wikipedia's overview of Next.js notes that server-side rendering reduces the burden on browsers and provides enhanced security. It is mostly frontend-focused, but it ships with built-in API routes, so you can add backend logic without standing up a separate service. That is the part people over-read: having route handlers does not make it an API framework. It makes it a page framework with convenient endpoints attached.
What Is Nest.js For?
Nest.js builds Node.js server APIs — it does not render web pages. We.Inc's NestJS vs Next.js guide puts it plainly: NestJS builds Node.js server APIs; Next.js builds React websites with some server code. Architecturally, Nest.js gives you modules, controllers, providers, and dependency injection, which is why Matt Burgess groups it with Adonis as one of the excellent JavaScript/TypeScript API solutions. If your problem is "organise business logic, validate requests, share one API across several clients," Nest.js is the tool. If your problem is "render a fast, SEO-friendly page," it is not.
When a Next.js App Is All You Need
A single Next.js app handles route handlers, server actions, auth, cron jobs, and small queues without any second service. You do not need Nest.js to write a JSON endpoint — a route handler does that:
// app/api/billing/route.ts
import { NextResponse } from "next/server";
export async function POST(req: Request) {
const body = await req.json();
// validate, write to DB, return
return NextResponse.json({ ok: true });
}Server actions cover mutations straight from the UI. Cron via Vercel Cron — or a scheduler hitting a route handler — covers small scheduled jobs. A queue is just a table plus a route handler if volume is low. We wrote about exactly this tradeoff in our piece on where the API actually lives: for a product with one web client, Next.js route handlers often win on simplicity.
Signals You've Outgrown Next.js
Four signals mean it is time to consider a separate Nest.js API: long-running jobs, websockets, multiple clients sharing one API, and heavy domain logic. Each of these fights the request/response shape route handlers are built around.
- Long-running jobs — video processing, report generation, ML inference — need a worker that survives a frontend redeploy, not a route handler waiting on a timeout.
- Websockets need persistent connections, which route handlers do not give you cleanly.
- Multiple clients — say your web app plus a partner integration API — is the exact scenario one team on Reddit described: they run Next.js for the main app and NestJS for the external/public partner API. As soon as you have two audiences for your data, one page-bound API stops being enough.
- Heavy domain logic — entities, aggregates, complex validation chains — wants modules and DI, not a folder of route handlers.
The Hacker News critique of Next.js puts it sharply: Next.js carries so many layers of abstraction that most projects don't need, and the ones that do might be better off with something else. That "something else" for the API layer is often Nest.js.
A Monorepo Layout That Doesn't Fight You
If you do split, keep both services in one repo and share types from a single package. Two repos means two PRs for every contract change. One repo with two apps and a shared package keeps the split boring:
.
├── apps/
│ ├── web/ # Next.js — pages, server actions, route handlers
│ └── api/ # Nest.js — controllers, modules, providers
├── packages/
│ └── shared/ # DTOs, zod schemas, config
└── turbo.jsonThat gives you one PR, one CI, and one deploy story per app — and stops the two services from drifting apart on request shapes.
Deployment Comparison
Concern | Next.js alone | Next.js + Nest.js |
|---|---|---|
Hosting | Vercel or a Node server | Vercel for web, Node container for API |
Cold starts | Some, on serverless | Depends on host; containers avoid it |
Deploy coupling | One deploy | Two deploys, two rollbacks |
Resource isolation | None — one process/function | API can scale separately from pages |
Ops overhead | Low | Two runtimes, two sets of logs, two secrets stores |
The Cost of Splitting Too Early
Splitting into two services before you need to costs you deployment overhead, duplicated auth, and shared-type drift — and buys you nothing. If your API exists only to serve your own Next.js pages, a separate Nest.js service is a second deploy that can fail independently, a second auth boundary, and a synchronisation problem for request types. We build web backends at techpotions, and the recurring mistake is frontloading a "proper backend" before the product has a second consumer. One web client, standard requests, modest background work: one Next.js app is the boring, correct choice.
Decision Table
Your situation | Use |
|---|---|
One web client, standard CRUD, some scheduled jobs | Next.js only |
Small background jobs, low volume | Next.js route handlers + a scheduler |
Multiple clients (web + mobile + partner API) | Add Nest.js |
Long-running jobs you cannot block a request on | Add Nest.js (or a worker) |
Real-time features (websockets) | Add Nest.js |
Heavy domain logic (aggregates, complex rules) | Add Nest.js |
You're still pre-product-market-fit | Next.js only — resist the split |
FAQ
Can Next.js replace a dedicated backend?
Yes, for a product with one web client and standard CRUD. Route handlers and server actions cover most request/response needs; you don't need Nest.js to write a JSON endpoint.
When should I add Nest.js to a Next.js app?
When you hit long-running jobs, websockets, multiple clients sharing one API, or heavy domain logic. Those are the signals where route handlers start fighting you.
Is Nest.js faster than Next.js for APIs?
They answer different questions. Nest.js gives you modules and dependency injection for organising complex business logic; Next.js gives you server-side rendering and page infrastructure. Speed is about fit, not benchmark numbers.