Aviary
Reference

Architecture

Package responsibilities, dependency graph, and request lifecycle for nestjs-inertia.

Five focused packages that together implement the Inertia.js protocol for NestJS.

Package map

                       ┌──────────────────────────────────┐
                       │   @dudousxd/nestjs-inertia       │
                       │            (core)                 │
                       │                                   │
                       │  InertiaModule.forRoot()          │
                       │  @Inertia() decorator             │
                       │  InertiaService                   │
                       │  Version negotiation              │
                       │  CSRF, redirects, method spoof    │
                       └───────────┬──────────────────────┘
              ┌────────────────────┼─────────────────────┐
              │                    │                     │
              ▼                    ▼                     ▼
 ┌─────────────────────┐  ┌────────────────────┐  ┌──────────────────────────┐
 │  nestjs-inertia-     │  │  nestjs-inertia-   │  │  nestjs-inertia-         │
 │       vite           │  │     testing        │  │      codegen             │
 │                      │  │                    │  │                          │
 │  Vite plugin         │  │  expectInertia()   │  │  CLI: codegen / doctor   │
 │  Dev-server HMR      │  │  InertiaAssertion  │  │  Emits:                  │
 │  Manifest serving    │  │  TestingModule     │  │    pages.d.ts            │
 └─────────────────────┘  └────────────────────┘  │    routes.ts             │
                                                  │    api.ts                │
                                                  └──────────┬───────────────┘
                                                             │ emits

                                                  ┌──────────────────────────┐
                                                  │  nestjs-inertia-         │
                                                  │       client             │
                                                  │                          │
                                                  │  @As() route naming      │
                                                  │  createFetcher           │
                                                  │  <Link> components       │
                                                  │  SSR hydration           │
                                                  └──────────────────────────┘

Package responsibilities

core (@dudousxd/nestjs-inertia)

  • InertiaModule.forRoot(options) registers the module globally. Configures root view, version string, shared-data factory.
  • InertiaModule.forFeature(options) registers an additional scope with isolated config and shared props.
  • @Inertia(component) method decorator intercepts a controller return value and serializes it as an Inertia response.
  • InertiaService injectable service for programmatic Inertia renders and redirects.
  • Version negotiation compares X-Inertia-Version header and triggers a full reload when assets change.
  • CsrfCookieInterceptor / CsrfGuard for CSRF protection.
  • RedirectInterceptor converts 302 to 303 for PUT/PATCH/DELETE per the Inertia protocol.
  • MethodSpoofMiddleware enables _method field support for HTML forms.
  • Auto-starts codegen watcher in development when @dudousxd/nestjs-codegen is installed.

vite (@dudousxd/nestjs-inertia-vite)

  • nestInertia(options) Vite plugin for React/Vue/Svelte transforms.
  • setupInertiaVite(app, options) attaches the Vite dev-server middleware to the NestJS Express/Fastify app.
  • In production, reads the Vite manifest to inject hashed asset URLs into the root view.

testing (@dudousxd/nestjs-inertia-testing)

  • expectInertia(response) fluent assertion chain (toRenderComponent, toHaveProp, toHaveVersion, and more).
  • assertInertia(payload) same assertions against a raw JSON payload.
  • InertiaTestingModule.forTest() wraps InertiaModule.forRoot() with test defaults.
  • createFakeInertiaRequest() / createFakeInertiaResponse() for unit tests without HTTP.
  • Framework matchers for Vitest and Jest via subpath imports.

codegen (@dudousxd/nestjs-codegen + @dudousxd/nestjs-inertia-codegen-extension)

The typed-client codegen lives in the standalone @dudousxd/nestjs-codegen package. This repo ships @dudousxd/nestjs-inertia-codegen-extension, the extension you register so the generated api.ts gains the Inertia router import and a typed navigate() helper. The codegen statically analyses the NestJS app and emits:

  • pages.d.ts module augmentation for typed @Inertia() and page props.
  • routes.ts typed route map + route() helper for URL resolution.
  • api.ts queryOptions(), mutationOptions(), queryKey(), and infiniteQueryOptions() for every route. Response types are wrapped in Jsonify<...> by default so they reflect the JSON wire shape (Datestring); opt out with serialization: 'superjson'. Page props use Parameters<typeof import(...).default>[0].

Setup diagnostics are provided by nestjs-inertia doctor (from @dudousxd/nestjs-inertia) with --fix for auto-repair.

client (@dudousxd/nestjs-inertia-client)

  • @As(name) sets the route name for a controller class or method (read by codegen). Auto-derived from ClassName.methodName when absent.
  • createFetcher(options) creates a typed fetch client from the generated api.ts.
  • invalidate(queryClient, name, args?) invalidates TanStack Query cache by route name.
  • hydrateClientFromInertia(page) initializes TanStack Query from the Inertia initial-page payload.
  • Typed <Link> components for React, Vue 3, and Svelte with route-name autocomplete.

Request lifecycle

Browser GET /dashboard
  → NestJS router → DashboardController.index()
      → @Inertia('Dashboard') interceptor
          ← { user, count }   (return value)
      → InertiaService serializes response
          • First visit  → HTML shell (Vite manifest + <div id="app" data-page="...">)
          • X-Inertia    → JSON { component, props, url, version }
  → Browser renders React/Vue/Svelte page via inertia entry

On this page