CLI · Development environments · Astral
uv
Manage Python versions, project dependencies and isolated tools with a single command-line program.
A package manager installs code. Build backends and executed tools can access the user's environment. Review package names, sources and versions before adding dependencies.
Understand the tool
What it does.
uv manages Python projects and packages. It can create environments, resolve dependencies, maintain a lockfile and run Python tools. The lockfile records a dependency resolution; an environment contains the installed packages used to execute the project.
Why use it?
Use it when a Python task needs a setup that another person can repeat. A project file, a reviewed lockfile and an explicit execution command make the required tools easier to understand than an undocumented collection of global installations.
A useful fit for
- Python project setup
- Dependency inspection
- Isolated Python tooling
From need to output
Ways to put it to work.
These are suggested workflows based on the documented capabilities. They are not recorded runtime results.
Use case 01
Explain a dependency
A reviewer finds a package in a project and needs to know why it is present.
- Open the project with its existing lockfile.
- Inspect the dependency tree without updating the lockfile.
- Identify the direct dependency that introduces the package.
Intended outputA traceable explanation of the package's place in the project.
Use case 02
Prepare a reproducible script
A team shares a data-conversion script that needs several Python libraries.
- Declare the Python and package requirements.
- Review and retain the resolved lockfile.
- Document environment setup and a test using synthetic input.
Intended outputA script with explicit dependencies and a repeatable verification step.
A concrete starting point
Inspect an existing locked dependency tree
Run in a project with an existing uv.lock. Frozen uses the existing lockfile without updating it; offline disables network access. Missing required local information can make the command fail.
uv tree --frozen --offlineWhat this can change
Reads local project and lockfile metadata and prints the dependency tree. It does not run project code or intentionally update the lockfile.
This example has not been executed for this review. Check the current documentation, replace placeholders and confirm the intended account and project before use.
Before you start
Setup and access.
What you’ll need
- Installed uv
- A Python project or identified tool to manage
- Existing uv.lock for the illustrative command
- Authentication
- No account is needed for local operations. Private indexes or repositories may require credentials.
- Can read
- Project metadata and lockfiles
- Package indexes, source repositories and local caches as needed
- Can write or change
- Environments, caches, lockfiles and project dependency declarations
- Published packages only when publishing is explicitly invoked
- Network and data flow
- Configured Python package indexes
- Python distribution and source hosts when downloads are needed
- Approval and control
- uv executes the requested operation. Package build backends and tools can run code without a separate interactive approval.
Check your environment
Compatibility, costs and license.
Compatibility notes
- Windows, macOS and Linux
- Supported Python versions and project formats documented by Astral
Costs and account requirements
uv is open source with no product subscription required. Private registries and compute used by the project can have separate costs.
Current pricing or plan information ↗MIT OR Apache-2.0
The project offers either license at the user's option; installed packages retain their own licenses.
Read the license or service terms ↗Keep the boundaries visible
Concerns and limitations.
A package manager installs code
Build backends and executed tools can access the user's environment. Review package names, sources and versions before adding dependencies.
Reproducibility is not a security verdict
A lockfile fixes a resolution but does not prove every package is trustworthy. Keep dependency review and vulnerability checks separate.
Where it may fall short
- Some Python workflows need migration work and project-specific configuration.
- Offline operations depend on available local metadata and caches.
Observed behavior · 2026-10-18
Runtime and security findings.
An offline virtual environment installed and imported a synthetic wheel with the correct hash. A wrong hash and an uncached offline package were rejected.
These checks cover the conditions below. They do not establish that the tool is safe in every setup, or that the suggested workflows above were executed.
What we found
Observed in this evaluation
Hash checking rejected the deliberately changed requirement
The wrong-hash run failed, while the matching-hash wheel installed and imported. This tests artifact matching for one wheel, not whether its code is trustworthy.
In practice: Pin versions and trusted hashes, review package provenance and retain a lockfile appropriate to the workflow.
Observed in this evaluation
Offline mode has a concrete dependency limit
An invented uncached dependency failed with an offline-resolution message. A clean deployment needs all required artifacts available beforehand.
In practice: Prepare and verify the required wheels/cache in advance, then rehearse the exact offline install.
Observed in this evaluation · medium severity under stated conditions
Hash verification does not prevent package code execution
The synthetic module executed when imported. Build backends and installed package code remain part of the trust decision; hash checks identify bytes rather than certify behavior.
In practice: Prefer reviewed artifacts and isolated environments; separately control source builds and execution.
Version, environment and fixture
- Version or deployment
- 0.13.1 (62faed335, x86_64-pc-windows-msvc)
- Tested target
- Official uv Windows x64 release archive
- Artifact identity
- SHA-256 3b2661a463a5baea7f5076ea2b25ab71d77f36a6c0d809e5350651792f80a672 of the official downloaded uv.zip artifact.
- Environment and fixture
- Windows 11 x64; Python 3.12.10 harness. Raw timestamps UTC.
- Fresh per-tool home/config/cache; child environment constructed from OS/runtime paths, explicit isolation variables and no inherited credentials. Synthetic fixtures only; no user account sign-in.
- UV_OFFLINE=1, UV_NO_SYSTEM_CONFIG=1 and UV_PYTHON_DOWNLOADS=never; explicit fixture interpreter and private cache.
Checks and results
6 recorded checks. Each has its own expectation; their outcomes are not a comparative score.
Downloaded versionMet expectation
- Method
<evaluation>\downloads\cli\uv\uv.exe --version- Expected
- Print the pinned binary version.
- Observed
- Exit 0. uv 0.13.1 (62faed335 2026-10-13 x86_64-pc-windows-msvc)
Create offline virtual environmentMet expectation
- Method
<evaluation>\downloads\cli\uv\uv.exe venv --python <python-install>\python.exe <evaluation>\runs\cli\uv\fixture\.venv --offline- Expected
- Create a fixture venv using the existing Python interpreter.
- Observed
- Exit 0. Created the fixture .venv with CPython 3.12.10; Python downloads were disabled.
Reject mismatching package hashMet expectation
- Method
Author a ZIP wheel named ionbin_fixture-0.0.1-py3-none-any.whl containing ionbin_fixture.py with VALUE = "synthetic-only"; ionbin_fixture-0.0.1.dist-info/METADATA with Metadata-Version: 2.1, Name: ionbin-fixture, Version: 0.0.1 (each on its own line); WHEEL with Wheel-Version: 1.0, Generator: IonBin synthetic fixture, Root-Is-Purelib: true, Tag: py3-none-any (each on its own line); and an empty RECORD. The tested wheel SHA-256 was d375a7e7cd1cdee145e6f347603d4c99a15de1a180db406cbd5e577c9aeda737. ZIP timestamps can change a regenerated archive hash; calculate its actual SHA-256 for the matching-hash case. bad.txt contains one line: <absolute-fixture-wheel-path> --hash=sha256:0000000000000000000000000000000000000000000000000000000000000000. Use the fixture .venv created by the preceding venv check. Command: <evaluation>\downloads\cli\uv\uv.exe pip install --python <evaluation>\runs\cli\uv\fixture\.venv\Scripts\python.exe --require-hashes --offline -r <evaluation>\runs\cli\uv\fixture\bad.txt- Expected
- Fail a wheel whose required SHA-256 is deliberately all zeroes.
- Observed
- Exit 1. Hash mismatch for ionbin-fixture; the expected all-zero digest did not match the locally generated wheel.
Install the matching wheelMet expectation
- Method
Author a ZIP wheel named ionbin_fixture-0.0.1-py3-none-any.whl containing ionbin_fixture.py with VALUE = "synthetic-only"; ionbin_fixture-0.0.1.dist-info/METADATA with Metadata-Version: 2.1, Name: ionbin-fixture, Version: 0.0.1 (each on its own line); WHEEL with Wheel-Version: 1.0, Generator: IonBin synthetic fixture, Root-Is-Purelib: true, Tag: py3-none-any (each on its own line); and an empty RECORD. The tested wheel SHA-256 was d375a7e7cd1cdee145e6f347603d4c99a15de1a180db406cbd5e577c9aeda737. ZIP timestamps can change a regenerated archive hash; calculate its actual SHA-256 for the matching-hash case. valid.txt contains one line: <absolute-fixture-wheel-path> --hash=sha256:d375a7e7cd1cdee145e6f347603d4c99a15de1a180db406cbd5e577c9aeda737. Use the fixture .venv created by the preceding venv check. Command: <evaluation>\downloads\cli\uv\uv.exe pip install --python <evaluation>\runs\cli\uv\fixture\.venv\Scripts\python.exe --require-hashes --offline -r <evaluation>\runs\cli\uv\fixture\valid.txt- Expected
- Install the exact synthetic wheel with --require-hashes --offline.
- Observed
- Exit 0. Resolved, prepared and installed one package: ionbin-fixture 0.0.1. Hardlinks were unavailable in this environment, so uv fell back to copying.
Import the installed fixtureMet expectation
- Method
<evaluation>\runs\cli\uv\fixture\.venv\Scripts\python.exe -I -c "import ionbin_fixture; print(ionbin_fixture.VALUE)"- Expected
- The isolated interpreter prints the synthetic package value.
- Observed
- Exit 0. synthetic-only
Reject an uncached offline dependencyMet expectation
- Method
<evaluation>\downloads\cli\uv\uv.exe pip install --python <evaluation>\runs\cli\uv\fixture\.venv\Scripts\python.exe --offline ionbin-does-not-exist-12345==0.0.1- Expected
- Fail without fetching an invented package.
- Observed
- Exit 1. No solution found: ionbin-does-not-exist-12345 was not in the cache, and network access was disabled.
Practical caveats
- This fixture used a locally authored pure-Python wheel with no dependencies or build backend.
- The observed hardlink fallback can affect installation cost; no speed comparison was performed.
What this evaluation does not establish
- Public/private indexes, dependency confusion, credential handling, source builds and malicious packages.
- Cross-platform locking, resolver edge cases, Python downloads and real application compatibility.
Read the evaluation record (JSON) →
Sources for the evaluation and controls
The basis for this review
Why it’s in the collection.
An editorial starting point for Python work: requirements and dependency outputs are explicit. Its value is task-specific; no speed or compatibility benchmark was run.
The number is an editorial starting order within the cli tools collection. It does not measure popularity, speed, reliability or safety.
What we reviewed
- Official project, dependency, authentication and command documentation
The evaluation above lists the current runtime coverage and untested behavior.
Reviewed Oct 18, 2026. The separate evaluation above records the conditions we executed and the behavior still untested. Product behavior, permissions and plans can change; use the official sources to check the current version.
Follow the evidence
Official sources.
- uv overview ↗docs.astral.sh
- Dependency management ↗docs.astral.sh
- Command reference ↗docs.astral.sh
- Authentication ↗docs.astral.sh
- Source and license ↗github.com