How to¶
Two heads, one core¶
PEP 517 build backend¶
Drop-in replacement for hatchling.build. Runs pnpm exec vite build
before delegating wheel/sdist construction to hatchling. End users who
pip install from PyPI don’t need pnpm or Node — the wheel ships with
the static assets already populated.
# packages/your-theme/pyproject.toml
[build-system]
requires = ["hatchling>=1.0", "sphinx-vite-builder"]
build-backend = "sphinx_vite_builder.build"
backend-path = ["../sphinx-vite-builder/src"] # for in-tree workspace consumption
Sphinx extension¶
Loaded from conf.py. Hooks builder-inited and build-finished so
sphinx-build and sphinx-autobuild automatically run the right vite
invocation: a one-shot pnpm exec vite build for plain sphinx-build
(or sphinx_vite_builder_mode = "prod"), a long-lived
pnpm exec vite build --watch child process for sphinx-autobuild
(or sphinx_vite_builder_mode = "dev"), with graceful SIGTERM →
SIGKILL teardown on signal / atexit.
# docs/conf.py
extensions = ["sphinx_vite_builder"]
sphinx_vite_builder_mode = "auto" # "auto" | "dev" | "prod"
sphinx_vite_builder_root = "/abs/path/to/web"
"auto" resolves to "dev" when the build is running under
sphinx-autobuild (detected via SPHINX_AUTOBUILD env var, argv[0],
or parent-process inspection on Linux), otherwise "prod". Setting
sphinx_vite_builder_root to None (the default) makes the extension
a complete no-op — useful when the consumer is installed from a wheel
where the static tree is already pre-baked.
Fast-fail diagnostics¶
When prerequisites are missing the backend / extension raises actionable errors rather than producing broken output:
PnpmMissingError—pnpmnot onPATH; hint includescorepack enable, the pnpm.io/installation URL, and a per-CI YAML/config snippet (GitHub Actions, CircleCI, Azure Pipelines, GitLab CI) when the build is detected to be running in CI.NodeModulesInstallError—pnpm installexited non-zero; hint includes the rerun command and captured stderr.ViteFailedError—pnpm exec vite buildexited non-zero; hint surfaces the captured stderr.
Set SPHINX_VITE_BUILDER_SKIP=1 in the environment to short-circuit
the backend (e.g., when an external orchestration handles vite).
Copyable config snippet
extensions = [
"sphinx_vite_builder",
]