SPA Mode Architecture (mode="spa") AppHandler serves a transformed index.html shell; client router owns navigation and fetches JSON from Litestar OpenAPI routes via @hey-api/openapi-ts and route(). HTML Shell Owner AppHandler (index.html) Injects window.__LITESTAR_CSRF__ Catch-all SPA fallback routes Navigation & Router Client Router React Router / Vue Router / TanStack route() & createRouteHelpers() Data Transport @hey-api/openapi-ts SDK JSON REST + csrfFetch() createTypedChannels() WS/SSE
Hybrid Inertia.js Architecture (mode="hybrid") Litestar controllers own routing and return component PageProps; Inertia.js swaps components via X-Inertia JSON and supports SSR via _InertiaSlots. HTML Shell & SSR AppHandler / Jinja + SSR data-page or <script id="app_page"> Optional Dev TCP / Prod Stdio SSR Server-Driven Routing @get(..., component="...") Python guards & DI own every route resolvePageComponent() on client Inertia.js Protocol PageProps[T] JSON defer() • merge() • lazy() • once() Generated page-props.ts types
Template + Server Islands Architecture (mode="template") Jinja2 templates render server HTML using vite() and vite_hmr(), progressively enhanced with HTMX swap="json", <litestar-stream>, and <litestar-island> fragments. Jinja2 / Server HTML {{ vite('src/main.ts') }} {{ vite_hmr() }} in development {{ vite_fragment('Chart.tsx') }} Server Fragments & Islands <litestar-island> ComponentResponse (HX-Push-Url) hydrateIslands() (React/Vue/Svelte) HTMX & Realtime Streams hx-swap="json" ls-for • ls-if • CSRF auto-header <litestar-stream> WebSocket/SSE
Meta-Framework Architecture (mode="framework" / "external") Astro, SvelteKit, or Nuxt owns its server/SSR pipeline while litestar-vite-plugin/{astro,sveltekit,nuxt} synchronizes ports, proxies /api, and runs typegen. Meta-Framework Server Astro / SvelteKit / Nuxt 4 litestar-vite-plugin/{astro,nuxt,...} Writes hotfile on server listen Proxy & Port Bridge .litestar.json + proxyMode Forwards /api/* to Litestar Routes HMR through Litestar port Shared TypeGen Output openapi.json + routes.json Typed load() / useFetch() calls Zero duplicate schema config