Harness the Combinatoric Power of Command-Line Tools and Utilities
Manage Python Projects and Environments With uv
Published March 20, 2026
Introduction
If you work with Python, you’ve juggled several tools while you worked: pyenv to install Python versions, venv to create virtual environments, and pip to install packages. uv replaces these with a single command-line tool that handles Python version management, virtual environments, and dependency resolution in one place.
In this tutorial you’ll install uv, use it to manage Python versions, create a project with a virtual environment, and manage your dependencies. Then you’ll run one-off scripts.
What You Need
To complete this tutorial, you need:
- Python installed, which you can do by following the Install Python tutorial.
- On macOS, you need Homebrew installed, which you can do by following the Install Homebrew tutorial.
Installing uv
On macOS, you can install uv with Homebrew:
brew install uvOn Linux and macOS, you can also install uv with the official installer:
curl -LsSf https://astral.sh/uv/install.sh | shOn Windows, use the PowerShell installer:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"Verify it’s installed:
uv --versionuv 0.10.10 (Homebrew 2026-03-13)
With uv installed, you can use it to install and manage Python versions on your system.
Managing Python Versions
Use uv python list to see which Python versions are available to install:
uv python listThis shows installed versions and versions available for download:
cpython-3.15.0a7-macos-aarch64-none <download available>
cpython-3.15.0a7+freethreaded-macos-aarch64-none <download available>
cpython-3.14.3-macos-aarch64-none /opt/homebrew/bin/python3.14 -> ../Cellar/python@3.14/3.14.3_1/bin/python3.14
cpython-3.14.3-macos-aarch64-none /opt/homebrew/bin/python3 -> ../Cellar/python@3.14/3.14.3_1/bin/python3
...
Install a specific version with the uv python install command:
uv python install 3.12uv searches and pulls down the specified version. You don’t need to configure your shell or manage shims like you would with pyenv.
Searching for Python versions matching: Python 3.12
Installed Python 3.12.9 in 2.84s
+ cpython-3.12.9
Now that you have a Python version installed, you can create a new project that uses it.
Creating a Project
Use uv init to create a new project:
uv init myprojectuv creates a directory, along with some default files:
Initialized project `myproject` at /Users/brianhogan/myproject
Switch to the project directory uv created:
cd myprojectList the files uv created, and be sure to list the hidden ones:
ls -latotal 16
drwxr-xr-x 8 brianhogan staff 256 Mar 20 17:11 .
drwxr-xr-x 21 brianhogan staff 672 Mar 20 17:11 ..
drwxr-xr-x 9 brianhogan staff 288 Mar 20 17:11 .git
-rw-r--r-- 1 brianhogan staff 109 Mar 20 17:11 .gitignore
-rw-r--r-- 1 brianhogan staff 5 Mar 20 17:11 .python-version
-rw-r--r-- 1 brianhogan staff 0 Mar 20 17:11 README.md
-rw-r--r-- 1 brianhogan staff 86 Mar 20 17:11 main.py
-rw-r--r-- 1 brianhogan staff 154 Mar 20 17:11 pyproject.toml
The pyproject.toml file is the project’s configuration. Open it and you’ll see uv has set up the basics:
[project]
name = "testproj"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.14"
dependencies = []
The .python-version file pins the Python version for this project. When you or anyone on your team runs uv commands in this directory, it uses the version specified in that file.
To run the project’s main.py file, use uv run:
uv run main.pyUsing CPython 3.14.3 interpreter at: /opt/homebrew/opt/python@3.14/bin/python3.14
Creating virtual environment at: .venv
Hello from testproj!
The first time you run the project, uv creates a virtual environment in .venv and installs any dependencies. You don’t need to create or activate the virtual environment manually.
With the project set up, you can start adding dependencies.
Adding Dependencies
Use uv add to add a package to your project:
uv add requestsResolved 6 packages in 657ms
Prepared 5 packages in 319ms
Installed 5 packages in 7ms
+ certifi==2026.2.25
+ charset-normalizer==3.4.6
+ idna==3.11
+ requests==2.32.5
+ urllib3==2.6.3
The uv tool resolves the dependency tree, installs the packages into the virtual environment, and updates pyproject.toml and a uv.lock lock file. The lock file pins exact versions so that every team member and your CI system get identical dependencies.
Check your pyproject.toml to see the change:
cat pyproject.toml[project]
name = "testproj"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.14"
dependencies = [
"requests>=2.32.5",
]
To remove a package, use uv remove. Remove the requests package you just added:
uv remove requestsResolved 1 package in 6ms
Uninstalled 5 packages in 8ms
- certifi==2026.2.25
- charset-normalizer==3.4.6
- idna==3.11
- requests==2.32.5
- urllib3==2.6.3
This removes the package and its unused dependencies.
You can also add development dependencies that aren’t needed in production. For example, add pytest as a development dependency with the following command:
uv add --dev pytestThis adds pytest under a separate [dependency-groups] section in pyproject.toml, keeping your production dependencies separate from your development dependencies.
These features handle most day-to-day work, but uv can also run one-off commands with packages you haven’t added to the project.
Running Scripts and Tools
You can use uv to run Python scripts and command-line tools without installing them or adding them as project dependencies. This is useful for one-off tasks like formatting code or running a linter.
Use the uvx to run a tool directly. Try using uvx to run ruff, a fast Python linting tool:
uvx ruff check .The package installs and runs:
Installed 1 package in 3ms
All checks passed!
The uvx command downloads the tool into a temporary environment, runs it, and cleans up. You get the tool you need without polluting your project’s dependencies.
You can also use uv run with inline script dependencies. Create a file called fetch.py:
# /// script
# requires-python = ">=3.12"
# dependencies = ["httpx"]
# ///
import httpx
response = httpx.get("https://httpbin.org/json")
print(response.json()["slideshow"]["title"])
The comment block at the top is a Python Enhancement Proposal (PEP) 723 inline metadata declaration. When you run this script with uv run, it reads those dependencies and installs them into an isolated environment:
uv run fetch.pyInstalled 6 packages in 7ms
Sample Slide Show
This lets you share self-contained scripts that declare their own dependencies.
Conclusion
The uv tool gives you a single command for Python version management, virtual environments, and dependency resolution. Your pyproject.toml and uv.lock files capture the full environment, making it possible to share consistent setups across your team, regardless of whether you’re on macOS, Windows, or Linux.