Using uv for Python Package Management¶
Our HPC users can use uv, an extremely fast package and project manager written in Rust. uv can act as a drop-in replacement for pip and venv, and is designed for high performance and reproducible Python workflows.
What is uv?¶
uv is a Python package and project manager written in Rust. It provides:
- Very fast environment and package operations (create, install, resolve).
- A unified interface that can replace:
pipfor package installation and management.venvfor creating virtual environments.- A modern, reproducible workflow for Python projects (including
pyproject.toml-based projects).
While uv is not a replacement for Conda in all scenarios, it excels at pure Python workloads where system-level dependencies are not required.
uv vs. Pixi vs. Conda: Choosing the right tool
uv is designed for pure Python projects and cannot install non-Python dependencies or packages in other languages. If your work requires these dependencies, use Conda or Pixi instead. uv works best when your project only needs Python packages available on PyPI.
To read more about uv, visit the official documentation.
Using uv on NSF NCAR HPC Systems¶
uv is available as an environment module on NCAR HPC systems.
Before using uv, ensure no conda environments are active:
Then, load the uv module:
By default, uv stores its cache in your home directory, which can quickly exceed your quota. The module automatically sets the cache location to /glade/derecho/scratch/$USER/.cache/uv. You can verify that by running uv cache dir and confirming the Cache dir points to your scratch space, not your home directory.
conda, uv, and pixi module conflicts
If you have previously loaded either conda or pixi modules in your session, you must unload them before loading uv. For example:
Working with Python Projects using uv¶
uv supports managing Python projects, which define their dependencies in a pyproject.toml file.
You can create a new Python project using the uv init command:
This creates a project directory with the following structure:
my-analysis/
├── pyproject.toml # Project configuration and dependencies
├── README.md # Project description
└── .python-version # Pinned Python version
The pyproject.toml file is where you define your project's dependencies.
What is a project-based workflow?
A project-based workflow organizes your code and dependencies around a central pyproject.toml file, rather than managing environments and packages separately. This approach:
- Declares dependencies explicitly : all required packages are listed in
pyproject.toml - Locks exact versions : for example a
uv.lockfile will pin exact versions of all dependencies - Enables reproducibility : recreate your environment months later with
uv sync
The project-based model is standard in modern Python tooling. This approach contrasts with the traditional approach of creating a conda or venv environment, installing packages ad-hoc, and doing pip freeze > requirements.txt. uv supports both workflows, but the project-based approach is recommended for better reproducibility.
Using pyproject.toml
See the official pyproject.toml guide for more details on getting started with the pyproject.toml format.
Managing Dependencies¶
Now you can add dependencies to your project:
Each time you add packages, uv updates your pyproject.toml and creates or updates a uv.lock file that pins exact versions of all dependencies. This lock file ensures that anyone can reproduce your exact environment.
You can also install packages from a requirements.txt file:
You can remove packages with uv remove:
To upgrade packages to their latest compatible versions, use:
The --upgrade-package flag will attempt to update the specified package to the latest compatible version, while keeping the rest of the lockfile intact.
Note
See uv documentation on dependency management for more advanced dependency management commands and scenarios.
Running Commands in uv Project Environments¶
Now, to run Python in your project environment:
The uv run command automatically activates your project environment and keeps it in sync with your pyproject.toml and lockfile, guaranteeing your command runs in a consistent, locked environment.
You can use uv pip list to see installed packages in your project environment:
Project environments
uv stores project environments in a .venv directory within your project. You do not need to activate this environment manually when using uv run. Alternatively, you can activate it traditionally with source .venv/bin/activate; then use python as usual.
Creating and Activating a Virtual Environment with uv¶
uv can be used to create standalone virtual environments similar to python -m venv.
To create an environment:
mkdir -p /glade/work/$USER/uv-envs
# Create a new uv virtual environment
uv venv /glade/work/$USER/uv-envs/myenv
# Activate the environment
source /glade/work/$USER/uv-envs/myenv/bin/activate
python commands within this environment just like a conda environment. If you use uv run commands, you do not need to activate the environment manually. Specifying Python Versions with uv
You can create virtual environments with specific Python versions using the --python flag.
uv venv /glade/work/$USER/uv-envs/myenv-py3.10 --python python3.10
source /glade/work/$USER/uv-envs/myenv-py3.10/bin/activate
python --version
uv will use the default Python version available in your environment. Environment location
Create virtual environments in /glade/work/$USER to avoid filling your home directory quota. Virtual environments can be several MBs-GBs or larger depending on installed packages.
Low-level uv pip Commands¶
These commands are intended for legacy workflows or cases where the high-level project commands (uv init, uv add, uv run) do not provide enough control.
Once your uv environment is active, you can install packages using uv’s pip interface:
This behaves similarly to pip, but with much faster dependency resolution.
Similarly you can install from a requirements.txt file:
or you can uninstall packages:
Other useful uv pip commands include:
uv pip check: Check that the current environment has compatible packages.uv pip tree: View the dependency tree for the environment.uv pip install -r pyproject.toml: Install packages from apyproject.tomlfile.
Locking packages in an environment can be done with:
uv pip compile: Compile requirements into a lockfile.uv pip sync: Sync an environment with a lockfile.
Warning
These commands do not exactly implement the interfaces and behavior of the tools they are based on. Consult the pip compatibility guide for details.
Reproducing uv Environments¶
One of uv's key strengths is built-in support for reproducibility through lock files.
When you create a uv project and add dependencies, uv automatically generates a uv.lock file that specifies exact versions of all packages and their dependencies.
To reproduce an environment from a project with a lock file:
# Clone or copy a project with pyproject.toml and uv.lock
cd my-analysis
# Install exact versions from lock file
uv sync --frozen
The --frozen flag tells uv to use the exact versions in the lock file without attempting to update them.
Lock files and version control
We strongly recommend committing uv.lock files to version control (Git) alongside your pyproject.toml. This allows colleagues and your future self to reproduce exact environments.
Creating Jupyter kernels for uv environments¶
uv environments can be used in JupyterLab sessions on the NCAR JupyterHub service.
First, install the ipykernel package into your uv environment:
At this point, your environment should appear automatically as a kernel option when you start a Jupyter server on Derecho or Casper. This method is convenient and ensures that all environment settings are properly applied when the kernel launches.
You can also manually create a kernel specification with a custom name:
This registers theuv environment as a Jupyter kernel named my-uv-analysis-kernel. Using uv in Batch Jobs¶
Using uv in Batch Jobs
The uv module can be loaded in batch scripts just like on login nodes.
Here is an example PBS code using uv virtual environments: