0–5 min: inventory
List current Python files: pyproject, requirements, lockfiles, Python version files, CI setup, and release scripts.
Success checkThe current workflow is visible before uv is introduced.
Infrastructure migration guide · Updated 2026-06-27
A practical migration guide for teams moving Python projects toward uv without breaking packaging, CI, private indexes, lockfiles, publishing, or developer onboarding.
Python toolchain migration fails when it is treated as a speed benchmark instead of a workflow change. uv can make installs and project workflows faster, but teams still need policy for lockfiles, Python versions, tools, private indexes, editable installs, build backends, publishing, CI caches, and developer onboarding.
This checklist turns the uv brief and Infrastructure Radar into a migration plan. It compares the roles of uv, pip, Poetry, pip-tools, pyenv, pipx, and mise, then gives teams a staged rollout model that starts with one repository and ends with updated docs, CI, fallback rules, and lockfile ownership.
RepoDaily verdict
Adopt uv when it reduces real project friction, not just because it is faster. Migrate in stages: tool execution first, then one application repo, then CI, then packaging and publishing. Keep pip or Poetry where release behavior is not yet proven, and use mise when the problem is cross-language tool pinning rather than Python dependency resolution.
This is not a benchmark of uv, pip, Poetry, or any package manager. RepoDaily created a small stdlib-only Python project to check whether a migration checklist preserves pyproject metadata, a repeatable test command, compile checks, uv-run execution when available, and an explicit lockfile policy.
| Evidence item | Smoke-test result | Why it matters | Limitation |
|---|---|---|---|
| Local migration fixture | 6/6 local smoke-test steps passed. | Validates the migration checklist mechanics, not a tool ranking. | Small stdlib-only project; no external dependency resolver stress. |
| pyproject metadata | The fixture keeps `requires-python` and the CI test command explicit in `pyproject.toml`. | A migration should make runtime and validation rules easier to audit, not hide them in ad hoc commands. | Does not cover complex build backends or optional dependency groups. |
| Baseline command parity | `python -m compileall src` and `python -m unittest discover -s tests` both pass. | Tool migration should preserve a repeatable baseline before changing installers or runners. | Uses unittest and stdlib code only. |
| uv-run check | uv is available in this workspace and `uv run` successfully executes the same local test suite with explicit `PYTHONPATH`. | Shows the checklist should record exactly what was run instead of implying a broad benchmark. | Not a speed test; no packages are downloaded. |
| Lockfile policy | A lockfile is present after the uv run, and the evidence records that this fixture has no external dependencies. | Lockfiles should be discussed as a policy and review artifact, not just a side effect. | No version-conflict or private-index behavior is tested. |
| Existing tool | uv migration target | Keep when | Evidence to collect |
|---|---|---|---|
| pip + venv | Use `uv sync`, `uv add`, `uv run`, and project-local virtualenvs | The project is tiny and no lockfile/reproducibility problem exists | Clean checkout setup time, import parity, test output |
| pip-tools | Use `uv lock` and `uv.lock` for dependency decisions | Requirements compilation policy is already mature and stable | Lockfile diff, dependency update review, private-index behavior |
| Poetry | Evaluate uv for project sync and lock behavior first | Publishing/build workflow depends on Poetry-specific behavior | Build artifact, publish dry run, script behavior, dependency groups |
| pyenv | Test `uv python install` for project interpreter management | Team has stable pyenv workflows across all projects | Python install path, version pin, CI parity |
| pipx | Use `uvx` or `uv tool` for developer CLI tools | Tool isolation and upgrade policy already works | Tool version, cache behavior, uninstall/upgrade path |
| mise | Use mise to pin uv and non-Python tools | The repo is Python-only and uv covers the workflow | mise.toml review, CI parity, tool owner |
Score a repository before changing its official onboarding docs.
| Readiness area | 0 points | 1 point | 2 points | Reviewer question |
|---|---|---|---|---|
| Project shape | Unknown packaging style | Known app/library type | App/library/tool workflows documented | What exactly is this repo shipping? |
| Dependency policy | No lock/update rule | Informal rule | Lockfile ownership and update review defined | Who updates dependencies and how? |
| CI parity | Local and CI differ | Partial parity | Clean CI uses same commands as local docs | Can a new runner reproduce local setup? |
| Private indexes | Untested auth/index behavior | Manual test only | CI and local private index path tested | How are credentials injected safely? |
| Publishing | Not tested | Build works | Build and publish dry run verified | What breaks at release time? |
| Fallback plan | No rollback | Manual notes | Documented fallback and migration branch | How do we revert if uv blocks release? |
Run this before opening a real migration PR.
List current Python files: pyproject, requirements, lockfiles, Python version files, CI setup, and release scripts.
Success checkThe current workflow is visible before uv is introduced.
Generate or inspect `uv.lock`, run `uv sync`, then run the project test or smoke command.
Success checkA clean local environment can run the core workflow.
Check optional dependencies, editable installs, private indexes, scripts, and Python version constraints.
Success checkKnown migration risks are named, not ignored.
Draft the CI command change and cache/version pinning strategy.
Success checkCI can mirror README without hidden commands.
Decide migrate, pilot longer, keep existing tool, or split local/CI/release responsibilities.
Success checkThe next action has owner, scope, and fallback path.
| Scenario | Migration pattern | Stop if |
|---|---|---|
| Small internal application | Adopt uv for lock, sync, run, and CI after one clean test run | Private dependencies or deployment image break |
| Published Python library | Test uv locally, but verify build and publish dry run before replacing release docs | Wheel/sdist metadata or publish path differs from current policy |
| Data science notebook repo | Use uv for environment sync and tool execution, keep data/source notes explicit | Notebook outputs depend on unmanaged local state |
| Polyglot product repo | Use mise to pin uv, Node, and other tools; use uv for Python dependencies | CI and local setup drift into two sources of truth |
| Poetry-heavy project | Pilot uv in branch; keep Poetry release path until publishing is proven | Scripts, dependency groups, or build backend assumptions break |
| Legacy requirements repo | Generate uv lock and compare imports/tests before removing requirements files | Dependency resolution changes behavior without a reviewer understanding why |
| Team-wide rollout | Move repo by repo with migration notes and fallback path | Docs say uv but CI/deploy still use older workflow |
A faster install is not enough. The migration must improve local setup, CI, lockfile review, and release confidence.
Applications and libraries have different needs. Do not replace a release tool until build and publish dry runs are verified.
Authentication, extra indexes, internal packages, and caching can behave differently in local and CI environments.
If docs use uv, CI uses pip, releases use Poetry, and developers use pyenv manually, the migration has created another layer.
A lockfile helps only if reviewers know who can update it, how diffs are reviewed, and how security updates are handled.
`uvx` and `uv tool` are convenient, but unreviewed tools should not become release-critical automation.
Pilot `uvx` or `uv tool` for developer-only CLIs before changing application dependency workflows.
Create a migration branch that changes lockfile, README, CI, and fallback notes together.
The commands in README should match CI setup and test commands; otherwise onboarding evidence is weak.
Keep Poetry or existing release scripts for published libraries until uv build/publish behavior is proven.
Use mise when the repo needs to pin uv plus Node, Terraform, cloud CLIs, or other non-Python tools.
Record old workflow, new workflow, commands tested, failures, fallback path, owner, and next review date.
Short answers for Python teams evaluating uv migration.
Not automatically. Pilot uv for sync and CI first, then verify build and publish behavior before changing a published package release path.
It depends on team policy. Applications usually benefit from committed lockfiles; libraries may use different policies. Write the rule before migration.
mise can pin uv, Python, Node, Terraform, and other tools. uv should own Python dependency/project behavior; mise should own cross-language tool setup.
Use uv in a branch for one low-risk application, run sync/tests in CI, document fallback, and keep the old workflow until release risks are tested.
Feedback
Anonymous feedback helps RepoDaily improve what is actually useful.