Where Coordination Meets Trust: pip Compatibility, Indexes, Builds, and Operations

uv's coordination model becomes consequential when a project crosses its local boundary. This chapter examines how the pip-compatible interface, package indexes, source builds, and CI or container workflows change the meaning of “the same environment.” The goal is practical judgment: a team should be able to adopt uv without importing unsupported pip assumptions, choose an index and build policy deliberately, and design a deployment path whose lock, cache, and security controls each have a clear job.

These concerns belong together because they all decide what crosses the boundary from a declaration into an executable environment. A requirements file crosses into a virtual environment. An index supplies candidate metadata and artifacts. A build backend turns source into a wheel. A container layer preserves or discards files. Credentials, hashes, and attestations determine what the team can verify. A fast command does not make those boundaries disappear; it makes it more important to know where they are.

The migration bridge still changes the contract

The uv pip interface is designed for teams that already think in terms of pip commands, requirements files, and manually selected environments. It supports familiar operations such as installing packages, compiling requirements, synchronizing an environment, and inspecting what is installed. That makes it a useful migration bridge. A team can change the installer before it changes its project layout, and can compare the resulting behavior against an existing workflow.

But the bridge is not an exact copy of pip. uv documents that its compatibility goal is strongest for common workflows and weaker as a user moves into unusual options or legacy behavior. It uses its own configuration files and UV_* environment variables rather than silently reading pip-specific configuration. This separation lets uv define settings that fit its own project interface and prevents a pip configuration file from becoming an accidental second source of truth.

The environment default is also deliberate. uv pip install and uv pip sync prefer virtual environments, including an inactive .venv in the current directory or a parent directory. Mutating a system environment requires an explicit --system choice or an explicit Python target. That reverses a dangerous default: a command run from an ordinary shell does not automatically turn the operating system's Python installation into a project-specific package store.

The distinction between install and sync matters during migration. Installation adds or updates requested packages but can leave unrelated packages in the environment. Synchronization makes the environment match the compiled output and removes packages that are not declared there. A requirements-file workflow that uses sync has a reproducibility contract closer to a project lock, but it also has a destructive transition: packages outside the intended set are removed. The team must decide whether the environment is owned exclusively by that file.

The same choice appears in compilation. uv pip compile can accept a project manifest, requirements files, or multiple inputs and produce pinned output. By default, its output behavior and some formatting choices differ from pip-tools. It can resolve for one target platform or use universal output with markers. The important migration question is not whether the generated file looks familiar. It is whether the file's platform assumptions, index information, constraints, build constraints, and upgrade policy are understood by every consumer that will install it.

Index choice is the next boundary. uv can consult multiple PyPI-compatible or flat indexes in a defined order, and can pin a package to a named index or select a source by marker. The default first-index strategy stops at the first index where a package is found and limits candidate versions to that index.