1  uv: Package and Project Manager

uv is a Python package and project management tool that simplifies the process of creating, managing, and distributing Python projects. It provides a streamlined workflow for setting up virtual environments, managing dependencies, and packaging your code for distribution. It is fast in dependency resolution and package installation, perhaps the fastest among all Python package managers (as of 2025).

1.1 Install uv

You can install uv using Python’s package installer pip. However, assuming you don’t have Python installed yet, we recommend using uv’s standalone installer via Powershell terminal (Windows user) or Terminal (MacOS/Linux user).

Use irm to download the script and execute it with iex:

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

Use curl to download the script and execute it with sh:

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

See the uv installation guide for more detailed instructions.

Once installed, to verify the installation, run:

uv --version

For future uv update, use the command:

uv self update

1.2 A typical uv workflow

You could use uv venv and uv pip install to create a virtual environment and install packages just like you do with the “default” Python tools venv and pip. However, uv provides a more streamlined workflow for managing your Python projects.

The recommended workflow creates a separate virtual environment for each project (as opposed to a global environment or a shared virtual environment across multiple projects). Here is a typical workflow using uv:

  1. Create a new project: Use uv init <project-name> --python <python-version> to create a new project directory with the necessary structure and files. The --python flag specifies the version of Python to use for the virtual environment. For example:

    uv init my-research-project --python 3.12

    This creates a folder named my-research-project with a basic project structure as following:

    my-research-project/
    ├── .git
    ├── .gitignore
    ├── .python-version
    ├── README.md
    ├── main.py
    └── pyproject.toml
    • The .git and .gitignore files are for Git version control as uv automatically initializes a Git repository for your project. (See more about Git in the Version Control and Collaboration chapter.)
    • The .python-version file specifies the Python version for the project.
    • The README.md file is a markdown file where you can document your project.
    • The main.py file is the main Python script for your project.
    • The pyproject.toml file is used to manage project metadata and dependencies.

    At this point, no virtual environment has been created yet.

  2. Install packages (and dependencies): Use uv add <package-name> to install packages and their dependencies into the project’s virtual environment. For example:

    uv add numpy pandas matplotlib

    This command will create a virtual environment (if it doesn’t exist yet) for the project and install the specified version of Python and packages (numpy, pandas, matplotlib, and their dependencies) into the virtual environment. The installed packages and their versions will be recorded in the pyproject.toml file.

    my-research-project/
    ├── .git
    ├── .gitignore
    ├── .python-version
    ├── .venv
    ├── README.md
    ├── main.py
    ├── pyproject.toml
    └── uv.lock

    Note that a virtual environment is now created in the .venv directory within the project folder.

    The pyproject.toml file will be updated to include the installed packages.

    [project]
    name = "my-research-project"
    version = "0.1.0"
    description = "Add your description here"
    readme = "README.md"
    requires-python = ">=3.12"
    dependencies = [
        "matplotlib>=3.10.7",
        "numpy>=2.3.4",
        "pandas>=2.3.3",
    ]

    The uv.lock file records the exact versions of all installed packages and their dependencies, ensuring a fully reproducible environment. Sharing this file with collaborators helps them install identical package versions. This file is automatically managed and should not be edited manually.

    To remove a package, use uv remove <package-name>.

  3. Run your code: Use uv run <script> to run your Python scripts.

    uv run main.py

    This command activates the virtual environment and runs the specified script (main.py in this case) under the virtual environment.

    If you clone an existing project that uses uv, uv run <script> will automatically create the virtual environment and install the required packages based on the pyproject.toml and uv.lock files. That is, in such case, uv run syncs the environment automatically. However, you could also explicitly sync the environment using uv sync.

1.3 Learning Resources

To learn more about uv and its features, the following resources may be helpful:

1.4 Limitations of uv

uv is a powerful tool for managing Python projects, focusing on Python packages, virtual environments, and Python interpreter versions. However, it does not handle system-level packages or libraries outside the Python ecosystem (for example, C/C++ libraries or OS packages). As a result, certain Python packages that depend on system-level components (such as psycopg2 or lxml) may require manual installation of those dependencies.

In such cases, conda, another package manager, might be a better fit, as it manages both Python packages and system-level dependencies within a unified environment, though it tends to be much slower than uv. Another emerging tool, pixi, aims to combine the strengths of both uv and conda: fast performance and support for both Python and system-level dependencies.

There are indeed many Python project management tools available. Bottom line: uv is an excellent choice for most Python workflows, but keep its limitations in mind when system-level dependencies are involved.