# uv: Python Package and Project Manager


uv is a fast Python package and project manager, built by Astral (now part of OpenAI), that replaces [pip](https://pydevtools.com/handbook/reference/pip.md), [pip-tools](https://pydevtools.com/handbook/reference/pip-tools.md), [pipx](https://pydevtools.com/handbook/reference/pipx.md), [Poetry](https://pydevtools.com/handbook/reference/poetry.md), [pyenv](https://pydevtools.com/handbook/reference/pyenv.md), and [virtualenv](https://pydevtools.com/handbook/reference/virtualenv.md) with a single tool.

One `uv` binary installs Python interpreters, resolves and locks dependencies, creates {{< term "virtual-environment" "virtual environments" >}}, runs scripts and command-line tools, formats and type-checks code, and builds and publishes packages. It is written in Rust and open source under the MIT and Apache-2.0 licenses.

> [!TIP]
> This page is a command reference for users who already know uv. For a guide that explains what uv is, covers installation, core workflows, benchmarks, and migration from pip and Poetry, see [uv: A Complete Guide](https://pydevtools.com/handbook/explanation/uv-complete-guide.md). For a hands-on first project, see [Create your first Python project](https://pydevtools.com/handbook/tutorial/create-your-first-python-project.md).

## When to use uv

Use uv when you want a single tool for managing Python versions, virtual environments, dependencies, and package publishing instead of combining [pip](https://pydevtools.com/handbook/reference/pip.md), [pyenv](https://pydevtools.com/handbook/reference/pyenv.md), [pipx](https://pydevtools.com/handbook/reference/pipx.md), and others. It is a strong default for new Python projects and for developers who value fast installs and reproducible lockfiles. If your project relies on non-Python scientific libraries, [conda](https://pydevtools.com/handbook/reference/conda.md) may be a [better fit](https://pydevtools.com/handbook/explanation/why-should-i-choose-conda.md); for a comparison with pip, see [What's the difference between pip and uv?](https://pydevtools.com/handbook/explanation/whats-the-difference-between-pip-and-uv.md).

## Why uv?

Traditional Python development involves juggling multiple tools (e.g. [pip](https://pydevtools.com/handbook/reference/pip.md), [pip-tools](https://pydevtools.com/handbook/reference/pip-tools.md), [pipx](https://pydevtools.com/handbook/reference/pipx.md), [poetry](https://pydevtools.com/handbook/reference/poetry.md), [pyenv](https://pydevtools.com/handbook/reference/pyenv.md), [virtualenv](https://pydevtools.com/handbook/reference/virtualenv.md)), each with different interfaces and behaviors. uv unifies these workflows while delivering 10-100x performance improvements over existing solutions. For background on how the ecosystem ended up so fragmented, see [Why are there so many Python packaging tools?](https://pydevtools.com/handbook/explanation/why-are-there-so-many-python-packaging-tools.md).

* Speed: 10-100x faster than traditional Python tools
* Simplicity: One tool for all Python packaging needs
* Standards: Full compatibility with modern Python packaging standards
* Reliability: Reproducible builds with [universal lockfiles](https://pydevtools.com/handbook/explanation/what-is-a-lock-file.md)

## Installation

### Quick Install

```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```
```powershell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```
See [How to install uv](https://pydevtools.com/handbook/how-to/how-to-install-uv.md) for alternative methods and troubleshooting.

## Command Categories

### Project Management

Projects use [pyproject.toml](https://pydevtools.com/handbook/reference/pyproject.toml.md) for configuration and [`uv.lock`](https://pydevtools.com/handbook/how-to/how-to-use-a-uv-lockfile-for-reproducible-python-environments.md) for dependency locking.

```bash
# Initialize new project
uv init my-project

# Add dependencies
uv add requests
uv add --dev pytest  # development dependency

# Remove a dependency
uv remove requests

# Read or update the project version
uv version
uv version 1.2.0
uv version --bump minor

# Resolve and lock dependencies
uv lock

# Install project and dependencies
uv sync

# Run commands in project environment
uv run my-project
uv run pytest

# Display the dependency tree
uv tree

# Export lockfile to requirements.txt format
uv export --format requirements-txt

# Build distributions
uv build

# Publish to PyPI
uv publish
```

See [How to run tests using uv](https://pydevtools.com/handbook/how-to/how-to-run-tests-using-uv.md) for configuring pytest with `uv run`, and [Understanding dependency groups in uv](https://pydevtools.com/handbook/explanation/understanding-dependency-groups-in-uv.md) for how `[dependency-groups]` interacts with `uv sync --group`.

### Workspace Inspection

`uv workspace` inspects a multi-package workspace: its members, their paths on disk, and its resolved metadata.

```bash
# List the members of the workspace
uv workspace list

# Print workspace metadata as JSON
uv workspace metadata

# Print the path of one workspace member
uv workspace dir --package my-library
```

See [How to set up a Python monorepo with uv workspaces](https://pydevtools.com/handbook/how-to/how-to-set-up-a-python-monorepo-with-uv-workspaces.md) for the `[tool.uv.workspace]` layout these commands read.

> [!NOTE]
> `uv workspace metadata` is experimental and prints a preview warning. Pass `--preview-features workspace-metadata` to silence it.

### Script Execution
Run standalone Python scripts with automatic dependency management.

```bash
# Run script with inline dependencies
uv run script.py

# Run with additional dependencies
uv run --with requests script.py

# Add dependencies to script metadata
uv add --script script.py requests
```

#### Inline Script Dependencies
uv allows you to specify dependencies for a script in the script itself, using the `dependencies` key.

Run `uv add --script script.py requests rich` to add the `requests` and `rich` dependencies to your script.


```python
# /// script
# dependencies = ["requests", "rich"]
# requires-python = ">=3.8"
# ///

import requests
from rich import print
```

> [!NOTE]
> Inline script dependencies are a [PEP 723](https://pydevtools.com/handbook/explanation/what-is-pep-723.md) compliant way to specify dependencies for a script.

### Formatting

uv includes a built-in code formatting command powered by [Ruff](https://pydevtools.com/handbook/reference/ruff.md)'s formatter:

```bash
# Format all Python files in the project
uv format

# Check formatting without making changes
uv format --check

# Show what would change
uv format --diff
```

Formatting configuration is read from the project's `pyproject.toml` under `[tool.ruff.format]`, the same settings [Ruff](https://pydevtools.com/handbook/reference/ruff.md) uses directly.

> [!NOTE]
> `uv format` is experimental and prints a preview warning. Its interface may change in future uv releases. For a stable formatting setup today, run [Ruff](https://pydevtools.com/handbook/reference/ruff.md) directly with [uvx](https://pydevtools.com/handbook/reference/uvx.md) `ruff format`.

### Type Checking

`uv check` type-checks the project's Python code using [ty](https://pydevtools.com/handbook/reference/ty.md). By default, all Python files in the project are checked after syncing the virtual environment with the project's dependencies.

```bash
# Type check the current project
uv check

# Pin ty to a specific version
uv check --ty-version 0.0.75

# Type check with a specific dependency group installed
uv check --group typechecking

# Skip syncing the virtual environment before checking
uv check --no-sync
```

For CI integration, see [How to use ty in CI](https://pydevtools.com/handbook/how-to/how-to-use-ty-in-ci.md).

### Security Auditing

`uv audit` checks the project's locked dependencies against the [OSV](https://osv.dev/) (Open Source Vulnerabilities) database and exits with a non-zero status when any are found.

```bash
# Audit the project's locked dependencies
uv audit

# Audit a single PEP 723 script
uv audit --script analysis.py

# Audit a specific dependency group
uv audit --only-group dev

# Ignore a vulnerability by advisory ID
uv audit --ignore GHSA-xxxx-xxxx-xxxx

# Ignore until an upstream fix is published
uv audit --ignore-until-fixed GHSA-xxxx-xxxx-xxxx
```

For a CI walkthrough and a comparison with `pip-audit`, see [How to scan Python dependencies for vulnerabilities](https://pydevtools.com/handbook/how-to/how-to-scan-python-dependencies-for-vulnerabilities.md).

### Tool Management
Install and run Python-based CLI tools in isolated environments.

```bash
# Run tool temporarily
uvx ruff check .

# Install tool globally
uv tool install ruff

# Upgrade tools
uv tool upgrade ruff
uv tool upgrade --all
```

### Python Version Management
Install and manage Python interpreters without relying on system packages or [pyenv](https://pydevtools.com/handbook/reference/pyenv.md).

```bash
# List available and installed Python versions
uv python list

# Install a specific Python version
uv python install 3.12

# Pin the project to a Python version
uv python pin 3.12

# Find where a Python version is installed
uv python find 3.12
```

See [How to install Python with uv](https://pydevtools.com/handbook/how-to/how-to-install-python-with-uv.md) and [How to change the Python version of a uv project](https://pydevtools.com/handbook/how-to/how-to-change-the-python-version-of-a-uv-project.md) for more detail. To make a uv-managed interpreter available as `python` outside a uv project, see [How to add Python to your system path with uv](https://pydevtools.com/handbook/how-to/how-to-add-python-to-your-system-path-with-uv.md). For why a uv-managed interpreter is a safer base than a Homebrew one, see [Should I use Homebrew to install Python?](https://pydevtools.com/handbook/explanation/should-i-use-homebrew-to-install-python.md).

### pip-Compatible Interface
uv provides a drop-in replacement for [pip](https://pydevtools.com/handbook/reference/pip.md)/[pip-tools](https://pydevtools.com/handbook/reference/pip-tools.md) workflows with enhanced performance.

```bash
# Create virtual environment
uv venv

# Install packages
uv pip install requests
uv pip install -r requirements.txt
uv pip install -e .  # editable install

# Generate lockfiles
uv pip compile requirements.in
uv pip compile --universal requirements.in  # cross-platform

# Sync environment with lockfile
uv pip sync requirements.txt

# Inspect an installed environment (works without a pyproject.toml)
uv pip tree --python .venv/bin/python
uv pip tree --invert --package markupsafe --show-version-specifiers
uv pip check
```

Unlike `uv tree`, which reads a project's lockfile, the `uv pip tree` command reads installed packages and accepts any interpreter through `--python`. See [How to inspect a virtual environment you did not create](https://pydevtools.com/handbook/how-to/how-to-inspect-an-existing-virtual-environment.md).

### Index Authentication

`uv auth` stores and retrieves credentials for private package indexes, so a token stays out of `pyproject.toml` and out of shell history.

```bash
# Store credentials for an index
uv auth login https://example.com/simple --username alice --token "$TOKEN"

# Print the stored token for an index
uv auth token https://example.com/simple

# Remove stored credentials
uv auth logout https://example.com/simple

# Show where uv keeps its credentials
uv auth dir
```

See [How to use private package indexes with uv](https://pydevtools.com/handbook/how-to/how-to-use-private-package-indexes-with-uv.md) for wiring an authenticated index into a project.

## Cons

* Still pre-1.0: uv is on the 0.x version line, and minor releases have changed behavior, so pin the uv version in CI rather than tracking the latest release.
* Single-vendor governance: uv is developed by Astral (now part of OpenAI), so its roadmap and eventual commercial model rest with one company rather than a community foundation.
* No plugin system: unlike [Poetry](https://pydevtools.com/handbook/reference/poetry.md), uv exposes no third-party plugin interface, so a workflow it does not cover natively falls back to a separate tool.
