Svelte#
Svelte integration with Litestar Vite for lightweight, reactive applications.
At a Glance#
Template:
litestar assets init --template svelteMode:
spaEntry:
src/main.tsDev:
litestar run --reload(orlitestar assets serve+litestar run)
Quick Start#
litestar assets init --template svelte
This creates a Svelte project with TypeScript support.
Project Structure#
Svelte applications use SPA mode - Vite serves the index.html directly:
my-app/
├── app.py # Litestar backend (API only)
├── index.html # Vite entry point (root level)
├── package.json
├── vite.config.ts
├── svelte.config.js
└── src/
├── main.ts # Svelte entry point
├── App.svelte # Root component
└── style.css
Backend Setup#
In SPA mode, Litestar serves only your API endpoints. The VitePlugin handles serving the frontend automatically:
vite = VitePlugin(
config=ViteConfig(
mode="spa",
dev_mode=DEV_MODE,
paths=PathConfig(root=here),
types=TypeGenConfig(),
runtime=RuntimeConfig(port=5021),
)
)
app = Litestar(route_handlers=[LibraryController], plugins=[vite], debug=True)
Key points:
mode="spa"tells Vite to serveindex.htmlfor non-API routesNo
template_configneeded - Jinja is not used in SPA modeTypeGenConfig()enables TypeScript type generation from OpenAPI
Vite Configuration#
import { svelte } from "@sveltejs/vite-plugin-svelte"
import tailwindcss from "@tailwindcss/vite"
import litestar from "litestar-vite-plugin"
import { defineConfig } from "vite"
export default defineConfig({
plugins: [
tailwindcss(),
svelte(),
litestar({
input: ["src/main.ts"],
types: "auto",
}),
],
})
Key configuration:
input- Entry point(s) for your applicationresourceDir- Source directory (explicitly set tosrc)The plugin auto-reads
assetUrl,bundleDirfrom.litestar.json(generated by Python)
HTML Entry Point#
In SPA mode, index.html lives at the project root and uses standard Vite syntax:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>svelte</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
Note
Unlike template mode, SPA mode doesn’t use Jinja helpers like {{ vite() }}.
Vite processes the HTML directly.
Svelte Component#
<script lang="ts">
import { onMount } from "svelte";
let summary = $state<{ headline: string } | null>(null);
onMount(async () => {
const res = await fetch("/api/summary");
summary = await res.json();
});
</script>
<main>
<h1>Svelte + Litestar</h1>
{#if summary}
<p>{summary.headline}</p>
{/if}
</main>
Running#
Realtime streams#
Use createEventStreamStore() from litestar-vite-plugin/svelte for
custom routes, or createQueueEventStreamStore() for Litestar Queues event
envelopes. The readable store shares one connection across subscribers and
disposes it after the last unsubscribe. See WebSocket and SSE event streams.
# Recommended: Litestar proxies Vite automatically in dev mode
litestar run --reload
# Alternative: Two-process setup
litestar assets serve # Vite dev server
litestar run --reload # Backend only (in another terminal)
Type Generation#
With types=TypeGenConfig() enabled, run:
litestar assets generate-types
This generates TypeScript types from your OpenAPI schema. See Type Generation for more details.
See Also#
Inertia.js - Svelte with Inertia.js for server-side routing
Type Generation - TypeScript type generation
WebSocket and SSE event streams - WebSocket and SSE helpers