# Getting started with uv


[uv](https://pydevtools.com/handbook/reference/uv.md) handles Python installation, project setup, dependency management, and script execution in a single tool. This tutorial walks through each of those capabilities so you can start using uv for any Python project.

## Prerequisites

You need a terminal (Terminal on macOS, PowerShell on Windows, or any Linux shell). No prior Python installation is required.

[Git](https://git-scm.com/downloads) is optional. If Git is on your `PATH`, `uv init` initializes a repository in the new project. uv does not install Git itself; install it separately if you want version control. The tutorial steps work either way.

## Installing uv

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

Alternatively, install with Homebrew:

```bash
brew install uv
```

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

Verify the installation:

```console
$ uv --version
uv 0.7.x
```

If you see `command not found: uv`, the installer printed a hint about updating your shell `PATH`. Open a new terminal window (or restart the current shell) so the updated `PATH` takes effect.

For platform-specific details, see [How to install uv](https://pydevtools.com/handbook/how-to/how-to-install-uv.md).

## Creating a project

### Initialize a new project

```console
$ uv init my-project
Initialized project `my-project` at `/path/to/my-project`
$ cd my-project
```

### Examine the generated files

`uv init` creates a ready-to-use project structure:

{{< /filetree/folder >}}
{{< /filetree/container >}}

Open [pyproject.toml](https://pydevtools.com/handbook/reference/pyproject.toml.md) to see your project metadata:

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

The `.python-version` file records which Python version the project uses. uv reads this file automatically and downloads that interpreter if it isn't already installed. See [What is a Python version file?](https://pydevtools.com/handbook/explanation/what-is-a-python-version-file.md) for more on how this works.

### Run the starter script

```console
$ uv run main.py
Using CPython 3.13.5
Creating virtual environment at: .venv
Hello from my-project!
```

`uv run` creates a [virtual environment](https://pydevtools.com/handbook/explanation/what-is-a-virtual-environment.md) in `.venv/`, installs the correct Python version, syncs any dependencies, and then runs your script. All of that happens automatically on the first run. Subsequent invocations skip the setup lines and print only `Hello from my-project!`.

Notice the new `.venv/` directory in the project. That is where the project's Python interpreter and installed packages live. uv manages it for you, so there is no need to activate it manually.

> [!TIP]
> `uv init` creates an application project by default. For libraries, CLI tools, or other structures, see [Understanding uv init project types](https://pydevtools.com/handbook/explanation/understanding-uv-init-project-types.md).

## Adding dependencies

### Add a package

If you see `error: No `pyproject.toml` found in current directory or any parent directory`, you are running `uv add` outside the project. `cd` into the `my-project/` directory you created with `uv init`, then retry.

```console
$ uv add requests
Resolved 6 packages in 101ms
Installed 5 packages in 9ms
 + certifi==2025.1.31
 + charset-normalizer==3.4.1
 + idna==3.10
 + requests==2.32.3
 + urllib3==2.3.0
```

This command does three things: updates `dependencies` in `pyproject.toml`, resolves compatible versions and writes a [lockfile](https://pydevtools.com/handbook/explanation/what-is-a-lock-file.md) (`uv.lock`), and installs the package into the project's virtual environment.

Notice the new `uv.lock` file in the project root. It pins the exact version of every direct and transitive dependency, so anyone running `uv sync` later gets the identical environment. Commit it alongside `pyproject.toml`.

Your `pyproject.toml` now includes:

```toml
dependencies = [
    "requests>=2.32.3",
]
```

### Use the package in your code

Replace the contents of `main.py` with:

```python
import requests

response = requests.get("https://httpbin.org/json")
data = response.json()
print(data["slideshow"]["title"])  # prints the title from the response
```

Run it:

```console
$ uv run main.py
Sample Slide Show
```

### Add a development dependency

Development tools like linters and test runners belong in a separate dependency group so they don't ship with your project:

```console
$ uv add --dev ruff
Resolved 7 packages in 83ms
Installed 1 package in 3ms
 + ruff==0.8.4
```

This adds `ruff` under a development dependency group in `pyproject.toml`. Run it with:

```console
$ uv run ruff check .
All checks passed!
```

### Remove a package

```console
$ uv remove requests
Resolved 2 packages in 4ms
Uninstalled 5 packages in 6ms
 - certifi==2025.1.31
 - charset-normalizer==3.4.1
 - idna==3.10
 - requests==2.32.3
 - urllib3==2.3.0
```

This updates `pyproject.toml`, regenerates `uv.lock`, and uninstalls the package from the virtual environment.

## Running code and tools

`uv run` is the primary way to execute anything inside your project's environment. It ensures dependencies are synced before every invocation.

```bash
# Run a Python script
uv run main.py

# Run a module
uv run -m http.server 8000

# Run a tool installed as a dependency
uv run ruff format .
```

To run a CLI tool that isn't part of your project (a one-off invocation), use `uvx`:

```bash
# Run a tool without adding it as a dependency
uvx cowsay "hello uv"
```

For a deeper comparison, see [When to use uv run vs uvx](https://pydevtools.com/handbook/explanation/when-to-use-uv-run-vs-uvx.md).

## Managing Python versions

uv downloads and manages Python interpreters directly. No separate tool like pyenv is needed.

### List available versions

```console
$ uv python list
cpython-3.14.0-macos-aarch64-none                 <download available>
cpython-3.13.5-macos-aarch64-none                 /Users/you/.local/share/uv/python/cpython-3.13.5-macos-aarch64-none/bin/python3.13
cpython-3.13.5+freethreaded-macos-aarch64-none    <download available>
cpython-3.12.7-macos-aarch64-none                 <download available>
...
```

The output lists every Python build uv can manage. Versions already on disk show a path; versions marked `<download available>` will be fetched on first use. Your output will differ based on platform, architecture, and which versions you have already installed.

### Install a specific version

```console
$ uv python install 3.12
Installed Python 3.12.7 in 80ms
 + cpython-3.12.7-macos-aarch64-none (python3.12)
```

If the version is already installed, uv prints `Python 3.12 is already installed` instead and exits without changes.

### Pin a version to your project

The pinned version must satisfy the `requires-python` constraint in `pyproject.toml`. If `requires-python = ">=3.13"`, pinning to `3.12` fails with `error: The requested Python version `3.12` is incompatible with the project `requires-python` value of `>=3.13`.` Loosen `requires-python` first, or pin a compatible version.

```console
$ uv python pin 3.12
Pinned `.python-version` to `3.12`
```

This writes `3.12` to the `.python-version` file. The next time you run `uv run`, uv uses that version (installing it first if necessary). Open `.python-version` to confirm the change; it contains a single line with the pinned version.

### Test against a different version

You can run a single command with a different Python version without changing the project pin:

```bash
uv run --python 3.11 main.py
```

## What to explore next

You now know how to install uv, scaffold a project, manage dependencies, run code, and switch Python versions. Each of these topics goes deeper:

- [Complete guide to uv](https://pydevtools.com/handbook/explanation/uv-complete-guide.md) covers workspaces, lockfile strategies, and advanced configuration
- [Create your first Python project](https://pydevtools.com/handbook/tutorial/create-your-first-python-project.md) builds a text analysis tool from scratch using uv
- [Set up Ruff for formatting and checking your code](https://pydevtools.com/handbook/tutorial/set-up-ruff-for-formatting-and-checking-your-code.md) adds linting and formatting to a uv project; see the [Ruff reference](https://pydevtools.com/handbook/reference/ruff.md) for its features and configuration
- [Setting up testing with pytest and uv](https://pydevtools.com/handbook/tutorial/setting-up-testing-with-pytest-and-uv.md) sets up a test suite with fixtures and coverage
- [How to translate pip commands to uv](https://pydevtools.com/handbook/how-to/how-to-translate-pip-commands-to-uv.md) maps familiar pip workflows to uv equivalents
- [uv reference page](https://pydevtools.com/handbook/reference/uv.md) for a concise overview of features, pros, and cons
