Vite 7/8 Environment API & Dev Proxy Architecture#
litestar-vite requires Vite 7+. It uses Vite’s RunnableDevEnvironment (server.environments.ssr) for development server-side rendering, build.rolldownOptions for bundler configuration, and a pooled httpx2 HTTP reverse proxy for single-port asset delivery. HMR uses a WebSocket tunnel. Development SSR uses a separate pooled HTTP IPC client to call Vite ModuleRunner; production SSR uses stdio IPC.
Vite Configuration: Environments, Rolldown & WS#
Environment API (``server.environments``): Vite provides isolated module graphs for
clientandssrenvironments inside a single dev server instance.litestar-viteusesserver.environments.ssr.runnerto evaluate server-rendered components in development without running a separate SSR build.Rolldown Options (``build.rolldownOptions``): Vite 8 uses Rolldown for bundling.
litestar-vitescaffolding templates configure output naming underbuild.rolldownOptions(falling back tobuild.rollupOptionson Vite 7 via thelitestar-viteVite plugin):// vite.config.ts export default defineConfig({ build: { rolldownOptions: { output: { entryFileNames: "assets/[name]-[hash].js", chunkFileNames: "assets/[name]-[hash].js", assetFileNames: "assets/[name]-[hash][extname]", }, }, }, });
WebSocket Configuration (``server.ws``): Vite 8.1+ configures HMR WebSocket listeners under
server.ws(server.hmron Vite 7 / 8.0, handled automatically by the plugin):server: { host: "0.0.0.0", port: Number(process.env.VITE_PORT || "5173"), cors: true, ws: { host: "localhost", }, },
Single-Port Dev Asset Proxying#
In development mode (dev_mode=True), litestar-vite serves your entire application on a single ASGI port (for example http://localhost:8000). Asset requests under asset_url (such as /static/@vite/client and /static/src/main.ts) and HMR WebSocket connections (/static/vite-hmr) are forwarded to the Vite dev server. HTTP responses stream through a lifespan-managed httpx2 client; HMR uses the WebSocket transport. The standard litestar-vite installation includes the HTTP client dependency.
sequenceDiagram
autonumber
participant Browser as Browser
participant Litestar as Litestar (Port 8000)
participant Vite as Vite Dev Server (Port 5173)
Browser->>Litestar: GET / (HTML Page Shell)
Litestar-->>Browser: HTML with <script src="/static/src/main.ts">
Browser->>Litestar: GET /static/src/main.ts
Litestar->>Vite: Pooled HTTP request /static/src/main.ts
Vite-->>Litestar: Transformed ES module
Litestar-->>Browser: Streamed ES module
Browser->>Litestar: WebSocket HMR (/static/vite-hmr)
Litestar->>Vite: WebSocket HMR tunnel
Vite-->>Browser: HMR updates
from pathlib import Path
from litestar import Litestar
from litestar_vite import PathConfig, ViteConfig, VitePlugin
vite_config = ViteConfig(
dev_mode=True,
paths=PathConfig(
root=Path(__file__).parent,
resource_dir="resources",
bundle_dir="public",
),
)
vite_plugin = VitePlugin(config=vite_config)
app = Litestar(plugins=[vite_plugin])
ModuleRunner Dev SSR#
In production, SSR components are imported from a built server bundle (such as ssr.js). In development, litestar-vite uses Vite’s createServerModuleRunner(server.environments.ssr) to evaluate SSR modules directly from Vite’s transform pipeline:
When an SSR or fragment render request arrives, the worker imports the component through the SSR
ModuleRunner.Vite transforms TypeScript, JSX, Vue SFCs, or Svelte modules on demand.
When a file changes, the Vite plugin invalidates the module and its importers in the SSR cache so subsequent renders use the updated code without rebuilding or restarting the worker.