###################
 Use the uv backend
###################

Make pipx use `uv <https://github.com/astral-sh/uv>`_ to create virtual environments and install packages in place of
`pip <https://pip.pypa.io/>`__ and venv. The CLI surface stays the same.

For why uv is faster and how pipx compares to Astral's standalone ``uv tool``, see :doc:`../explanation/comparisons`.

******************
 Make uv available
******************

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

.. code-block:: console

    $ 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
*************************

.. mermaid::

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

.. code-block:: console

    $ 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
  <https://peps.python.org/pep-0723/>`__ 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 :doc:`Dependency cooldown
  <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 :doc:`Metadata <../reference/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 :doc:`use-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
**********

.. code-block:: console

    $ pipx environment --value PIPX_RESOLVED_BACKEND

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