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.