Python projects often begin with a familiar sequence: create a virtual environment, upgrade pip, install packages, and save dependencies in a requirements.txt file. That workflow works, but it can involve several separate tools and commands.

uv is a fast Python package and project manager created by Astral. It can replace much of the day-to-day workflow around pip, venv, and tools such as pipx, while also generating a lockfile that records the exact dependency versions selected for a project.

Why Use uv?

uv is useful when you want a simpler and more reproducible Python workflow.

  • It creates and manages virtual environments for projects.
  • It installs packages quickly using a global cache.
  • It manages project dependencies in pyproject.toml.
  • It generates uv.lock so installations can be reproduced.
  • It can run commands in a project environment without manual activation.
  • It can install and run standalone Python tools.

uv does not remove the need to understand Python environments. Instead, it puts common environment and dependency operations behind a consistent command-line interface.

Install uv

On Windows, install uv with PowerShell:

powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

On macOS or Linux, use the shell installer:

curl -LsSf https://astral.sh/uv/install.sh | sh

You can also install uv with a package manager. For example, Homebrew users can run:

brew install uv

Confirm that the installation works:

uv --version

Restart your terminal if the uv command is not found immediately after installation.

Create a Python Project

Create a new project with uv init:

mkdir weather-app
cd weather-app
uv init

This creates a basic project structure, including a pyproject.toml file and a Python entry point. The exact files may vary depending on the options you provide, but pyproject.toml is the central configuration file for the project.

You can specify a project name directly:

uv init --name weather-app

To start with a particular Python version, use the --python option:

uv init --python 3.12

If that Python version is not installed locally, uv can download a managed copy when needed.

Add and Remove Dependencies

Add a package with uv add:

uv add requests

This updates pyproject.toml, resolves compatible versions, and updates uv.lock. Add several packages at once when they belong to the same feature:

uv add pandas matplotlib

Development-only dependencies can be placed in a development dependency group:

uv add --dev pytest ruff

Remove a package with:

uv remove requests

To install a specific version range, include it in the requirement:

uv add "django>=5.0,<6"

Run Your Project

Use uv run to execute a command in the project environment:

uv run main.py

For a package configured as a project script, run its script name instead. For example, if pyproject.toml contains a script named start, use:

uv run start

You can also run development tools without manually activating the virtual environment:

uv run pytest
uv run ruff check .

This is one of the most convenient parts of the workflow. The command makes it clear which project environment should provide the tool and its dependencies.

Understand uv.lock and uv sync

The uv.lock file records the resolved versions of the project’s direct and transitive dependencies. Commit it to version control so other developers and deployment systems can reproduce the same environment.

To synchronize the environment with the project files and lockfile, run:

uv sync

For a reproducible installation in continuous integration, use the locked dependencies without changing the lockfile:

uv sync --locked

When pyproject.toml changes, run uv lock or uv sync to resolve the updated dependency set and review the resulting lockfile changes.

Use a Virtual Environment Directly

Most project workflows do not require manual activation, but uv can create a virtual environment explicitly:

uv venv

The default environment is created in a .venv directory. Activate it using the command for your operating system if you want to work with ordinary python and pip commands.

Windows PowerShell:

.venv\Scripts\Activate.ps1

macOS and Linux:

source .venv/bin/activate

For a project managed with pyproject.toml, prefer uv add, uv remove, uv sync, and uv run so the configuration and lockfile stay up to date.

Install Standalone Python Tools

uv can install command-line tools in isolated environments. For example:

uv tool install ruff

You can also run a tool without permanently installing it:

uvx ruff check .

This is helpful for occasional tools or for trying a command before adding it to a project.

A Practical Daily Workflow

A small project might use this sequence:

uv init --python 3.12
uv add requests
uv add --dev pytest ruff
uv run pytest
uv run ruff check .
uv sync --locked

Commit both pyproject.toml and uv.lock. Do not commit .venv, because it is a local generated environment and can be recreated with uv sync.

Migrating from requirements.txt

If an existing project already has a requirements.txt file, create or enter the project directory and add the listed requirements:

uv init
uv add -r requirements.txt

Review the resulting pyproject.toml and uv.lock files before removing the old requirements file. If deployment or another tool still expects requirements.txt, keep generating or maintaining that file until the rest of the project has moved to the new workflow.

Common Commands Cheat Sheet

CommandPurpose
uv initCreate a Python project
uv python install 3.12Install a managed Python version
uv venvCreate a virtual environment
uv add packageAdd a project dependency
uv add --dev packageAdd a development dependency
uv remove packageRemove a project dependency
uv syncSynchronize the environment with the project
uv sync --lockedSynchronize without changing the lockfile
uv run commandRun a command in the project environment
uv lockResolve and update the lockfile
uv tool install toolInstall a standalone Python tool
uvx toolRun a tool in a temporary environment

Final Thoughts

uv brings project initialization, Python versions, virtual environments, dependencies, lockfiles, and command execution into one workflow. It is a strong choice for new Python projects and a practical way to simplify existing projects that rely on several separate commands.

The most important habit is to treat pyproject.toml as the project’s dependency declaration and uv.lock as the reproducibility record. With those files committed, a new environment can be recreated with a single uv sync command.