Skip to main content

nextjs-nestapi

NestJS-style controllers for the Next.js App Router

src/features/hello/controller.ts
@Controller("/hello")
export class HelloController {
@Get("/:id")
getOne(context: RouteContext) {
return { id: context.params.id };
}

@Post("")
create(@Body(CreateHelloDto) dto: CreateHelloDto) {
return { created: dto };
}
}

Why nextjs-nestapi?

Plain Next.js route handlers are just functions — no ceremony, straight to the Web APIs. That's exactly where the pain starts once an API grows past a few endpoints: validation gets hand-rolled per route, error shapes drift, and there's no single place that lists what your API actually exposes.

Validation, built in

@Body(DtoClass) validates the request body against your class-validator decorators before the handler ever runs — no hand-rolled if checks, no field quietly left unvalidated. The same decorated method validates just as well when bound and called as a Next.js Server Action.

One error shape, always

Every validation failure returns the same structured response. Nothing to remember, nothing to retype slightly differently in the next route.

Routes you can actually see

Routes are the @Get/@Post decorators on a controller class — read one file to know what an API exposes, instead of browsing a folder tree.

No framework tax

Still the same NextRequest/NextResponse Next.js already gives you. nextjs-nestapi organizes the API — it doesn't replace anything underneath it.

Docs that can't drift

@ApiTags/@ApiOperation and generateOpenApiDocument() build the OpenAPI spec from the same decorators the route already needs — no separate file to keep in sync.

One command to start

npx nextjs-nestapi new/init/generate scaffolds the wiring and the boilerplate — you write the controller, not the plumbing around it.

How nextjs-nestapi compares

Feature
nextjs-nestapi
Route Handlers
NestJS
Express
Setup
npx nextjs-nestapi new
Manual
nest new (separate app)
Manual
Learning curve
⭐ Easy
⭐ Easy
⭐⭐⭐⭐ Steep
⭐⭐ Easy
Boilerplate
Minimal
Grows per route
Moderate (modules)
Minimal
Request validation
Built-in — @Body(Dto)
Manual
Built-in — pipes
Manual
DI container
None, by design
N/A
Full
None
OpenAPI docs
Auto-generated
Manual
Auto-generated
Manual
Runs inside Next.js
Yes
Yes
No — separate server
Yes, via custom server

Everything you need

Decorator-based routing

@Controller, @Get/@Post/@Put/@Patch/@Delete and Express-style :param segments — organize your API the way NestJS does, on top of Next.js's own request/response objects.

DTO validation built in

@Body(DtoClass) parses and validates the request body with class-validator, and returns a structured error response automatically when validation fails — in API routes and in Next.js Server Actions alike.

One catch-all route

A single app/api/[[...route]]/route.ts dispatches to every controller. No per-endpoint route files to create or keep in sync.

OpenAPI / Swagger docs

generateOpenApiDocument() builds a spec straight from your decorators and DTOs; createSwaggerUiHandler() serves the UI from your own node_modules — no CDN, nothing vendored.

CLI scaffolding

nextjs-nestapi new, init, and generate controller bootstrap a project or add a feature without hand-writing boilerplate.

No DI container

Controllers are plain classes you construct however you like — no modules, no second framework running alongside Next.js.