litestar-org/litestar-skills/litestar-vite

Claude Code and agent skill by litestar-org/litestar-skills

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Auto-activate for litestar_vite, VitePlugin, ViteConfig, PathConfig, TypeGenConfig, vite.config.ts, InertiaConfig, component=, or @inertiajs/*. Not for plain Vite or server-only HTMX.

Install

npx vskill@latest install litestar-org/litestar-skills/litestar-vite

SKILL.md

litestar-vite

litestar-vite is the first-party plugin that connects a Vite frontend build pipeline to a Litestar backend. It handles dev-server proxying, HMR coordination, manifest resolution for production assets, and (optionally) end-to-end type generation from Litestar OpenAPI to TypeScript.

The runtime has four canonical modes: spa, template, hybrid, and framework. htmx, inertia, ssr, and ssg are aliases that normalize to those modes. external is a fifth, permanent alias of framework; it still requires an ExternalDevServer.

The plugin pairs with the npm package `litestar-vite-plugin` on the JS side. Python ViteConfig is the source of truth; the generated .litestar.json bridge lets JS config normally keep only litestar({ input: [...] }).

This guidance targets litestar-vite 0.33.0. Features include server-rendered UI component fragments, persistent IPC SSR transports with circuit-breaker fallback, AsyncAPI 3.0 typed channel generation, Vite 7+ support, and single-port development proxying. See Release Updates.

Code Style Rules

  • Python: PEP 604 unions (T | None); consumer Litestar app modules MAY use from __future__ import annotations.
  • TypeScript: strict mode; defineConfig from vite; one vite.config.ts per frontend project.
  • Keep ViteConfig as the source of truth. Only duplicate bundleDir, hotFile, or assetUrl in vite.config.ts for deliberate standalone/override workflows.
  • Inertia (`mode="hybrid"`): use msgspec.Struct(..., rename="camel") for structured page-prop returns, wire csrfHeaders() into createInertiaApp({ defaults: { visitOptions } }), use useForm for mutations, and read flash notifications from top-level usePage().flash (dict[str, list[str]]), never usePage().props.flash.

Quick Reference

Minimal SPA setup (Python side)
python
from litestar import Litestar
from litestar_vite import PathConfig, ViteConfig, VitePlugin
vite_config = ViteConfig(
mode="spa",
enabled=True,
paths=PathConfig(
resource_dir="resources",
bundle_dir="public",
hot_file="hot",
),
dev_mode=True,
)
app = Litestar(plugins=[VitePlugin(config=vite_config)])
Minimal SPA setup (JS side)
ts
// vite.config.ts
import { defineConfig } from "vite"
import litestar from "litestar-vite-plugin"
import react from "@vitejs/plugin-react"
export default defineConfig({
clearScreen: false,
publicDir: "public",
plugins: [
react(),
litestar({
input: ["resources/main.tsx", "resources/main.css"],
}),
],
resolve: { alias: { "@": "/resources" } },
})
Mode Selection
ModeUse ForKey Setup
spaReact, Vue, Svelte, or Analog-powered Angular SPA with a Litestar JSON API backenddev_mode=True proxies to Vite; manifest in prod
template (htmx alias)Server-rendered Jinja2/Mako pages and HTMX with Vite-bundled assetsUse TemplateConfig; add litestar-htmx when using HTMX
hybrid (inertia alias)Inertia.js routes returning JS page componentsConfigure ViteConfig(inertia=InertiaConfig(...))
framework (ssr / ssg aliases)Nuxt, SvelteKit, Astro, Angular CLI, or another frontend-owned HTML serverUse the framework entry point or ExternalDevServer

Decision tree:

  • Need full SPA with client-side routing → spa
  • Server-rendered HTML, sprinkle Vite-bundled JS → template
  • HTMX-driven hypermedia with Vite assets → template (htmx alias) + HTMXPlugin
  • Server-side routing + JS page components, shared data → hybrid (inertia alias; see Inertia Reference)
  • Nuxt, SvelteKit, or Astro owns HTML → framework
  • Angular CLI or another non-Vite server → framework + ExternalDevServer
VitePlugin config (Python)
python
from litestar_vite import (
PathConfig,
RuntimeConfig,
TypeGenConfig,
ViteConfig,
VitePlugin,
)
vite_config = ViteConfig(
mode="spa",
enabled=True,
dev_mode=False,
paths=PathConfig(
root=".",
resource_dir="src",
bundle_dir="public",
static_dir="src/public",
hot_file="hot",
asset_url="/static/",
),
runtime=RuntimeConfig(
port=5173,
host="localhost",
protocol="http",
executor="bun",
),
types=TypeGenConfig(
generate_zod=False,
generate_sdk=True,
generate_routes=True,
generate_schemas=True,
generate_page_props=False,
output="src/generated",
),
)

enabled=None auto-detects serving contexts and consults VITE_ENABLED. enabled=False leaves VitePlugin.config and asset CLI commands available but skips runtime routes, middleware, static routers, lifespans, and the SPA handler.

Type Generation
python
TypeGenConfig(
generate_sdk=True,
generate_routes=True,
generate_schemas=True,
generate_page_props=True,
output="src/generated",
)
OutputPathTriggerFrontend Use
openapi.jsonoutput/openapi.jsonWhenever OpenAPI schema changesSource of truth for SDK + schemas
routes.jsonoutput/routes.jsonRoute table changesRoute metadata consumed by the JS plugin
routes.tsoutput/routes.tsRoute table or app.csrf_config changesroute("name", { params }) typed URL builder + CSRF_COOKIE_NAME / CSRF_HEADER_NAME (0.31.0+)
api/output/api/OpenAPI changeshey-api types, schemas, SDK, and fetch client
schemas.tsoutput/schemas.tsRoute request/response changesFormInput, FormResponse, and SuccessResponse helpers
inertia-pages.jsonoutput/inertia-pages.jsonInertia handlers added/changedPage-prop metadata consumed by the JS plugin
page-props.tsoutput/page-props.tsInertia handlers added/changedTyped props for Inertia page components
static-props.tsoutput/static-props.tsViteConfig.static_props changesTyped static bridge values (virtual:litestar-static-props)
asyncapi.jsonoutput/asyncapi.jsonAsyncAPIPlugin + Channels / WebSocket / SSE route changes (0.32.0+)AsyncAPI 3.0 document when AsyncAPIPlugin is registered and generate_channels=True
channels.tsoutput/channels.tsAsyncAPIPlugin + Channels / WebSocket / SSE route changes (0.32.0+)ChannelMap consumed by createTypedChannels()

CLI:

bash
litestar assets generate-types # one-off generation
litestar assets export-routes # routes.json metadata (--only, --except, --include-components)
litestar assets export-routes --typescript # routes.ts only
litestar --app app:app run # generates on startup if enabled

Frontend consumption:

ts
// routes + CSRF constants (0.31.0+)
import { CSRF_COOKIE_NAME, CSRF_HEADER_NAME, route } from "@/generated/routes"
import { csrfFetch, csrfHeaders, getCsrfHeaderName, getCsrfToken } from "litestar-vite-plugin/helpers"
const url = route("users:get", { id: 123 })
await csrfFetch(url, { method: "POST" }, { headerName: CSRF_HEADER_NAME, cookieName: CSRF_COOKIE_NAME })
// hey-api output
import type { User } from "@/generated/api"
// ergonomic route helpers
import type { FormInput } from "@/generated/schemas"
type LoginInput = FormInput<"auth:login">
ViteAssetLoader, Secondary HTML Entries, and Component Fragments

Auto-registered Jinja2 globals when a template engine is configured:

HelperUse
{{ vite('resources/main.ts') }}Render script/link tags for a Vite input; handles dev vs manifest
{{ vite_hmr() }}Inject HMR client <script> in dev mode; no-op in prod
{{ vite_static('favicon.svg') }}Resolve a static asset URL
{{ vite_routes() }}Render inline route metadata for client-side routing
{{ vite_fragment('components/Card.vue', props=..., mode='static') }}Server-render a React/Vue/Svelte/Astro fragment or <litestar-island> (0.32.0+)

Minimal base template:

html
<!DOCTYPE html>
<html>
<head>
{{ vite_hmr() }}
{{ vite('resources/main.tsx') }}
</head>
<body>
<div id="app"></div>
</body>
</html>

For programmatic asset loading (ViteAssetLoader, resolve_html_entry) or server-rendered <litestar-island> UI component fragments (ComponentResponse(..., mode="island")), see Modes and Config.

CLI
bash
litestar assets init # Scaffold vite.config.ts and package.json
litestar assets install # Run npm/pnpm/bun install
litestar assets update # Update within package.json semver ranges
litestar assets serve # Start Vite dev server (also auto-started when `dev_mode=True`)
litestar assets build # Production build (emits manifest.json + hashed bundles)
litestar assets deploy --dry-run # Build and preview an fsspec-backed deployment
litestar assets deploy # Build and sync to DeployConfig.storage_backend
litestar assets generate-types # TypeScript type generation
litestar assets export-routes # routes.json metadata
litestar assets doctor # Diagnose integration health
litestar assets status # Read-only status summary

assets init --template accepts react, react-router, react-tanstack, react-inertia, react-inertia-jinja, vue, vue-inertia, vue-inertia-ssr, vue-inertia-jinja, vue-inertia-jinja-ssr, svelte, svelte-inertia, svelte-inertia-jinja, sveltekit, nuxt, astro, htmx, jinja-htmx, htmx-no-jinja, angular, and angular-cli.

HMR & Production Build
  • Dev Mode (Single-Port Proxy): Vite runs on runtime.port and writes paths.hot_file; Litestar proxies asset HTTP and the HMR WebSocket (/static/vite-hmr) so the browser uses a single public origin. In Vite 8.1+, place explicit HMR network overrides under server.ws (not server.hmr). See HMR Reference.
  • Production Build: Run litestar assets build (or litestar assets deploy) with dev_mode=False. Asset loading checks <bundle_dir>/<manifest_name> then <bundle_dir>/.vite/<manifest_name>. See Deployment Reference.
Inertia & HTMX Integration
  • Inertia (`mode="hybrid"`): Configure ViteConfig(mode="hybrid", inertia=InertiaConfig(...)) on a single VitePlugin. Return msgspec.Struct(..., rename="camel") prop bags from @get(..., component="...") handlers (field renames are preserved at top level). Stage share(), flash(), error(), and clear_history() in InertiaTransientState, wire csrfHeaders() into createInertiaApp({ defaults: { visitOptions } }), read flash messages from top-level usePage().flash, and pass uninvoked callables to defer / lazy / optional / once. See Inertia Reference, Deferred & Merge Props, and Advanced Inertia Patterns.
  • HTMX (`mode="template"`): Pair ViteConfig(mode="template") with TemplateConfig and HTMXPlugin().

<workflow>

Workflow

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
0

Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/litestar-org/litestar-skills/litestar-vite/badge)](https://verified-skill.com/skills/litestar-org/litestar-skills/litestar-vite)

Something wrong with this skill or its page? Tell us.