Skip to content

/commands/uv/uv-add-dependency

uv add package: add a dependency to a Python project with uv

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · uv 0.12.19 (bea138450 2026-09-24 aarch64-pc-windows-msvc)updated
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

bash
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.lock

uv 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

CommandWhat it does
uv add requestsLatest 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 pytestDevelopment dependency (dependency-groups.dev)
uv add --group docs mkdocsAny named dependency group
uv add --optional plot matplotlibAn optional extra of your own package (project.optional-dependencies)
uv add git+https://github.com/psf/requestsFrom a Git repository (recorded in tool.uv.sources)
uv add --editable ./libs/coreA local package, installed in editable mode
uv add -r requirements.txtImport every line of a requirements file
uv add --no-sync requestsUpdate pyproject.toml and uv.lock without installing into .venv
uv remove requestsRemove 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 add stops with No solution found when resolving dependencies and leaves pyproject.toml unchanged.
  • Commit uv.lock. CI that runs uv sync --locked fails with the lockfile needs to be updated when pyproject.toml changed but uv.lock did not.
  • No project yet. Outside a project uv add fails because there is no pyproject.toml; run uv init first. For a single script, use uv add --script file.py pkg, which writes inline metadata into the script.
  • Activated virtualenv. If another environment is active, uv warns that VIRTUAL_ENV does not match the project environment and uses .venv anyway.

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.

Sources