Get Started with the uv Package Manager

Chris SatoChris Sato
7 min read

Introduction

There's been a slew of different Python package management systems throughout the years such as pipx, poetry, and virtualenv. Despite various alternatives, I don’t think there’s been a package manager that definitively replaces pip as the standard. However, I think uv will become the de facto package manager for Python due to its speed, reliability, and ease of use once you get used to it.

The uv package manager, created by Charlie Marsh at Astral, is a Python package manager built with Rust. It streamlines Python development by handling virtual environments and dependency management. I've found that uv makes managing Python packages easier than the standard pip, venv, and requirements.txt approach I used to struggle with.

I haven't used other package managers well enough to do a comprehensive comparison and I recommend that you search for other blog posts, articles, YouTube videos for that info.

This article focuses on how to quickly get started using uv in a project with these simple commands.

Install uv

Depending on your machine, follow the installation instructions. The standalone installation are listed below. For any other installation methods, follow the installation instruction link.

# MacOS and Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

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

Verify that uv is installed by simply calling uv in the command line. A help menu should pop up. Confirm that uv is updated to the current version by calling uv --version or uv -V. If you already have uv installed, update to the latest with uv self update. As of writing this article, uv is at version 0.6.14 and have been updated weekly.

# Check version
uv --version

# Update uv
uv self update

First Steps

When you usually start a Python project, a virtual environment and Python interpreter are the first things you set up. I started my Python journey using PyCharm and became used to the IDE setting up my Python version and virtual environment with its UI. I was incredibly confused when switching to the VS Code editor as I had to manually create my virtual environment and activate it. With uv, it became easier to set up the Python version I want to use and create my environment.

Initiate a Project with uv init

This article will focus on Python projects instead of scripts. uv init is a great command to create a new project. It automatically generates several different files within the directory.

  • .git folder (hidden folder)

  • .gitignore file

  • .python-version file

  • main.py

  • pyproject.toml

  • README.md

The two key files here are the .python-version and pyproject.toml file.

The .python-version file specifies which Python version should be used for this project. When using uv, the default is the latest Python version to be used. However, I recommend explicitly specifying the version using the --python flag. If the specified version has not been downloaded, uv will automatically download and cache it for you. By specifying the Python version, a .venv folder is automatically generated along with the other above files.

The pyproject.toml file is a standardized configuration file introduced by PEP 518 and PEP 621 to make Python packaging consistent across tools. It's used by uv to define project dependencies and automatically updated whenever new dependencies are added by uv.

# Creates a project in the current working directory
uv init

# Creates a project in the specified file path within the working directory
uv init <path_name>

# Creates a project in the current directory and virtual environment with specified python version
uv init --python 3.13
# pyproject.toml file -- initial configurations

[project]
name = "project-name"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = []

Create a Virtual Environment

If you create your project using uv init --python <version_number>, a .venv folder will be generated with the specified Python version. However, uv init without the --python flag will not create a .venv folder right away. This is because "some project state is not created until needed, e.g., the project virtual environment (.venv) and lockfile (uv.lock) are lazily created during the first sync." (https://docs.astral.sh/uv/reference/cli/#uv-init)

You can explicitly create the .venv folder with uv venv. Again, to specify the Python interpreter when creating the virtual environment, use the --python flag followed by the version number.

uv venv

uv venv --python 3.13

Manage Dependencies

Add Dependencies with uv add

Instead of the usual pip install <package_name>, add project dependencies with uv using:

uv add <package_name>

For example, installing pandas with uv add pandas will:

  • Install pandas along with its dependencies to the virtual environment

  • Update the dependencies section in the pyproject.toml

  • Generate a uv.lock file (if one doesn't already exist), and record dependency versions (uv.lock file automatically updates when dependencies are modified)

$ uv add pandas
Resolved 7 packages in 334ms
Prepared 2 packages in 7.59s
Installed 6 packages in 1.70s
 + numpy==2.2.4
 + pandas==2.2.3
 + python-dateutil==2.9.0.post0
 + pytz==2025.2
 + six==1.17.0
 + tzdata==2025.2

The toml file will look like the following:

[project]
name = "example"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
    "pandas>=2.2.3",
]

You can view the dependency tree with:

uv tree

And it will end up looking like this.

$ uv tree
Resolved 7 packages in 2ms
example v0.1.0
└── pandas v2.2.3
    ├── numpy v2.2.4
    ├── python-dateutil v2.9.0.post0
    │   └── six v1.17.0
    ├── pytz v2025.2
    └── tzdata v2025.2

You can also add developer dependencies with the --dev flag.

For example, installing pytest as a developer dependency with uv add --dev pytest will install pytest with its dependencies in the virtual environment, add pytest to the [dependency-groups] section within the pyproject.toml file, and update the uv.lock file.

[project]
name = "example"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
    "pandas>=2.2.3",
]

[dependency-groups]
dev = [
    "pytest>=8.3.5",
]
$ uv tree
Resolved 12 packages in 2ms
example v0.1.0
├── pandas v2.2.3
│   ├── numpy v2.2.4
│   ├── python-dateutil v2.9.0.post0
│   │   └── six v1.17.0
│   ├── pytz v2025.2
│   └── tzdata v2025.2
└── pytest v8.3.5 (group: dev)
    ├── colorama v0.4.6
    ├── iniconfig v2.1.0
    ├── packaging v24.2
    └── pluggy v1.5.0

Remove Dependencies with uv remove

To remove a dependency, simply run uv remove <package_name>. Unlike pip, this will also remove package dependencies. For example, if pandas is removed, numpy, python-dateutil, six, pytx, and tzdata will also be removed as long as no other installed packages depend on them.

Sync a Project with uv sync

Let's say you cloned a project that has been managed with uv. There will be a uv.lock, .python-version, and pyproject.toml file defining the project environment. Instead of the usual steps of creating a virtual environment and pip install requirements.txt, simply call uv sync.

uv sync

This will:

  • Create the virtual environment with the specified python version from the .python-version file

  • Install all dependencies listed in the pyproject.toml and uv.lock file

One command takes care of everything!

Run Files with uv run

You can run a individual Python file or specify a relative or absolute path using:

uv run <file_name>.py

uv run path/to/<file_name>.py

When running Python files with uv run, there is no need to manually activate your virtual environment. It automatically does it for you before executing the file.

Example: Running a FastAPI App in Development Mode

For example, let's say you want to run a FastAPI project in development mode with the following project structure where main.py is the entry point:

my-fastapi-app/
├── .venv/
├── src/
│   └── app/
│       ├── __init__.py
│       └── main.py
├── pyproject.toml
├── uv.lock
└── .python-version
uv run fastapi dev src/app/main.py

Note: To use the fastapi dev command, you need to have the fastapi[standard] package downloaded as it includes the base package and other commonly used optional dependencies that enable the use of fastapi dev command.

Conclusion

This was a quick practical guide to help you get started using uv in your Python project. With open-source projects like FastAPI and Pydantic adopting uv, I imagine many more teams will begin to follow suit.

So give it a try and see how it can streamline your next project!

0
Subscribe to my newsletter

Read articles from Chris Sato directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Chris Sato
Chris Sato