uv pip install vs uv add: what each does (tested)
uv add writes the dependency to pyproject.toml and uv.lock and installs it. uv pip install only installs into the venv, so the next uv sync or uv run uninstalls it. In a project, use uv add.
uv has two ways to install a package: the project interface (uv add, uv sync, uv.lock) and the pip-compatible interface (uv pip install). They behave very differently in a project. Measured with uv 0.13.5 on Python 3.13.5 (Linux). Every command below was run in a fresh directory and its output pasted unedited.
1. uv add: records the dependency, locks, installs
Transcript:
$ uv init demo -q
$ cd demo && uv add requests
Using CPython 3.13.5 interpreter at: /usr/bin/python3.13
Creating virtual environment at: .venv
Resolved 6 packages in 3ms
Building demo @ file:///tmp/uvw397/demo
Built demo @ file:///tmp/uvw397/demo
Prepared 1 package in 4ms
Installed 6 packages in 1ms
+ certifi==2026.10.23
+ charset-normalizer==3.5.2
+ demo==0.1.0 (from file:///tmp/uvw397/demo)
+ idna==3.20
+ requests==2.34.2
+ urllib3==2.8.0
$ cd demo && sed -n '/dependencies/,/]/p' pyproject.toml
dependencies = [
"requests>=2.34.2",
]
$ cd demo && ls -a | grep -E 'uv.lock|.venv'
.venv
uv.lock
uv add requests wrote "requests>=2.34.2" into pyproject.toml, created uv.lock and the .venv, and installed everything. Anyone running uv sync on the repo gets the same versions.
2. uv pip install: installs only, and uv sync removes it
Transcript:
$ cd demo && uv pip install six
Resolved 1 package in 1ms
Installed 1 package in 2ms
+ six==1.17.0
$ cd demo && grep -c six pyproject.toml uv.lock
pyproject.toml:0
uv.lock:0
[exit 1]
$ cd demo && uv pip list | grep -i six
six 1.17.0
$ cd demo && uv sync
Resolved 6 packages in 0.76ms
Uninstalled 1 package in 0.23ms
- six==1.17.0
$ cd demo && uv pip list | grep -i six || echo 'six: not installed'
six: not installed
uv pip install six put the package in .venv but did not touch pyproject.toml or uv.lock. The next uv sync (which uv run also does) made the environment match the lockfile exactly and uninstalled it. If a package "disappears" in a uv project, it was installed with uv pip install: use uv add instead (or uv sync --inexact to keep extras).
3. uv pip install outside a venv: No virtual environment found
Transcript:
$ mkdir -p plain && cd plain && uv pip install six
error: No virtual environment found; run `uv venv` to create an environment, or pass `--system` to install into a non-virtual environment
[exit 2]
$ cd plain && uv venv -q && uv pip install six
Resolved 1 package in 1ms
Installed 1 package in 2ms
+ six==1.17.0
Unlike pip, uv pip install refuses to install into the system Python. Create an environment with uv venv (it is picked up from .venv in the current or a parent directory), or pass --system deliberately, e.g. in a Docker image. On Debian/Ubuntu the system Python will still be externally managed.
4. requirements.txt: uv pip freeze, uv export, uv add -r
Transcript:
$ cd demo && uv pip freeze
certifi==2026.10.23
charset-normalizer==3.5.2
-e file:///tmp/uvw397/demo
idna==3.20
requests==2.34.2
urllib3==2.8.0
$ cd demo && uv export --format requirements-txt --no-hashes -q
# This file was autogenerated by uv via the following command:
# uv export --format requirements-txt --no-hashes
-e .
certifi==2026.10.23
# via requests
charset-normalizer==3.5.2
# via requests
idna==3.20
# via requests
requests==2.34.2
# via demo
urllib3==2.8.0
# via requests
$ printf 'six==1.17.0\n' > req.txt && cd demo && uv add -r ../req.txt -q
$ cd demo && sed -n '/dependencies/,/]/p' pyproject.toml
dependencies = [
"requests>=2.34.2",
"six==1.17.0",
]
uv pip freeze lists what is installed right now, including anything added with uv pip install. uv export --format requirements-txt writes the lockfile instead, with comments showing why each package is there, which is what you want for a deploy target that only understands pip. To move an existing requirements.txt into a uv project, uv add -r requirements.txt copies its lines into pyproject.toml.
Rule of thumb: in a project with pyproject.toml, use uv add / uv remove / uv sync. Use uv pip install for throwaway venvs, scripts and tools that expect pip.
Related: uv pip compile, uv ignore SSL errors (UnknownIssuer), pip error: externally-managed-environment, pytest using the wrong Python version.
Frequently asked questions
What is the difference between uv add and uv pip install?
uv add records the package in pyproject.toml and uv.lock and installs it; uv pip install only installs it into the current venv.
Why did uv sync uninstall my package?
It was installed with uv pip install and is not in uv.lock. uv sync makes the venv match the lockfile exactly. Add it with uv add.
How do I create requirements.txt with uv?
uv export --format requirements-txt (from the lockfile) or uv pip freeze (what is installed now).
Written with AI assistance. Measured on 2026-10-23 with uv 0.13.5 and CPython 3.13.5 on Linux. Each transcript was produced by running the commands verbatim in a fresh directory. PlainHeaders is our extension; uv is free.