# What's the difference between pip and uv?

[pip](https://pydevtools.com/handbook/reference/pip.md) and [uv](https://pydevtools.com/handbook/reference/uv.md) both install Python packages from [PyPI](https://pydevtools.com/handbook/explanation/what-is-pypi.md), but they solve different problems. pip installs packages. uv manages entire Python projects: dependencies, environments, interpreters, and lockfiles.

## Side-by-side comparison

| | pip | uv |
|---|---|---|
| **Install a package** | `pip install requests` | `uv add requests` |
| **Install from requirements** | `pip install -r requirements.txt` | `uv add -r requirements.txt` |
| **Create a virtual environment** | `python -m venv .venv` | `uv venv` (or automatic with `uv sync`) |
| **Lock dependencies** | `pip lock` (experimental, pip 25.1+) or [pip-tools](https://pydevtools.com/handbook/reference/pip-tools.md) | `uv lock` (built in) |
| **Install from a PEP 751 lockfile** | `pip install -r pylock.toml` (experimental, pip 26.1+) | `uv sync` |
| **Run a script** | `python script.py` (after activating venv) | `uv run script.py` |
| **Run inline-metadata script (PEP 723)** | `pip install --requirements-from-script script.py` (pip 26+) | `uv run script.py` |
| **Pin to a past date** | `pip install --uploaded-prior-to 2024-01-01 ...` (pip 26+); `--uploaded-prior-to P3D` (pip 26.1+) | `exclude-newer = "7 days"` in `uv.lock` |
| **Install Python itself** | Requires [pyenv](https://pydevtools.com/handbook/reference/pyenv.md) or system package | `uv python install 3.12` |
| **Run CLI tools** | Requires [pipx](https://pydevtools.com/handbook/reference/pipx.md) | `uvx ruff check .` |
| **Dependency file** | [requirements.txt](https://pydevtools.com/handbook/reference/requirements.md) | [pyproject.toml](https://pydevtools.com/handbook/reference/pyproject.toml.md) + `uv.lock` |
| **Cross-platform lockfile** | No (`pip lock` targets the current platform only) | Yes |

## Performance

uv resolves and installs dependencies 10-100x faster than pip. The gap comes from parallel downloads, aggressive caching of metadata and artifacts, and a resolver written in a compiled language. Cold installs that take minutes with pip often finish in seconds with uv.

## Environment management

pip operates on whatever Python environment is active. Creating and activating a [virtual environment](https://pydevtools.com/handbook/explanation/what-is-a-virtual-environment.md) requires separate tools ([venv](https://pydevtools.com/handbook/reference/venv.md) or [virtualenv](https://pydevtools.com/handbook/reference/virtualenv.md)):

```bash
python -m venv .venv
source .venv/bin/activate   # macOS/Linux
pip install requests
```

uv creates and manages virtual environments automatically. `uv run` ensures the environment exists and matches the [lockfile](https://pydevtools.com/handbook/explanation/what-is-a-lock-file.md) before executing a command:

```bash
uv add requests
uv run python app.py
```

No activation step, no risk of installing into the wrong environment.

## Dependency tracking

pip installs packages but does not record which were explicitly requested. Keeping a `requirements.txt` in sync with the environment is a manual process, and the file contains no distinction between direct and transitive dependencies.

pip 25.1 added an experimental `pip lock` command that writes [PEP 751](https://pydevtools.com/handbook/explanation/what-is-pep-751.md) `pylock.toml` files, and pip 26.1 added an experimental install side (`pip install -r pylock.toml`). Both are still single-platform: the generated lockfile is only valid for the Python version and platform that produced it. Sharing a lock across macOS and Linux developers still requires [pip-tools](https://pydevtools.com/handbook/reference/pip-tools.md) or a platform-matrix pipeline.

uv tracks dependencies in [pyproject.toml](https://pydevtools.com/handbook/reference/pyproject.toml.md) and pins exact versions in `uv.lock`. Adding or removing a package updates both files automatically. The lockfile is cross-platform by default, and the virtual environment becomes disposable because `uv sync` can rebuild it from the lockfile at any time.

## Scope

pip focuses on package installation. Building a complete workflow still requires combining it with other tools:

- [venv](https://pydevtools.com/handbook/reference/venv.md) or [virtualenv](https://pydevtools.com/handbook/reference/virtualenv.md) for environments
- [pip-tools](https://pydevtools.com/handbook/reference/pip-tools.md) for cross-platform dependency locking (pip's own `pip lock` covers a single platform)
- [pyenv](https://pydevtools.com/handbook/reference/pyenv.md) for Python version management
- [pipx](https://pydevtools.com/handbook/reference/pipx.md) for isolated CLI tools

uv replaces all of these with a single binary. It handles Python version management, virtual environments, dependency locking, CLI tool execution (`uvx`), project scaffolding (`uv init`), and package publishing (`uv publish`).

## When pip is the right choice

pip ships with Python and requires no extra installation. It remains a reasonable default for quick experiments, CI images that already have it pre-installed, or projects locked into a [requirements.txt](https://pydevtools.com/handbook/reference/requirements.md) workflow. pip 26.0 (January 2026) strengthened that baseline further by adding `--requirements-from-script` for [PEP 723](https://pydevtools.com/handbook/explanation/what-is-pep-723.md) inline scripts and `--uploaded-prior-to` for datetime-based package filtering, so several workflows that once required uv now work with pip alone. uv still provides a [pip-compatible interface](https://pydevtools.com/handbook/explanation/why-use-native-uv-over-uv-pip.md) (`uv pip install`) that drops into existing pip-based workflows with no structural changes, giving an immediate speed boost.

## Switching from pip to uv

For existing projects with a `requirements.txt`, migration takes a few commands:

```bash
uv init --bare
uv add -r requirements.txt
```

See [How to migrate from requirements.txt to pyproject.toml with uv](https://pydevtools.com/handbook/how-to/migrate-requirements.txt.md) for the full process including dev dependencies and cleanup.

## Related

- [uv reference](https://pydevtools.com/handbook/reference/uv.md) documents all uv commands
- [pip reference](https://pydevtools.com/handbook/reference/pip.md) covers pip's capabilities
- [Did pip 26 close the gap with uv?](https://pydevtools.com/blog/did-pip-26-close-the-gap-with-uv.md) audits the pip 25 and 26 releases that landed several uv features
- [Why use native uv commands instead of uv pip](https://pydevtools.com/handbook/explanation/why-use-native-uv-over-uv-pip.md) compares uv's two interfaces
- [Why choose pyproject.toml over requirements.txt?](https://pydevtools.com/handbook/explanation/pyproject-vs-requirements.md) explains the benefits of declarative dependency management
- [How to install uv](https://pydevtools.com/handbook/how-to/how-to-install-uv.md) covers installation on all platforms
- [Create your first Python project](https://pydevtools.com/handbook/tutorial/create-your-first-python-project.md) walks through starting a new uv project
