advanced-alchemy
Auto-activate for advanced_alchemy imports, alembic/, SQLAlchemyAsyncRepositoryService, SQLAlchemyAsyncConfig, repository_type, service_class, filters, or…
Auto-activate for uv build, hatch build, PyApp, PYAPP_*, wheel assets, GitHub release matrices, cargo-zigbuild, or python-build-standalone. Not for runtime deployment.
$ npx -y skills add litestar-org/litestar-skills --skill litestar-build --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/litestar-buildContext preview
The summary Claude sees to decide when to auto-load this skill.
Auto-activate for uv build, hatch build, PyApp, PYAPP_*, wheel assets, GitHub release matrices, cargo-zigbuild, or python-build-standalone. Not for runtime deployment.
name: litestar-build description: "Auto-activate for uv build, hatch build, PyApp, PYAPP_*, wheel assets, GitHub release matrices, cargo-zigbuild, or python-build-standalone. Not for runtime deployment."
Build-side packaging patterns for Litestar applications: how to produce a **self-contained wheel** that embeds the Vite/Bun frontend, how to wrap that wheel in a **PyApp onefile** binary, and how to wire the whole pipeline into **GitHub Actions** CI and releases.
This skill is the counterpart to [litestar-deployment](../litestar-deployment/SKILL.md) — build is about producing artifacts, deployment is about running them.
A Litestar wheel is the single source of truth for a release. It contains:
Once produced, that wheel can be:
1. `pip install`ed into a container (litestar-deployment). 2. Wrapped in a **PyApp** binary (`dist/<app>`, `dist/app-x86_64-linux-gnu`) for zero-dep distribution. 3. Uploaded to PyPI or a private index.
All three paths assume the wheel is **already complete** — no `bun run build` happens at deploy/install time.
| Property | Bundled wheel | External CDN | | --- | --- | --- | | Deploy artifacts | 1 (`.whl` or binary) | 2+ (wheel + CDN upload) | | Version alignment | Atomic — API and UI lock-step | Easy to skew; rollback is painful | | PyApp onefile | Required — the binary embeds the wheel | Not possible — binary can't fetch CDN URLs at install time | | Offline/air-gapped | Works | Doesn't | | Dev server startup | Instant (files on disk next to package) | Fine | | Frontend-only deploys | Rebuild + redeploy wheel | Push to CDN only |
For **most Litestar apps that ship as a product** (CLIs, internal tools, enterprise installers), bundled-in-wheel is correct. Projects like [litestar-fullstack-inertia](#example-projects) and [litestar-fullstack](#example-projects) all bundle.
This is the piece most developers miss. The Vite/litestar-vite configs in the reference apps are **deliberately set up so the Vite output lands inside the Python package directory** — because that's what makes the wheel pick them up automatically.
**litestar-fullstack** (`src/js/web/vite.config.ts`):
export default defineConfig({
build: {
outDir: path.resolve(__dirname, "../../py/app/server/static/web"), // ← inside src/py/app/ (the Python package)
emptyOutDir: true,
},
plugins: [
litestar({
bundleDir: path.resolve(__dirname, "../../py/app/server/static/web"),
hotFile: path.resolve(__dirname, "../../py/app/server/static/web/hot"),
}),
],
})**litestar-fullstack-inertia** — the litestar-vite plugin resolves `bundle_dir` relative to the project root, and Python settings point it at a package-internal path:
# app/lib/settings.py
return ViteConfig(
paths=PathConfig(
root=BASE_DIR.parent,
bundle_dir=Path("app/domain/web/public"), # ← inside app/ (the Python package)
resource_dir=Path("resources"),
),
)**Advanced reference pattern** — same approach: Vite and the offline-report build write to `src/py/<app>/server/public/` and `src/py/<app>/domain/web/static/reports/offline/`, both under the package root.
Contrast with a naïve `vite build` that writes to `./dist/` at the repo root: those files are **outside** the package directory listed in `[tool.hatch.build.targets.wheel] packages = [...]`, so Hatchling silently drops them. The wheel ships without a frontend.
Rule: **Vite's `outDir` and litestar-vite's `bundle_dir` must point inside one of the Python packages that Hatchling is told to include.** Everything else flows from that.
| Topic | Reference | Key Commands | | --- | --- | --- | | Wheel build + asset bundling | [references/wheel-assets.md](references/wheel-assets.md) | `uv build --wheel`, `[tool.hatch.build.targets.wheel.force-include]`, `ignore-vcs = true` | | PyApp — simple (hatch-binary) | [references/pyapp-simple.md](references/pyapp-simple.md) | `uv run hatch build --target binary` | | PyApp — advanced (offline + custom install dir) | [references/pyapp-advanced.md](references/pyapp-advanced.md) | `tools/bundler.py build`, `cargo zigbuild` | | GitHub Actions CI (test matrix) | [references/github-ci.md](references/github-ci.md) | `astral-sh/setup-uv@v7`, `oven-sh/setup-bun@v2`, composite actions | | GitHub Actions release | [references/github-release.md](references/github-release.md) | matrix onefiles, `cargo-zigbuild`, `gh release create` | | Upgrading Python / PyApp | [references/upgrading.md](references/upgrading.md) | Files to edit in sync |
Every Litestar app with bundled assets has some variant of this:
.PHONY: install build-assets build-wheel build-onefile install: ## Install Python + JS deps @uv sync --all-groups @cd src/js/web && bun install --frozen-lockfile build-assets: ## Build frontend into the Python package @uv run app assets install @uv run app assets build build-wheel: build-assets ## Self-contained Python wheel @uv build --wheel build-onefile: build-wheel ## Single-file PyApp binary @./tools/scripts/build-onefile-package.sh
The dependency chain is **load-bearing**: `build-onefile` depends on `build-wheel`, which depends on `build-assets`. Running them out of order produces an empty or broken artifact.
Real projects have multiple JS build outputs that all need to land in the wheel:
js-build-all: js-build-web js-build-offline-report build-wheel: generate-licenses build-templates js-
Opinionated, first-party agent skills, plugins, subagents, slash commands, and MCP servers for the Litestar framework and its ecosystem — publishable to every major AI agent and IDE from a single repo.
Repo: litestar-org/litestar-skills
Auto-activate for advanced_alchemy imports, alembic/, SQLAlchemyAsyncRepositoryService, SQLAlchemyAsyncConfig, repository_type, service_class, filters, or…
Auto-activate for Google ADK, LlmAgent, Runner, SQLSpecSessionService, Vertex AI, SSE agent chats, tool calls, or Litestar model workflows. Not for offline ML…
Auto-activate for guards=, Guard, ASGIConnection, JWTAuth, JWTCookieAuth, SessionAuth, role or tenant checks, or WebSocket auth. Not for frontend route…
Auto-activate for litestar_autowire, AutowirePlugin, AutowireConfig, domain_packages, AutowireIntegration, AutowireLoader, or clear_autowire_cache. Not for…
Auto-activate for SQLAlchemyAsyncRepositoryService, SQLSpecAsyncService, create_filter_dependencies, LimitOffsetFilter, OffsetPagination, filters, or CRUD…
Auto-activate for Dockerfile, compose, Railway, Cloud Run, GKE, systemd, Kubernetes, Terraform, deploy scripts, or granian/litestar run at runtime. Not for…