> ## Documentation Index
> Fetch the complete content index at: https://smallsharpsoftwaretools.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage Python Projects and Environments With uv


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`](https://docs.astral.sh/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]({{< ref "install_python" >}}) tutorial.
- On macOS, you need Homebrew installed, which you can do by following the [Install Homebrew]({{< ref "homebrew" >}}) tutorial.

## Installing `uv`

On macOS, you can install `uv` with Homebrew:

```command
brew install uv
```

On Linux and macOS, you can also install `uv` with the official installer:

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

On Windows, use the PowerShell installer:

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

Verify it's installed:

```command
uv --version
```

```output
uv 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:

```command
uv python list
```

This shows installed versions and versions available for download:

```output
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:

```command
uv python install 3.12
```

`uv` searches and pulls down the specified version. You don't need to configure your shell or manage shims like you would with `pyenv`.

```output
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:

```command
uv init myproject
```

`uv` creates a directory, along with some default files:

```output
Initialized project `myproject` at /Users/brianhogan/myproject
```

Switch to the project directory `uv` created:

```command
cd myproject
```

List the files `uv` created, and be sure to list the hidden ones:

```command
ls -la
```

```output
total 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:

```toml
[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`:

```command
uv run main.py
```

```output
Using 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:

```command
uv add requests
```

```output
Resolved 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:

```command
cat pyproject.toml
```

```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:

```command
uv remove requests
```

```output
Resolved 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:

```command
uv add --dev pytest
```

This 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`](https://docs.astral.sh/ruff/), a fast Python linting tool:

```command
uvx ruff check .
```

The package installs and runs:

```output
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`:

```python
# /// 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](https://peps.python.org/pep-0723/) inline metadata declaration. When you run this script with `uv run`, it reads those dependencies and installs them into an isolated environment:

```command
uv run fetch.py
```

```output
Installed 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.

