Skip to content

How to migrate from requirements.txt to pyproject.toml with uv

To migrate a requirements.txt project to pyproject.toml, run uv init --bare to create a minimal pyproject.toml, then uv add -r requirements.txt to import every dependency. uv reads the file, writes the packages into [project.dependencies], and generates a uv.lock file that pins exact resolved versions.

For a detailed explanation of why pyproject.toml replaces requirements.txt, see why choose pyproject.toml over requirements.txt.

Prerequisites

Install uv if it isn’t already on your system.

Steps

1. Create a pyproject.toml file

$ uv init --bare

This creates a minimal pyproject.toml without sample source code or a README. If the project already has a pyproject.toml (from a tool like setuptools or hatch), skip this step.

2. Import runtime requirements

$ uv add -r requirements.txt

This command:

Tip

If requirements.txt contains pinned versions like requests==2.31.0, uv adds the package name without the pin. The exact resolved version is captured in uv.lock instead, which is the recommended approach for reproducibility.

3. Import development requirements

If the project has a separate requirements-dev.txt (or requirements-test.txt):

$ uv add --dev -r requirements-dev.txt

This adds them as development dependencies, which are installed during development but excluded from production builds.

Verify that every dependency was imported:

$ uv pip freeze

4. Remove the old requirements files

Once the migration is confirmed, remove the old files:

$ rm requirements.txt requirements-dev.txt

If any deployment tooling still expects a flat requirements.txt, regenerate one from the lockfile on demand instead of maintaining it by hand:

$ uv export --format requirements-txt > requirements.txt

5. Manage dependencies with uv going forward

# Add a new runtime dependency
$ uv add requests

# Add a development dependency
$ uv add --dev pytest

# Remove a dependency
$ uv remove requests

# Install every dependency from the lockfile
$ uv sync

Frequently asked questions

How do I convert requirements.txt to pyproject.toml?

Run uv init --bare to create a minimal pyproject.toml, then uv add -r requirements.txt to import every dependency. uv writes the packages into [project.dependencies] and generates a uv.lock file that pins exact resolved versions. For development-only requirements files, run uv add --dev -r requirements-dev.txt.

Will uv keep my exact pinned versions?

uv adds package names to pyproject.toml without the pin (e.g., requests==2.31.0 becomes requests) and captures the resolved version in uv.lock instead. This split is the recommendation. pyproject.toml declares constraints, and uv.lock pins exact versions for reproducible installs. To keep a hard constraint in pyproject.toml, edit it manually after import or pass the pin to uv add (e.g., uv add 'requests==2.31.0').

What happens to VCS, URL, and editable entries in requirements.txt?

uv preserves them. Git URLs like git+https://github.com/psf/requests.git are rewritten as dependencies with the git source, direct URLs are stored as URL dependencies, and editable entries like -e . are dropped because the project itself is already editable when installed via uv sync. Editable paths to sibling projects (-e ../other-pkg) become path dependencies with editable = true.

Can I keep using requirements.txt alongside pyproject.toml?

Yes. Run uv export --format requirements-txt > requirements.txt to regenerate a pip-compatible file from uv.lock whenever one is needed, for Docker images, legacy deploy tooling, or AWS Lambda. The pyproject.toml and lockfile stay authoritative; the exported requirements.txt is a build artifact.

Does uv support constraints.txt files?

Yes. Pass -c constraints.txt to uv add or uv pip install to enforce version bounds without adding the constrained packages as dependencies. Constraint files are honored during resolution but do not appear in pyproject.toml.

How do I migrate a requirements.in file compiled with pip-tools?

Treat requirements.in as the source of truth and pass it to uv add -r requirements.in. uv replaces the pip-tools requirements.in to requirements.txt workflow with pyproject.toml plus uv.lock. If a flat requirements.txt is still needed for downstream tools, export one with uv export --format requirements-txt.

Related

This handbook is free, independent, and ad-free. If it saved you time, consider sponsoring it on GitHub.

Last updated on