Inertia.js, native to NestJS

Server-driven SPAs, native to NestJS.

Build React, Vue, or Svelte frontends on your NestJS monolith — no API to design, no client cache to sync. Pages render straight from your controllers, with a typed <Link>, page-name autocomplete, and end-to-end props along for the ride. Express and Fastify.

5 packages on npm · `nestjs-inertia init` scaffolds everything · auto-codegen in dev

Server-driven by default

Your controller is the page.

Return an object from a controller, tag it with @Inertia, and that data lands in your page component — fully typed, no fetch, no API route, no client cache to babysit. The response is the page.

dashboard.controller.tsserver
@Controller('dashboard')
export class DashboardController {
@Get()
@Inertia('Dashboard') // typed page name
getDashboard() {
return { user, stats }; // → the page props
}
}
inertia/pages/Dashboard.tsx✓ typed props
// props inferred from getDashboard() — no manual types
export default function Dashboard({ user, stats }: PageProps) {
return (
<section>
<h1>Hi, {user.name}</h1>
<Link href="/settings">Settings</Link> // typed route
</section>
);
}
// no fetch · no useQuery · no API route
The codegen sibling

Got consumers that aren't Inertia?

Inertia covers your own frontend. For mobile apps, third parties, or anything that calls your NestJS API directly, its sibling @dudousxd/nestjs-codegen generates a fully typed client from the same controllers — TanStack Query options, typed params and bodies, the works.

hooks/useCrew.ts✗ before
// manual axios hooks everywhere
export function useGetCrew() {
return useQuery({
queryKey: ['crew'],
queryFn: async () => {
const { data } = await axios.get('/api/v1/crew/list');
return data as CrewResponse;
},
});
}
// ...repeat for every endpoint
PostList.tsx✓ nestjs-codegen
import { api } from '~codegen/api';
// Queries — fully typed, zero boilerplate
const { data } = useQuery(api.crew.getCrew.queryOptions());
// Mutations — body & params typed from your controller
const update = useMutation(api.crew.updateCrew.mutationOptions());
await update.mutateAsync({ params: { id: '42' }, body: { name: 'New Name' } });
// Cache invalidation — typed keys
qc.invalidateQueries({ queryKey: api.crew.getCrew.queryKey() });

The monolith, with a typed wire

Six guarantees, one mental model. Everything between your NestJS controllers and your pages is generated and type-checked.

Server-driven, no API

Controllers return page props; Inertia ships them with the page render. No REST or GraphQL layer to design, version, or keep in sync — and no client data cache to invalidate.

Typed <Link>

Route names autocompleted from your controllers. routeParams required and typed to the exact params. Wrong route or missing param? Compile-time error.

Type-safe page names

The codegen scans inertia/pages/ and augments @Inertia() to only accept pages that exist. A typo like 'Dashbord' fails the build — not the user.

Props E2E

req.inertia.render() knows what each page expects — props inferred straight from the default export of every page component. Wrong props never ship.

React, Vue, or Svelte

One adapter, three frameworks, full Inertia protocol parity: partial reloads, deferred props, history encryption, error bags — on Express and Fastify.

First-class testing

expectInertia() matchers assert the rendered page, props, and redirects in supertest e2e suites — without booting a browser.

Wire it in

One command. That's the install.

nestjs-inertia init scaffolds the inertia/ directory and auto-patches your existing app.module.ts and main.ts. From then on, nest start --watch is the only dev command you need — codegen watches alongside it.

Full setup guide
terminal
$ pnpm add @dudousxd/nestjs-inertia \
@dudousxd/nestjs-inertia-vite @dudousxd/nestjs-inertia-client
$ npx nestjs-inertia init
✓ inertia/ scaffolded (pages, app shell, vite entry)
✓ app.module.ts patched — InertiaModule.forRoot()
✓ main.ts patched — setupInertiaVite()
✓ nestjs-inertia.config.ts created — auto-codegen on dev boot

Ship pages, not endpoints.

Install, run init, and build server-driven SPAs on NestJS — React, Vue, or Svelte, with the compiler watching your pages, links, and props.