Use the uv backend

Make pipx use uv to create virtual environments and install packages in place of pip and venv. The CLI surface stays the same.

For why uv is faster and how pipx compares to Astral’s standalone uv tool, see Comparisons.

Make uv available

Install pipx with the uv extra so it ships the bundled binary:

$ pipx install pipx[uv]

Or install uv 0.9.17 or newer however you like (brew install uv, cargo install uv) and put it on PATH; pipx picks it up. New venvs then default to uv. Existing venvs keep their recorded backend. When the uv pipx finds is older than that, pipx warns and falls back to pip. Asking for uv explicitly (--backend uv, PIPX_DEFAULT_BACKEND=uv, or a venv that recorded uv) with an older uv fails and asks you to upgrade it.

How pipx picks a backend

        flowchart TD
    START["new venv"] --> CLI{"--backend given?"}
    CLI -->|yes| USECLI["use it"]
    CLI -->|no| ENV{"PIPX_DEFAULT_BACKEND set?"}
    ENV -->|yes| USEENV["use it"]
    ENV -->|no| UV{"uv 0.9.17+ available?<br/>bundled or on PATH"}
    UV -->|yes| USEUV["uv"]
    UV -->|no| PIP["pip + venv"]

    classDef decision fill:#2a9d8f,stroke:#1f7268,color:#fff;
    classDef uv fill:#7c4dff,stroke:#5a34c0,color:#fff;
    classDef pip fill:#3f72af,stroke:#28507d,color:#fff;
    class CLI,ENV,UV decision;
    class USECLI,USEENV,USEUV uv;
    class PIP pip;
    

Choose a backend explicitly

$ pipx install black --backend pip
$ pipx install ruff --backend uv
$ PIPX_DEFAULT_BACKEND=uv pipx install ruff
$ pipx environment --value PIPX_RESOLVED_BACKEND

install, install-all, inject, upgrade, upgrade-all, reinstall, reinstall-all, and run all accept --backend. Switch an installed venv with pipx reinstall NAME --backend uv.

What changes under uv

  • pipx creates venvs with uv venv. The venv contains no pip and no pipx_shared.pth file.

  • pipx runpip runs uv pip <args> --python <venv>/bin/python. uv rejects flags it does not understand rather than dropping them silently.

  • pipx run execs uv tool run; its cache lives in uv’s cache directory. Pass --no-cache to skip it or --refresh to rebuild the cached environment.

  • pipx run script.py execs uv run --active --script script.py for PEP 723 inline scripts, with VIRTUAL_ENV pointing at an environment in pipx’s cache.

  • --cooldown DAYS (or PIPX_COOLDOWN) maps to uv’s --exclude-newer P{DAYS}D. See Dependency cooldown.

  • uv reads your user config (~/.config/uv/uv.toml, %APPDATA%\uv\uv.toml on Windows), the system config (/etc/uv/uv.toml), and a UV_CONFIG_FILE, but no project config from your working directory or the script’s directory. pipx sets UV_PROJECT (--project for uv run --script) to PIPX_HOME, replacing any UV_PROJECT you set, so uv looks for a uv.toml or a pyproject.toml with a [tool.uv] table in PIPX_HOME and each of its parents up to the filesystem root.

  • With the default PIPX_HOME under your home directory, the parents uv searches for project config belong to you or to root. If PIPX_HOME (or PIPX_GLOBAL_HOME) sits below a directory other accounts can write, such as /tmp or a group-writable share, any of them can place a uv.toml there that steers pipx’s uv calls; keep it in a directory only you can write.

  • A --project, --directory or --config-file in --pip-args points uv at other configuration, and pipx records it with the environment. On POSIX, a later upgrade or reinstall refuses to replay it when another account can change the path. See Metadata.

Limitations

  • pipx install pip --backend uv errors: a uv venv has no pip. Use --backend pip.

  • pipx run --backend uv honors [pipx.run] entry points only where it builds a venv, which with --spec means an <app> that differs from the spec’s normalized distribution name, or a spec carrying no name at all. An <app> matching that name goes to uv tool run, which reads console scripts only, so reach for --backend pip to override a console script of the same name.

  • Some --pip-args values have no uv tool run equivalent (--editable, --no-build-isolation); pipx errors instead of dropping them. See Use a private index for which flags uv translates.

  • pipx run --backend uv rejects --system-site-packages, since uv builds the environment. Use --backend pip when you need it.

  • pipx run --backend uv against URL or named-pipe scripts falls back to a pipx-managed venv, because uv run --script reads PEP 723 metadata off disk and runtime-fetched content has no on-disk path. pipx logs a warning.

  • pipx run falls back to a pipx-managed venv when it has to infer the script name: from a VCS URL, a local project path, or a name it normalizes (pipx run pip_search installs pip-search). uv tool run takes that name up front and would guess it from the package, so pipx installs the package first and runs the script it declares. Pass pipx run --spec <spec> <normalized-name> to keep uv’s cache when the package declares a matching console script. pipx installs a spec with no distribution name (a path, a URL, a direct reference) twice, once to learn its name and once into the run venv.

Cache layout

Under the uv backend, pipx run APP caches in UV_CACHE_DIR instead of PIPX_VENV_CACHEDIR, while pipx run script.py keeps the script’s environment in PIPX_VENV_CACHEDIR. Switching the default backend on a host that already used pipx run leaves the old pipx cache behind. Find it with pipx cache dir and remove its environments with pipx cache purge. The 14-day expiry sweep pipx applies to its own cache does not extend to uv’s cache, which uv manages on its own schedule (uv cache clean).

Verify it

$ pipx environment --value PIPX_RESOLVED_BACKEND

It prints uv when pipx will use the uv backend for new venvs.