/commands/uv/uv-add-dependency
uv add package: add a dependency to a Python project with uv
- tool
- uv
- versions
- uv 0.4+
- os
- any
uv add requests adds requests to the dependencies list of pyproject.toml, resolves the whole project and writes the exact versions to uv.lock, then installs everything into the project's .venv. Add --dev for a development-only dependency (written to the dev group under [dependency-groups]) and --group name for any other group. Remove a package with uv remove.
Add a dependency and a dev dependency
uv init -q --bare --name demo --python 3.13 .
uv add -q "six==1.16.0"
uv add -q --dev "idna>=3.10,<4"
cat pyproject.toml
echo "--- uv tree"
uv tree -q | sed -E 's/idna v[0-9.]+/idna v3.x/'
ls -a | grep -E "^(\.venv|uv\.lock)$"Output
[project]
name = "demo"
version = "0.1.0"
requires-python = ">=3.13"
dependencies = [
"six==1.16.0",
]
[dependency-groups]
dev = [
"idna>=3.10,<4",
]
--- uv tree
demo v0.1.0
├── six v1.16.0
└── idna v3.x (group: dev)
.venv
uv.lockuv wrote the specifiers as given, created uv.lock with the resolved versions and the .venv environment, and uv tree shows the result with the group of each dependency. Without a version, uv add requests writes a lower bound on the version it resolved (for example requests>=2.32.3), so later upgrades stay possible.
Variants
| Command | What it does |
|---|---|
| uv add requests | Latest compatible version, saved as requests>=x.y.z |
| uv add "requests==2.32.3" | An exact version |
| uv add "fastapi[standard]" | A package with extras |
| uv add --dev pytest | Development dependency (dependency-groups.dev) |
| uv add --group docs mkdocs | Any named dependency group |
| uv add --optional plot matplotlib | An optional extra of your own package (project.optional-dependencies) |
| uv add git+https://github.com/psf/requests | From a Git repository (recorded in tool.uv.sources) |
| uv add --editable ./libs/core | A local package, installed in editable mode |
| uv add -r requirements.txt | Import every line of a requirements file |
| uv add --no-sync requests | Update pyproject.toml and uv.lock without installing into .venv |
| uv remove requests | Remove it from pyproject.toml, uv.lock and .venv |
Pitfalls
- Conflicts fail the command. If the new requirement cannot be satisfied together with the others (or with
requires-python),uv addstops with No solution found when resolving dependencies and leavespyproject.tomlunchanged. - Commit
uv.lock. CI that runsuv sync --lockedfails with the lockfile needs to be updated whenpyproject.tomlchanged butuv.lockdid not. - No project yet. Outside a project
uv addfails because there is nopyproject.toml; run uv init first. For a single script, useuv add --script file.py pkg, which writes inline metadata into the script. - Activated virtualenv. If another environment is active, uv warns that
VIRTUAL_ENVdoes not match the project environment and uses.venvanyway.
How to confirm it worked
uv tree prints the dependency tree from uv.lock, and uv run python -c "import six; print(six.__version__)" imports the package from the project environment. git diff pyproject.toml uv.lock shows exactly what the command changed.
FAQ
What is the difference between uv add and uv pip install?
uv add records the dependency in pyproject.toml, updates uv.lock and syncs the project environment. uv pip install only installs into an environment, like pip, and changes no project file, so the next uv sync can remove what it installed.
How do I add a dependency from requirements.txt?
Run uv add -r requirements.txt. Each line becomes an entry in project.dependencies with the same version specifier, and uv locks and installs them.
Where does uv add put the virtual environment?
In a .venv folder next to pyproject.toml, created on first use. Set UV_PROJECT_ENVIRONMENT to use another path, for example in a container.