# uv: A Complete Guide to Python's Fastest Package Manager


[uv](https://pydevtools.com/handbook/reference/uv.md) is a fast, all-in-one command-line tool for Python development. Built by [OpenAI](https://astral.sh), it manages Python interpreters, virtual environments, dependencies, lockfiles, and command-line tools from a single binary, replacing pip, pyenv, pipx, virtualenv, and pip-tools. It installs packages several times faster than pip and creates virtual environments in milliseconds.

> [!NOTE]
> Already familiar with uv and looking for a quick command reference? See the [uv reference page](https://pydevtools.com/handbook/reference/uv.md).

## What uv does

uv ships as a standalone binary with no Python dependency, so you can bootstrap an entire Python development environment from scratch. One install, one CLI, one mental model. It comes from [OpenAI](https://astral.sh), the same team behind [Ruff](https://pydevtools.com/handbook/reference/ruff.md) and [ty](https://pydevtools.com/handbook/reference/ty.md).

uv achieves large speedups over [pip](https://pydevtools.com/handbook/reference/pip.md) through aggressive caching, parallel downloads, and an optimized dependency resolver written in Rust. The [speed comparison](#how-fast-is-uv) shows the gap: installing 23 packages from a warm cache takes pip 6.6 seconds and uv 0.12 seconds.

uv aligns with modern Python packaging standards. It uses [pyproject.toml](https://pydevtools.com/handbook/reference/pyproject.toml.md) for project metadata following [PEP 621](https://pydevtools.com/handbook/explanation/what-is-pep-621-compatibility.md), generates cross-platform lockfiles, and works with standard [build backends](https://pydevtools.com/handbook/explanation/what-is-a-build-backend.md). Projects created with uv remain compatible with pip and other Python tools.

Before uv, the same set of capabilities required combining [pyenv](https://pydevtools.com/handbook/reference/pyenv.md) for interpreter management, [virtualenv](https://pydevtools.com/handbook/reference/virtualenv.md) for environment isolation, [pip-tools](https://pydevtools.com/handbook/reference/pip-tools.md) for dependency locking, and [pipx](https://pydevtools.com/handbook/reference/pipx.md) for CLI tools. [Poetry](https://pydevtools.com/handbook/reference/poetry.md) unified some of these but historically used non-standard metadata (Poetry 2.0, released January 2025, added PEP 621 support) and has no built-in Python version management.

For a deeper look at why this fragmentation happened and how uv fits in, see [Why are there so many Python packaging tools?](https://pydevtools.com/handbook/explanation/why-are-there-so-many-python-packaging-tools.md) and [Why you should try uv if you use Python](https://pydevtools.com/handbook/explanation/why-you-should-try-uv-if-you-use-python.md).

## How fast is uv?

The speed claims are easy to verify. Here are timed comparisons of uv 0.11.18 against pip 26.0 on the same machine (Apple Silicon, Python 3.14).

### Virtual environment creation

`python -m venv` takes a little over a second. `uv venv` finishes in about 10 milliseconds.

```console
$ time python -m venv .venv
python -m venv .venv  0.96s user 0.16s system  1.150 total

$ time uv venv .venv
Using CPython 3.14.4
Creating virtual environment at: .venv
uv venv .venv  0.00s user 0.00s system  0.008 total
```

### Installing packages (cold cache)

With no cached wheels, installing five libraries (boto3, requests, pandas, fastapi, sqlalchemy) and their 23 total dependencies:

```console
$ time pip install boto3 requests pandas fastapi sqlalchemy
...
Successfully installed 23 packages
pip install  5.10s user 1.21s system  8.889 total

$ time uv pip install boto3 requests pandas fastapi sqlalchemy
Resolved 23 packages in 298ms
Prepared 23 packages in 797ms
Installed 23 packages in 53ms
uv pip install  0.29s user 0.58s system  1.187 total
```

pip: **8.9 seconds**. uv: **1.2 seconds**. About 7x faster on a cold cache, where both tools spend most of their time downloading wheels over the network.

### Reinstalling packages (warm cache)

The warm-cache scenario reflects CI pipelines where layers are cached or local development where you recreate an environment:

```console
$ time pip install boto3 requests pandas fastapi sqlalchemy
...
Successfully installed 23 packages
pip install  4.91s user 0.99s system  6.591 total

$ time uv pip install boto3 requests pandas fastapi sqlalchemy
Resolved 23 packages in 5ms
Installed 23 packages in 78ms
uv pip install  0.03s user 0.13s system  0.116 total
```

pip: **6.6 seconds**. uv: **0.12 seconds**. Roughly 55x faster. uv's cache stores pre-built wheels and uses hard links to avoid copying files into the virtual environment, so "installing" cached packages is nearly instantaneous.

### Summary

| Operation | pip | uv | Speedup |
|---|---|---|---|
| Create virtual environment | 1.15s | 0.01s | **~115x** |
| Install 23 packages (cold cache) | 8.9s | 1.2s | **~7x** |
| Install 23 packages (warm cache) | 6.6s | 0.12s | **~55x** |

These numbers come from a single machine. Results will vary by hardware, network speed, and package size. The cold-cache gap is smaller because both tools are bottlenecked on the network; the warm-cache and environment-creation gaps show where uv's parallel downloads, compiled resolver, and hard-link caching pay off. The pattern holds across environments.

## Installation

uv ships as a standalone binary with no Python dependency. For full instructions, see [How to install uv](https://pydevtools.com/handbook/how-to/how-to-install-uv.md). The recommended approach is the official installer:

```bash
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```

Alternative methods:

```bash
# Homebrew (macOS)
brew install uv

# pip (if Python is already installed)
pip install uv
```

After installing, confirm it works:

```bash
uv --version
```

Platform-specific details are covered in the dedicated how-to guides for [macOS](https://pydevtools.com/handbook/how-to/how-to-install-uv-on-macos.md), [Linux](https://pydevtools.com/handbook/how-to/how-to-install-uv-on-linux.md), and [Windows](https://pydevtools.com/handbook/how-to/how-to-install-uv-on-windows.md). To keep uv current, see [How to upgrade uv](https://pydevtools.com/handbook/how-to/how-to-upgrade-uv.md).

## Core workflows

### Managing Python versions

uv can install and manage multiple Python interpreters without pyenv or system package managers.

```bash
# Install a specific Python version
uv python install 3.12

# List available versions
uv python list

# Install multiple versions for testing
uv python install 3.11 3.12 3.13
```

> [!TIP]
> `uv run` and `uv sync` automatically download the Python version specified in your `pyproject.toml` if it isn't already installed. Every developer gets the same interpreter version without manual setup.

Unlike pyenv, which compiles Python from source (a process that can take minutes and requires build dependencies), uv downloads prebuilt binaries. `uv python install` finishes in seconds. uv stores these interpreters in a shared cache, so multiple projects using the same Python version share a single installation.

You can pin a project to a specific Python version with a [`.python-version` file](https://pydevtools.com/handbook/explanation/what-is-a-python-version-file.md):

```bash
uv python pin 3.12
```

This writes a `.python-version` file that uv (and other tools) respect. When a collaborator clones the project and runs `uv sync`, uv reads this file and installs the correct interpreter automatically.

To make a uv-installed Python available outside of uv projects (for example, so `python3` resolves to it in your shell), 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 a side-by-side comparison with pyenv, read [How do pyenv and uv compare for Python interpreter management?](https://pydevtools.com/handbook/explanation/how-do-pyenv-and-uv-compare-for-python-interpreter-management.md). If you are currently using pyenv, the guide [How to switch from pyenv to uv](https://pydevtools.com/handbook/how-to/how-to-switch-from-pyenv-to-uv-for-managing-python-versions.md) walks through the migration step by step.

### Creating and managing projects

`uv init` scaffolds a new project with a `pyproject.toml`. The virtual environment and lockfile are created when you first run `uv sync` or `uv add`.

```bash
# Create a new project
uv init my-project
cd my-project

# Add dependencies
uv add requests
uv add pandas numpy

# Add development dependencies
uv add --dev pytest ruff

# Install everything (creates/updates .venv and uv.lock)
uv sync

# Run a command inside the project environment
uv run python main.py
```

> [!NOTE]
> `uv.lock` pins every direct and transitive dependency to an exact version, ensuring reproducible installs across machines. Unlike `pip freeze` output, uv's lockfile is cross-platform by default.

uv supports two project types out of the box: applications and libraries. An application (the default) suits web services, scripts, and data pipelines. A library is intended for packages you publish to [PyPI](https://pydevtools.com/handbook/explanation/what-is-pypi.md). The difference affects how uv generates your `pyproject.toml` and how it handles version constraints. Read [Understanding uv init project types](https://pydevtools.com/handbook/explanation/understanding-uv-init-project-types.md) for guidance on which to choose.

```bash
# Create a library project
uv init --lib my-package

# Create an application (default)
uv init my-app
```

uv also handles [optional dependencies and dependency groups](https://pydevtools.com/handbook/explanation/what-are-optional-dependencies-and-dependency-groups.md), letting you define sets of extras like `[project.optional-dependencies]` for features or `[dependency-groups]` for development tools. For the mechanics of installing groups with `uv sync --group`, see [Understanding dependency groups in uv](https://pydevtools.com/handbook/explanation/understanding-dependency-groups-in-uv.md).

For a hands-on walkthrough of creating a project from scratch, follow the tutorial [Create your first Python project](https://pydevtools.com/handbook/tutorial/create-your-first-python-project.md). For libraries with native extensions, see [Build a Python library with a C extension](https://pydevtools.com/handbook/tutorial/build-a-python-library-with-a-c-extension.md) or [Build a Python library with a Rust extension](https://pydevtools.com/handbook/tutorial/build-a-python-library-with-a-rust-extension.md).

Changing your project's Python version is straightforward:

```bash
uv python pin 3.13
uv sync
```

See [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 details.

Lockfiles are central to reproducible environments. `uv.lock` pins every transitive dependency to an exact version and records platform-specific resolution so that `uv sync` produces identical environments on macOS, Linux, and Windows.

For more on how lockfiles work and why they matter, see [What is a lockfile?](https://pydevtools.com/handbook/explanation/what-is-a-lock-file.md) and [How to use a uv lockfile for reproducible Python environments](https://pydevtools.com/handbook/how-to/how-to-use-a-uv-lockfile-for-reproducible-python-environments.md).

### Running scripts

`uv run` executes a Python script after ensuring the project's virtual environment is up to date. For one-off scripts that aren't part of a project, you can specify dependencies inline using [PEP 723](https://pydevtools.com/handbook/explanation/what-is-pep-723.md) metadata:

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

import requests
from rich import print

response = requests.get("https://api.github.com/zen")
print(response.text)
```

Run it with:

```bash
uv run script.py
```

uv reads the inline metadata, creates a temporary environment with the declared dependencies, and executes the script. No project setup, no manual virtualenv. The environment is cached, so running the same script a second time skips dependency installation entirely.

You can also pass dependencies on the command line without modifying the script:

```bash
uv run --with requests script.py
```

This is useful for quick experiments or when running someone else's script with an additional package. You can even specify a Python version:

```bash
uv run --python 3.11 script.py
```

For interactive work, uv launches a REPL with your project's dependencies available:

```bash
uv run python
```

See [How to run a Python REPL with uv](https://pydevtools.com/handbook/how-to/how-to-run-a-python-repl-with-uv.md), [How to run the IPython shell in your uv project](https://pydevtools.com/handbook/how-to/how-to-run-the-ipython-shell-in-your-uv-project.md), and [How to run a Jupyter Notebook with uv](https://pydevtools.com/handbook/how-to/jupyter-notebook-with-uv.md). For test suites, [How to run tests using uv](https://pydevtools.com/handbook/how-to/how-to-run-tests-using-uv.md) covers pytest configuration and common workflows.

### Managing CLI tools

Many Python packages ship command-line tools: [Ruff](https://pydevtools.com/handbook/reference/ruff.md), [Black](https://pydevtools.com/handbook/reference/black.md), [Jupyter](https://pydevtools.com/handbook/how-to/jupyter-notebook-with-uv.md), and dozens more. uv provides two ways to run them:

`uvx` runs a tool in a temporary, isolated environment. No installation required. The tool is cached for fast subsequent runs:

```bash
uvx ruff check .
uvx black --check .
```

`uv tool install` installs a tool permanently so it's available as a regular command:

```bash
uv tool install ruff
ruff check .  # now available directly
```

This replaces [pipx](https://pydevtools.com/handbook/reference/pipx.md) for most use cases. Each tool gets its own isolated environment, so tools never conflict with each other or with your project's dependencies.

You can also upgrade installed tools:

```bash
uv tool upgrade ruff
uv tool upgrade --all
```

The distinction between `uvx` and `uv tool install` maps to how you use the tool. If you run it occasionally or want to try it once, use `uvx`. If you use it daily and want it on your PATH, use `uv tool install`. Both approaches isolate the tool's dependencies from your project.

For a detailed comparison of when to use `uv run` versus `uvx`, see [When to use uv run vs uvx](https://pydevtools.com/handbook/explanation/when-to-use-uv-run-vs-uvx.md).

### Formatting code

uv includes a `uv format` command that formats Python code using [Ruff](https://pydevtools.com/handbook/reference/ruff.md)'s formatter. This follows the same pattern as `cargo fmt` in Rust: the formatter is a separate tool under the hood, but uv provides a convenient interface so you don't need to think about it as a separate dependency. uv downloads and caches the Ruff version it needs the first time you run it.

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

# Check formatting without making changes
uv format --check

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

Formatting settings are read from `[tool.ruff.format]` in your `pyproject.toml`. If you already use [Ruff](https://pydevtools.com/handbook/reference/ruff.md) for formatting, `uv format` uses the same configuration.

> [!NOTE]
> `uv format` is experimental as of uv 0.11.18 and prints a preview warning. Its interface may change. For a stable formatting setup today, run Ruff directly (`uvx ruff format`) or pin a uv version in CI.

### pip compatibility

If you have existing workflows built around pip and requirements files, uv provides a drop-in compatible interface:

```bash
# Install from requirements.txt
uv pip install -r requirements.txt

# Install a package
uv pip install requests

# Generate a locked requirements file from loose constraints
uv pip compile requirements.in -o requirements.txt

# Sync an environment to match a requirements file exactly
uv pip sync requirements.txt
```

> [!TIP]
> These commands produce identical results to their pip equivalents but run significantly faster. Swap `pip` for `uv pip` in your CI scripts for an immediate speed boost without changing your project structure.

`uv pip compile` takes a loose `requirements.in` file (or `pyproject.toml`) and produces a fully resolved `requirements.txt` with pinned versions and hashes. The `--universal` flag generates a single requirements file that works across platforms, a feature [pip-tools](https://pydevtools.com/handbook/reference/pip-tools.md) does not offer.

For a full comparison of pip and uv, see [What's the difference between pip and uv?](https://pydevtools.com/handbook/explanation/whats-the-difference-between-pip-and-uv.md). To migrate an existing requirements.txt-based project to uv's native project format, follow [How to migrate from requirements.txt to pyproject.toml with uv](https://pydevtools.com/handbook/how-to/migrate-requirements.txt.md).

You can also use pip inside a uv-managed virtual environment if needed. See [How to use pip in a uv virtual environment](https://pydevtools.com/handbook/how-to/how-to-use-pip-in-a-uv-virtual-environment.md).

## What's new in uv

uv ships releases roughly weekly, so the command set keeps growing. A few recent additions are worth knowing about; the [uv changelog](https://github.com/astral-sh/uv/releases) tracks every release.

- **`uv format`** wraps Ruff's formatter so you can format a project without adding Ruff as an explicit dependency. It is experimental as of 0.11.18 and prints a preview warning. See [Formatting code](#formatting-code).
- **`uv audit`** scans a project's locked dependencies for known vulnerabilities and adverse project statuses such as yanked or deprecated releases. It is also experimental. Pair it with [How to protect against Python supply chain attacks with uv](https://pydevtools.com/handbook/how-to/how-to-protect-against-python-supply-chain-attacks-with-uv.md).
- **`uv auth`** manages credentials for package indexes through `uv auth login`, `logout`, and `token`, replacing hand-edited netrc files for private registries. See [How to use private package indexes with uv](https://pydevtools.com/handbook/how-to/how-to-use-private-package-indexes-with-uv.md).
- **`uv_build`** is uv's own [build backend](https://pydevtools.com/handbook/explanation/what-is-a-build-backend.md) and the default for packaged projects since July 2025, covered under [Advanced topics](#advanced-topics).
- **`uv python upgrade`** upgrades a uv-managed interpreter to the latest patch release in place. See [How to keep Python up to date with uv python upgrade](https://pydevtools.com/handbook/how-to/how-to-keep-python-up-to-date-with-uv-python-upgrade.md).

For reproducible resolutions that ignore packages published after a cutoff date, the `--exclude-newer` flag is covered in [How to use exclude-newer for reproducible Python environments](https://pydevtools.com/handbook/how-to/how-to-use-exclude-newer-for-reproducible-python-environments.md).

## How uv compares to alternatives

| Feature | uv | [pip](https://pydevtools.com/handbook/reference/pip.md) | [Poetry](https://pydevtools.com/handbook/reference/poetry.md) | [pyenv](https://pydevtools.com/handbook/reference/pyenv.md) | [pipx](https://pydevtools.com/handbook/reference/pipx.md) |
|---|---|---|---|---|---|
| Install packages | Yes | Yes | Yes | No | No |
| Lockfile | Yes | No | Yes | No | No |
| Virtual environments | Yes | No | Yes | No | Yes (per-tool) |
| Python version management | Yes | No | No | Yes | No |
| Run CLI tools | Yes | No | No | No | Yes |
| Script execution | Yes | No | No | No | No |
| Performance | [15-50x faster](#how-fast-is-uv) | Baseline | Pure Python | Compiles from source | Pure Python |
| Standards compliance | pyproject.toml (PEP 621) | requirements.txt | pyproject.toml (PEP 621 in 2.0+) | N/A | N/A |

For in-depth comparisons:

- [What's the difference between pip and uv?](https://pydevtools.com/handbook/explanation/whats-the-difference-between-pip-and-uv.md)
- [How do uv and Poetry compare?](https://pydevtools.com/handbook/explanation/how-do-uv-and-poetry-compare.md)
- [How do pyenv and uv compare?](https://pydevtools.com/handbook/explanation/how-do-pyenv-and-uv-compare-for-python-interpreter-management.md)

## When to use uv

New projects: uv is the strongest default for new Python projects today. A single `uv init` gives you a standards-compliant `pyproject.toml`, a lockfile, and a virtual environment. No other tool setup required. uv is still on 0.x version numbers, but its core project, packaging, and pip-compatible commands are stable and run in production CI pipelines across the ecosystem; pin a specific uv version in CI for reproducibility and treat the experimental `uv format` and `uv audit` commands accordingly.

Existing pip/requirements.txt projects: Start by replacing `pip install` with `uv pip install` for an immediate speed boost. When ready, migrate to `pyproject.toml` with `uv init` and `uv add`. The guide [How to migrate from requirements.txt to pyproject.toml with uv](https://pydevtools.com/handbook/how-to/migrate-requirements.txt.md) covers this process.

Existing Poetry projects: uv supports the same `pyproject.toml`-based workflow with better performance and standards compliance. See [How to migrate from Poetry to uv](https://pydevtools.com/handbook/how-to/how-to-migrate-from-poetry-to-uv.md).

CI/CD pipelines: uv's speed advantage is most dramatic in CI, where environments are recreated on every run. Its caching and fast resolution cut minutes from pipeline execution. See [Setting up GitHub Actions with uv](https://pydevtools.com/handbook/tutorial/setting-up-github-actions-with-uv.md) and [How to use uv in a Dockerfile](https://pydevtools.com/handbook/how-to/how-to-use-uv-in-a-dockerfile.md).

One-off scripts and automation: Inline script dependencies (PEP 723) make uv a strong choice for standalone scripts. You can share a single `.py` file with its dependencies declared inside, and anyone with uv installed can run it without further setup. This is useful for data processing scripts, automation tasks, and quick prototypes.

> [!IMPORTANT]
> If your project depends on non-Python libraries (C/Fortran extensions for scientific computing, CUDA binaries), [conda](https://pydevtools.com/handbook/reference/conda.md) manages those cross-language dependencies in ways uv cannot. See [Why should I choose conda?](https://pydevtools.com/handbook/explanation/why-should-i-choose-conda.md) for guidance. For installing GPU-accelerated stacks like RAPIDS with uv directly, see [How to install RAPIDS with uv](https://pydevtools.com/handbook/how-to/how-to-install-rapids-with-uv.md).

Some organizations with established Poetry workflows may prefer to stay with Poetry if the migration cost outweighs the benefits; see [How do uv and Poetry compare?](https://pydevtools.com/handbook/explanation/how-do-uv-and-poetry-compare.md) for a balanced assessment.

## Editor and tool integration

uv creates ordinary [virtual environments](https://pydevtools.com/handbook/explanation/what-is-a-virtual-environment.md) in `.venv`, following the same structure as [venv](https://pydevtools.com/handbook/reference/venv.md) and virtualenv. Most editors detect this directory automatically and configure the Python interpreter path. Some need manual configuration, particularly when the `.venv` directory is in a non-standard location or when using workspace setups.

- [How to configure VS Code for a uv project](https://pydevtools.com/handbook/how-to/how-to-configure-vs-code-for-a-uv-project.md)
- [How to configure Cursor for a uv project](https://pydevtools.com/handbook/how-to/how-to-configure-cursor-for-a-uv-project.md)
- [How to configure Cursor rules to use uv](https://pydevtools.com/handbook/how-to/how-to-configure-cursor-rules-to-use-uv.md)
- [How to configure Claude Code to use uv](https://pydevtools.com/handbook/how-to/how-to-configure-claude-code-to-use-uv.md)
- [How to create a new Python project with Codex](https://pydevtools.com/handbook/how-to/how-to-create-a-new-python-project-with-codex.md)

For project-scaffolding instructions you can paste into a CLAUDE.md or session prompt, see the [Modern Python Project Setup Guide for AI Assistants](https://pydevtools.com/handbook/explanation/modern-python-project-setup-guide-for-ai-assistants.md).

For task running, see [How to use Poe the Poet as a task runner with uv](https://pydevtools.com/handbook/how-to/how-to-use-poe-the-poet-as-a-task-runner-with-uv.md).

## Testing with uv

uv pairs well with [pytest](https://pydevtools.com/handbook/reference/pytest.md) for running tests:

```bash
uv add --dev pytest
uv run pytest
```

For testing across multiple Python versions, `uv run --python` downloads any missing version on demand:

```bash
uv run --python 3.11 pytest
uv run --python 3.12 pytest
uv run --python 3.13 pytest
```

Guides:

- [How to run tests using uv](https://pydevtools.com/handbook/how-to/how-to-run-tests-using-uv.md)
- [How to fix common pytest errors with uv](https://pydevtools.com/handbook/how-to/how-to-fix-common-pytest-errors-with-uv.md)
- [How to test against multiple Python versions using uv](https://pydevtools.com/handbook/how-to/how-to-test-against-multiple-python-versions-using-uv.md)
- [Setting up testing with pytest and uv (tutorial)](https://pydevtools.com/handbook/tutorial/setting-up-testing-with-pytest-and-uv.md)

## Advanced topics

Virtual environment customization: By default, uv creates a `.venv` directory in your project root. Some workflows require placing the environment elsewhere, for example when working with Docker volumes or shared filesystems where the default location causes performance issues. See [How to customize uv's virtual environment location](https://pydevtools.com/handbook/how-to/how-to-customize-uvs-virtual-environment-location.md).

Docker: uv's standalone binary and fast installs make it well-suited for container builds. Because uv has no runtime dependency on Python, you can copy the binary into a Docker image and use it immediately. Combined with its caching behavior and fast resolution, this can cut Docker build times from minutes to seconds when dependencies haven't changed. See [How to use uv in a Dockerfile](https://pydevtools.com/handbook/how-to/how-to-use-uv-in-a-dockerfile.md).

Dynamic versioning: For packages that derive their version from git tags or other sources, see [How to add dynamic versioning to uv projects](https://pydevtools.com/handbook/how-to/how-to-add-dynamic-versioning-to-uv-projects.md).

Build backend: when you create a packaged project (`uv init --package` or `uv init --lib`), uv defaults to `uv_build`, uv's own [build backend](https://pydevtools.com/handbook/explanation/what-is-a-build-backend.md) (stable since July 2025). Earlier versions defaulted to [Hatchling](https://pydevtools.com/handbook/reference/hatch.md). A plain `uv init` application has no build backend until you add one. Either way, `uv build` produces standard [wheels](https://pydevtools.com/handbook/reference/wheel.md) and [sdists](https://pydevtools.com/handbook/reference/sdist.md) that work with pip and any PEP 517-compatible tool. For background on the original Hatchling default, see [Why did uv originally use Hatch as a build backend?](https://pydevtools.com/handbook/explanation/why-does-uv-use-hatch-as-a-backend.md).

Publishing packages: Once you've built a package, uv can publish it to PyPI:

```bash
uv build
uv publish
```

For a walkthrough of the full publishing process, see [Publishing your first Python package to PyPI](https://pydevtools.com/handbook/tutorial/publishing-your-first-python-package-to-pypi.md).

## Troubleshooting

Most uv errors have clear messages that point to the fix. Two common issues new users encounter:

> [!WARNING]
> The **"No `project` Table Found"** error occurs when you run `uv add` or `uv sync` in a directory without a `pyproject.toml`, or with a `pyproject.toml` that lacks a `[project]` section. See [How to fix "No project Table Found" error in uv](https://pydevtools.com/handbook/how-to/how-to-fix-no-project-table-found-error-in-uv.md).

> [!WARNING]
> Python version incompatibility errors happen when your `pyproject.toml` specifies a `requires-python` range that conflicts with the installed interpreter or with a dependency's requirements. See [How to fix Python version incompatibility errors in uv](https://pydevtools.com/handbook/how-to/how-to-fix-python-version-incompatibility-errors-in-uv.md).

## Learn more

### Tutorials
- [Create your first Python project](https://pydevtools.com/handbook/tutorial/create-your-first-python-project.md)
- [Run your first Python script with uv](https://pydevtools.com/handbook/tutorial/how-to-run-your-first-python-script.md)
- [Setting up testing with pytest and uv](https://pydevtools.com/handbook/tutorial/setting-up-testing-with-pytest-and-uv.md)
- [Setting up GitHub Actions with uv](https://pydevtools.com/handbook/tutorial/setting-up-github-actions-with-uv.md)

### How-to guides
- [How to install uv](https://pydevtools.com/handbook/how-to/how-to-install-uv.md)
- [How to install Python with uv](https://pydevtools.com/handbook/how-to/how-to-install-python-with-uv.md)
- [How to run a Jupyter Notebook with uv](https://pydevtools.com/handbook/how-to/jupyter-notebook-with-uv.md)
- [How to migrate from Poetry to uv](https://pydevtools.com/handbook/how-to/how-to-migrate-from-poetry-to-uv.md)
- [How to migrate from requirements.txt to pyproject.toml with uv](https://pydevtools.com/handbook/how-to/migrate-requirements.txt.md)

### Explanations
- [Why you should try uv if you use Python](https://pydevtools.com/handbook/explanation/why-you-should-try-uv-if-you-use-python.md)
- [What's the difference between pip and uv?](https://pydevtools.com/handbook/explanation/whats-the-difference-between-pip-and-uv.md)
- [How do uv and Poetry compare?](https://pydevtools.com/handbook/explanation/how-do-uv-and-poetry-compare.md)
- [Understanding uv init project types](https://pydevtools.com/handbook/explanation/understanding-uv-init-project-types.md)
- [When to use uv run vs uvx](https://pydevtools.com/handbook/explanation/when-to-use-uv-run-vs-uvx.md)
- [Why are there so many Python packaging tools?](https://pydevtools.com/handbook/explanation/why-are-there-so-many-python-packaging-tools.md)

### Reference
- [uv reference page](https://pydevtools.com/handbook/reference/uv.md)
- [uv official documentation](https://docs.astral.sh/uv/)
