Angular¶
Litestar Vite supports Angular in two ways: Vite-based (using AnalogJS) and Angular CLI.
At a Glance¶
Vite-based:
litestar assets init --template angular(modespa)Angular CLI:
litestar assets init --template angular-cli(modeexternal)Entry:
src/main.ts(both variants)Dev:
litestar run --reload(Vite-based) ornpm start/ng serve(Angular CLI)
Option 1: Vite-Based (Recommended)¶
Uses @analogjs/vite-plugin-angular for fast HMR and unified tooling.
litestar assets init --template angular
Project Structure¶
my-app/
├── app.py # Litestar backend
├── package.json
├── vite.config.ts
├── tsconfig.json
├── index.html # Vite entry
└── src/
├── main.ts # Angular bootstrap
└── app/
├── app.component.ts
├── app.component.html
├── app.config.ts
├── app.routes.ts
└── home.component.ts
Backend Setup¶
from typing import Any
from litestar import Litestar, get
from litestar_vite import ViteConfig, VitePlugin
@get("/api/hello")
async def hello() -> dict[str, Any]:
return {"message": "Hello from Litestar!"}
vite = VitePlugin(config=ViteConfig(dev_mode=True))
app = Litestar(
plugins=[vite],
route_handlers=[hello],
)
Vite Configuration¶
import angular from "@analogjs/vite-plugin-angular"
import tailwindcss from "@tailwindcss/vite"
import litestar from "litestar-vite-plugin"
import { defineConfig } from "vite"
export default defineConfig({
resolve: {
mainFields: ["module"],
},
plugins: [
// Angular plugin must be first
angular(),
tailwindcss(),
litestar({
input: ["src/main.ts", "src/styles.css"],
}),
],
})
Key configuration:
angular()plugin must come firstinputincludes both TypeScript entry and CSSresourceDirexplicitly set tosrcresolve.mainFieldsset to["module"]for Angular compatibility
Angular Route Shell¶
The current scaffold keeps AppComponent as a router shell and loads the
page component through app.routes.ts:
import { Component } from "@angular/core";
import { RouterOutlet } from "@angular/router";
@Component({
selector: "app-root",
standalone: true,
imports: [RouterOutlet],
template: `<router-outlet />`,
})
export class AppComponent {}
Feature Component¶
import { Component, OnInit, inject } from "@angular/core";
import { HttpClient } from "@angular/common/http";
@Component({
selector: "app-root",
standalone: true,
template: `
<h1>Angular + Litestar</h1>
<p>{{ message }}</p>
`,
})
export class HomeComponent implements OnInit {
private http = inject(HttpClient);
message = "";
ngOnInit() {
this.http.get<{message: string}>("/api/hello")
.subscribe(res => this.message = res.message);
}
}
Running (Analog)¶
# Single-port: Litestar starts and proxies Vite
litestar run --reload
# Two-port: start Vite yourself
litestar assets serve
litestar run --reload
Option 2: Angular CLI¶
Standard Angular CLI workflow with proxy to Litestar and Angular’s application builder.
litestar assets init --template angular-cli
This creates a standard Angular project that:
Uses Angular’s
@angular/buildapplication builderUses
ng servefor developmentProxies API requests to Litestar via
proxy.conf.jsonUses Tailwind 4 via
.postcssrc.jsonand@tailwindcss/postcssBuilds to
dist/browser/for productionExposes
npm run generate-typesfor manual OpenAPI client generation
Proxy Configuration¶
{
"/api": {
"target": "http://localhost:8000",
"secure": false
}
}
Running Angular CLI¶
# Terminal 1: Litestar backend
litestar run --reload
# Terminal 2: Angular dev server
npm start
Access at http://localhost:4200 (Angular proxies API calls to Litestar).
Comparison¶
Aspect |
Vite (Analog) |
Angular CLI |
|---|---|---|
Build Tool |
Vite |
Angular application builder |
HMR Speed |
Fast |
Standard |
litestar-vite-plugin |
Yes |
No |
Type Generation |
Enabled |
Manual script |
Port |
Single (8000) |
Two (4200 + 8000) |