How to Build Read the Docs with uv
If your docs already build on Read the Docs, you can now switch .readthedocs.yaml to native uv support instead of maintaining a hand-rolled build.jobs override. Read the Docs added this support on April 21, 2026. The two supported paths are uv sync with a docs dependency group, and uv pip install with a requirements file.
Define a docs dependency group
If your project already has a pyproject.toml, declare a dependency group for the documentation toolchain. Groups are the PEP 735 standard place to keep development-only dependencies out of what your users install:
[dependency-groups]
docs = [
"sphinx>=8.1",
"furo>=2024.8",
"myst-parser>=4.0",
]Pin the versions you actually build with. Dependency groups never ship to PyPI, so they exist only for local and CI installs (see the dependency-groups explainer for the full model).
Wire up .readthedocs.yaml to use uv sync
Create .readthedocs.yaml at the repo root with method: uv and command: sync:
version: 2
build:
os: ubuntu-24.04
tools:
python: "3.13"
python:
install:
- method: uv
command: sync
groups:
- docsRead the Docs runs uv sync against your pyproject.toml and pulls in the docs group alongside the project’s main dependencies. If a uv.lock file is present in the repo, uv installs from it; otherwise it resolves fresh.
The groups key takes either a list of group names or the string all. Use all to install every declared group:
python:
install:
- method: uv
command: sync
groups: allPin Python with build.tools.python
Set build.tools.python to an explicit version that satisfies your project’s requires-python, such as "3.13" or "3.14". Avoid "3" unless you’re willing to let doc builds float to the latest 3.x available on Read the Docs.
Commit uv.lock for reproducible doc builds
A single uv.lock covers both the application or library and the docs build. Commit it to version control and Read the Docs installs the exact resolved versions on every build.
$ git add uv.lock
$ git commit -m "Lock dependencies"
Without uv.lock, every build re-resolves and may pull in newer compatible versions of Sphinx, your theme, or any plugin. That works, but a docs build that succeeded yesterday can fail today on a transitive upgrade. See How to use a uv lockfile for reproducible Python environments for the full mechanics of uv lock and uv sync --locked.
Install from a requirements file instead
Projects that aren’t on pyproject.toml yet can still use uv on Read the Docs by switching command to pip:
version: 2
build:
os: ubuntu-24.04
tools:
python: "3.13"
python:
install:
- method: uv
command: pip
requirements: docs/requirements.txtRead the Docs runs uv pip install -r docs/requirements.txt. Use path: instead of requirements: to install the package itself with optional extras:
python:
install:
- method: uv
command: pip
path: .
extras:
- docsThat maps to uv pip install .[docs].
Avoid the two uv-mode pitfalls
Two rules trip people up on the first migration:
- Only one
python.installentry is allowed whenmethod: uv. The legacy pip method lets you stack a requirements install and a package install. The uv method does not. Fold everything into a singlesync(with groups or extras) or a singlepipinvocation. syncandpipaccept different keys.groupsbelongs tocommand: syncand is rejected undercommand: pip.requirementsbelongs tocommand: pipand is rejected undercommand: sync. Pick the command that matches the input you have (apyproject.tomlforsync, arequirements.txtforpip) and use only that command’s keys.
Reach for build.jobs when uv-mode is too narrow
Native method: uv covers the common cases but does not surface every uv flag. Workflows that need --locked, --frozen, --no-dev, or a multi-step install have to drop down to build.jobs and call uv directly. See Read the Docs build customization for the escape hatch and stay on python.install for everything else.
Learn more
- Read the Docs: uv is now supported natively is the original announcement.
- Configuration file reference: python.install lists every key the parser accepts.
- Build customization covers the
build.jobsescape hatch. - uv sync documentation documents the underlying command.