Skip to content
Development
Skill

/litestar-build

Use when working with uv build, hatch build, PyApp, PYAPP_*, wheel assets, GitHub release matrices, cargo-zigbuild, or python-build-standalone. Not for runtime deployment.

From plugin
litestar
1720 skills1 agent2 hooks

Claude Code

$ npx -y skills add litestar-org/litestar-skills --skill litestar-build --agent claude-code

SKILL.md

litestar-build.SKILL.md
name: litestar-build
description: "Use when working with uv build, hatch build, PyApp, PYAPP_*, wheel assets, GitHub release matrices, cargo-zigbuild, or python-build-standalone. Not for runtime deployment."

litestar-build

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.

The Core Idea: One Wheel, Self-Contained

A Litestar wheel is the single source of truth for a release. It contains:

  • Python code (`src/py/app/` or `app/`)
  • SQL migrations, Jinja templates, INI configs
  • The **built** Vite/Bun frontend bundle (JS, CSS, HTML, images)
  • Email templates rendered from React/MJX to static HTML

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.

Why bundle assets into the wheel (and not serve from a CDN)

| 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.

Why litestar-vite configs look the way they do in reference apps

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** — in `litestar-vite` v0.30+, Python `ViteConfig(paths=PathConfig(bundle_dir=...))` is the single source of truth and writes `.litestar.json` on startup/CLI invocation so `litestar({ input: [...] })` in `vite.config.ts` inherits `bundleDir`, `hotFile`, and `assetUrl` automatically (and `litestar assets build` exports OpenAPI/routes metadata, runs `TypeGenConfig` codegen once with `LITESTAR_VITE_SKIP_BUILD_TYPEGEN=1`, installs `node_modules` if missing, and runs the Vite build):

from pathlib import Path
from litestar_vite.config import PathConfig, ViteConfig


def get_vite_config(base_dir: Path) -> ViteConfig:
    """Configure litestar-vite to emit assets inside the app/ Python package."""
    return ViteConfig(
        paths=PathConfig(
            root=base_dir.parent,
            bundle_dir=Path("app/domain/web/public"),
            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.

Code Style Rules

  • Emit all compiled frontend bundles (`PathConfig.bundle_dir` / Vite `build.outDir`) inside a Python package directory included by Hatchling (`app/...` or `src/py/<pkg>/...`).
  • Choose exactly one Hatchling asset inclusion strategy (`[tool.hatch.build.targets.wheel.force-include]` OR `ignore-vcs = true`) — never combine both.
  • Guard custom Hatchling build hooks (`BuildHookInterface.initialize`) with `if version == "editable":` (warning to `sys.stderr`, creating the placeholder directory, and returning early when compiled assets do not exist yet) so `uv sync` succeeds before frontend assets are built, and exclude `tools/build` from `mypy` and `pyright`.
  • Run asset compilation, static template generation, and license collection before `uv build --wheel --clear`.
  • Treat `PYAPP_*` configuration variables (`PYAPP_PROJECT_PATH`, `PYAPP_PYTHON_VERSION`, `PYAPP_DISTRIBUTION_EMBED`, `PYAPP_DISTRIBUTION_VARIANT_GIL`, `PYAPP_SKIP_INSTALL`) as compile-time inputs to `cargo build` / `cargo zigbuild`; at runtime, use `PYAPP_INSTALL_DIR_<PROJECT_NAME>` (where `<PROJECT_NAME>` is the uppercased `PYAPP_PROJECT_NAME` with `-` replaced by `_`) to override the extraction directory and inspect `os.getenv("PYAPP")` (`"1"` or path when built with `PYAPP_PASS_LOCATION=1`) to detect PyApp execution.
  • Use `cargo zigbuild --release --target <arch>-unknown-linux-gnu.2.17` with `BZIP2_SYS_STATIC=1` and `LZMA_API_STATIC=1` when building portable L
Read more
@litestar-org
Ships withlitestar

Opinionated, first-party agent skills, plugins, subagents, hooks, and rules for the Litestar framework and its ecosystem — published from a single-root repository across Google Antigravity, Claude Code, Codex CLI, Cursor, OpenCode, and VS Code / Copilot.

1720 skills1 agent
Get the whole plugin

Stars on GitHub

Momentum

stars in total
17
Star history of litestar-org/litestar-skills on GitHub, a chart by star-history.com

Other skills on litestar.

advanced-alchemy

advanced-alchemy

Use when working with advanced_alchemy, alembic/, SQLAlchemyAsyncRepositoryService, SQLAlchemyAsyncConfig, repository_type,…

litestar-autowire

litestar-autowire

Use when working with litestar_autowire, AutowirePlugin, AutowireConfig, domain_packages, AutowireIntegration, AutowireLoader, or…

litestar-docs

litestar-docs

Use when working with zensical.toml, docs/conf.py, sphinx, shibuya, litestar-sphinx-theme, mkdocstrings, Griffe, objects.inv, or…

litestar-email

litestar-email

Use when working with litestar_email, EmailPlugin, EmailConfig, EmailService, EmailMessage, SMTPConfig, ResendConfig,…

litestar-granian

litestar-granian

Use when working with litestar_granian, GranianPlugin, litestar run Granian options, runtime threads, HTTP/2, TLS, access logs,…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc12d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about litestar-build.

Which coding agents can use litestar-build?
litestar-build installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.