uv

uv is a modern Python package and project manager.

In this guide, it will be used to manage:

  • the Python project,
  • dependencies,
  • development dependencies,
  • the virtual environment,
  • the lockfile,
  • commands executed inside the project environment.

Why use uv?

Python projects often start with simple commands such as:

pip install package-name

This works for quick experiments, but it can become harder to manage when the project grows.

A maintainable project should make it clear:

  • which Python version is expected,
  • which dependencies are needed,
  • which dependencies are used only during development,
  • how to install the project,
  • how to run tests and quality checks,
  • how to reproduce the same environment on another machine.

uv helps with these tasks.

What uv replaces in this guide

This guide uses uv instead of manually combining many separate tools at the beginning.

For this project, uv will help replace or simplify parts of workflows often handled with:

  • pip,
  • venv,
  • manually maintained dependency files,
  • ad hoc setup instructions.

The goal is not to say that older tools are bad.

The goal is to use one modern tool that keeps the beginner workflow simple and consistent.

Important project files

When working with uv, several files are important.

pyproject.toml

pyproject.toml is the central configuration file for the Python project.

In this guide, it contains:

  • project metadata,
  • Python version requirements,
  • build system configuration,
  • project dependencies,
  • development dependencies,
  • pytest configuration,
  • Ruff configuration.

This file should be edited carefully because it describes how the project works.

.python-version

.python-version stores the default Python version for the project.

It helps uv know which Python version should be used when creating the project environment.

.venv/

.venv/ is the local virtual environment.

It contains the Python interpreter and installed packages for this project.

This directory should not be committed to Git.

It is generated locally and should stay ignored.

uv.lock

uv.lock stores exact resolved dependency versions.

It helps make installations reproducible.

Unlike .venv/, the lockfile should be committed to Git.

This allows other people and CI systems to install the same dependency versions.

Basic commands

The most important uv commands in this guide will be introduced gradually.

Examples:

uv init --package
uv sync
uv add --group dev pytest
uv add --group dev ruff
uv add --group dev mypy
uv add --group dev pytest-cov
uv run pytest
uv run pytest --cov=text_toolkit --cov-report=term-missing
uv run ruff check .
uv run ruff format .
uv run mypy
uv build --no-sources

Do not worry if these commands are not fully clear yet.

Each one will be explained when it becomes useful.

Why not add everything now?

This guide is built step by step.

It would be possible to create the whole project configuration immediately, but that would make the learning process less clear.

Instead, the project will grow in small changes:

  • explain uv,
  • initialize the Python project,
  • inspect the generated files,
  • add the example package,
  • add tests,
  • add code quality tools,
  • add continuous integration.

This makes the repository history easier to understand.

Rule of thumb

Use uv to make the project environment reproducible and easy to run.

A good setup should let another person clone the repository and quickly answer:

How do I install this project?
How do I run the code?
How do I run the tests?
How do I check code quality?

If the project answers these questions clearly, the tooling is doing its job.

Continue