Svelte¶
Svelte 5 integration with Litestar Vite for lightweight, reactive applications.
Quick Start¶
litestar assets init --template svelte
This creates a Svelte 5 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"],
resourceDir: "src",
}),
],
})
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¶
# 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