Where to Find the uv Resolver and Cache Source Code in the astral-sh/uv Repository

The uv resolver and cache source code is located in the crates/ directory of the astral-sh/uv repository, with the resolver implemented in the uv-resolver crate and caching functionality distributed across uv-cache-key, uv-cache-info, uv-fs, and uv-client.

The astral-sh/uv repository is organized as a Rust workspace containing multiple specialized crates under the crates/ directory. If you are looking to understand how uv performs dependency resolution or manages its aggressive caching strategy, you will need to examine specific crates dedicated to these concerns rather than a single monolithic source file.

Understanding the Crate Structure

The uv project follows a modular architecture where functionality is split into focused libraries. The crates/ directory at the repository root contains all sub-crates, each prefixed with uv- to indicate their purpose. When searching for the uv resolver source code or cache implementation, you should look for crates named uv-resolver, uv-cache-key, uv-cache-info, and uv-fs.

Locating the uv Resolver Source Code

The dependency resolution algorithm is implemented entirely within the uv-resolver crate. This crate contains the backtracking solver that determines compatible package versions across Python environments.

Core Resolver Implementation

The primary entry point for the resolver is crates/uv-resolver/src/lib.rs, which exports the Resolver struct and ResolverOptions. The resolution algorithm itself is implemented across several key files:

Resolution Strategies and Preferences

Advanced resolution behavior is controlled by:

Finding the uv Cache Source Code

Unlike the resolver, the caching subsystem is distributed across multiple crates, each handling a specific layer of the cache stack.

Cache Key Generation

The uv-cache-key crate at crates/uv-cache-key/src/cache_key.rs produces deterministic, reproducible cache keys for wheels, source distributions, and build artifacts. These keys ensure that identical inputs always map to the same cache location.

Cache Metadata and Storage

Two crates manage the physical and logical cache structure:

Network and Distribution Caching

Higher-level caching for HTTP requests and Python packages:

CLI Cache Commands

The user-facing cache commands are implemented in the main uv binary crate:

Practical Examples: Interacting with the Resolver and Cache

Below are practical examples demonstrating how the resolver and cache subsystems work in practice, both via CLI and programmatic Rust usage.

Resolving Dependencies via CLI

The uv lock command triggers the full resolution algorithm:


# Resolve requirements and write a lock file

uv lock --requirement requirements.txt

Internally, this creates a Resolver instance from uv_resolver::Resolver and calls resolve(), which traverses graph_ops.rs and candidate_selector.rs to produce a concrete dependency graph.

Inspecting Cache State

Monitor cache utilization using built-in commands:

uv cache size               # Displays total cache size

uv cache prune --dry-run    # Lists entries eligible for removal

These commands walk the directory structure created by uv_fs::cachedir::CacheDir, aggregate file sizes, and respect expiration timestamps from uv_cache_info::CacheInfo.

Bypassing Cache for Fresh Downloads

Force network refresh with:

uv pip install requests --refresh

The --refresh flag instructs uv_client::cached_client::CachedClient to ignore stored HTTP responses and re-download the wheel from PyPI.

Using the Resolver Programmatically

For Rust developers integrating uv's resolver:

use uv_resolver::{Resolver, ResolverOptions, Requirements};
use uv_types::Requirement;

let req = Requirement::from_str("requests==2.31.0")?;
let reqs = Requirements::from_requirements(vec![req]);

let resolver = Resolver::new(ResolverOptions::default());
let resolved = resolver.resolve(&reqs)?;

println!("Resolved version: {}", resolved[0].version);

This example pulls in uv-resolver directly, utilizing the algorithms defined in src/graph_ops.rs and src/candidate_selector.rs.

Programmatic Cache Access

Demonstrating cache key generation and lookup:

use uv_cache_key::CacheKey;
use uv_fs::cachedir::CacheDir;
use std::path::PathBuf;

let key = CacheKey::new("requests", "2.31.0", "cp311-cp311-manylinux_2_17_x86_64.whl");
let cache_dir = CacheDir::default(); // Resolves to $XDG_CACHE_HOME/uv
let cached_path: PathBuf = cache_dir.path().join(key.to_path());

if cached_path.exists() {
    println!("Found cached wheel at {}", cached_path.display());
}

This shows how uv-cache-key generates deterministic identifiers and how uv-fs::cachedir resolves the physical storage location.

Summary

  • The uv resolver source code lives in the uv-resolver crate under crates/uv-resolver/src/, with core logic in lib.rs, graph_ops.rs, and candidate_selector.rs.
  • The uv cache source code is distributed across multiple crates: uv-cache-key for key generation, uv-cache-info for metadata, uv-fs for directory operations, and uv-client for HTTP caching.
  • The main uv binary crate implements CLI commands like uv cache dir, uv cache prune, and uv cache size in crates/uv/src/commands/cache_*.rs.
  • All components follow a modular Rust architecture under the top-level crates/ directory in the astral-sh/uv repository.

Frequently Asked Questions

Where is the uv resolver algorithm implemented?

The uv resolver algorithm is implemented in the uv-resolver crate located at crates/uv-resolver/src/. The entry point is lib.rs, which exports the Resolver struct. The core resolution logic resides in graph_ops.rs (dependency graph construction), candidate_selector.rs (version selection and backtracking), and fork_strategy.rs (handling Python version markers). This crate implements the backtracking solver that determines compatible package versions across different Python environments and platforms.

How does uv handle cache key generation?

Cache key generation is handled by the uv-cache-key crate in crates/uv-cache-key/src/cache_key.rs. This crate produces deterministic, reproducible cache keys for wheels, source distributions, and build artifacts. The keys incorporate package name, version, platform tags, and build requirements to ensure that identical inputs always map to the same cache location. This deterministic approach allows uv to safely reuse cached artifacts across different projects and virtual environments without collisions.

What commands can I use to manage the uv cache?

The uv CLI provides several commands to inspect and manage the cache, implemented in crates/uv/src/commands/. Use uv cache dir to display the cache directory location, uv cache size to check total disk usage, and uv cache prune to remove unused entries. The --dry-run flag with cache prune shows what would be deleted without removing files. To bypass the cache entirely for a specific operation, use the --refresh flag with install commands, which forces uv-client to re-download packages from PyPI.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →