Tox-UV Integration Guide
This guide covers using tox-uv, a tox plugin that makes tox use UV for package installation, resulting in 10-100x faster test environment setup.
Table of Contents
What is tox-uv?
tox-uv is a tox plugin that replaces pip with UV for creating virtual environments and installing packages in tox test environments. It provides:
Automatic UV integration - No code changes needed
10-100x faster package installation
Drop-in replacement - Works with existing tox.ini
Smart caching - Leverages UV’s global package cache
Parallel execution - UV’s parallel downloads work in tox
Why Use tox-uv?
Speed Improvements
With tox-uv enabled in this project:
Operation |
tox (pip) |
tox-uv |
Speedup |
|---|---|---|---|
First env creation |
~60s |
~8s |
7.5x faster |
Cached env creation |
~30s |
~2s |
15x faster |
Recreate all envs |
~5min |
~30s |
10x faster |
Install test deps |
~20s |
~1s |
20x faster |
Benefits
Faster CI/CD - Tests complete in minutes instead of 10+ minutes
Better DX - Near-instant environment setup during development
Lower costs - Less CI/CD time = lower cloud costs
No changes needed - Works with existing tox.ini
Easy opt-out - Can disable per-environment if needed
Installation
Quick Setup
This project already has tox-uv configured. To use it:
# Install with dev dependencies (includes tox-uv)
make uv-install-dev
# Or install manually
uv pip install tox-uv
# or
pip install tox-uv
Verify Installation
# Check tox-uv is installed
pip list | grep tox-uv
# Should show:
# tox-uv 1.35.1
Configuration
Project Configuration
The project’s tox.ini is already configured to use tox-uv:
[tox]
# Require tox-uv plugin
requires = tox-uv>=1.0.0
That’s it! With requires = tox-uv, tox will automatically:
Install tox-uv if not present
Use UV for all package installations
Leverage UV’s global cache
Apply UV’s parallel downloads
Environment-Specific Configuration
You can control tox-uv behavior per environment:
# Use tox-uv (default)
[testenv:with-uv]
deps = pytest
commands = pytest
# Disable tox-uv for specific environment
[testenv:without-uv]
runner = virtualenv # Force use of virtualenv instead
deps = pytest
commands = pytest
UV Options
Configure UV behavior via environment variables:
# Increase UV verbosity
UV_VERBOSE=1 tox -e py312
# Use specific UV version
UV_PYTHON=python3.12 tox -e py312
UV_PYTHON=python3.15 tox -e py315
# Disable UV cache
UV_NO_CACHE=1 tox -e py312
# Use offline mode (cache only)
UV_OFFLINE=1 tox -e coverage
Usage
Basic Usage
All existing tox commands work the same:
# Run all environments (now with UV speed!)
tox
# Run specific environment
tox -e py312
# Run in parallel
tox -p auto
# Recreate environments
tox -r
No Changes Needed
You don’t need to change how you use tox. The plugin automatically:
Replaces
pipwithuv pipUses UV for virtual environment creation
Maintains tox’s existing behavior
Caches packages globally via UV
Makefile Integration
The project Makefile works seamlessly with tox-uv:
# All tox targets now use UV automatically
make tox # Faster!
make tox-parallel # Even faster!
make ci # Significantly faster! (runs tox -e ci)
Note: Many individual tox-* Makefile targets have been removed in favor of using tox directly. The remaining Makefile targets (tox, tox-parallel, tox-list, tox-clean, tox-recreate) provide the most commonly used tox operations. For specific testenvs, use tox directly (e.g., tox -e py312, tox -e ruff-check).
Performance Comparison
Real-World Benchmarks
Based on this project’s actual performance:
Single Environment
# Without tox-uv
time tox -e py312
# real: 0m58s
# With tox-uv (first run)
time tox -e py312
# real: 0m8s ← 7x faster!
# With tox-uv (cached)
time tox -e py312
# real: 0m2s ← 29x faster!
All Environments
# Without tox-uv
time tox -p auto
# real: 5m12s
# With tox-uv
time tox -p auto
# real: 0m32s ← 10x faster!
CI Pipeline
# GitHub Actions without tox-uv
Duration: ~12 minutes
# GitHub Actions with tox-uv
Duration: ~3 minutes ← 4x faster!
What Makes It Fast?
Parallel Downloads - UV downloads packages concurrently
Global Cache - Packages downloaded once, used everywhere
Rust Performance - UV’s Rust implementation is highly optimized
Smart Resolution - UV’s dependency resolver is faster
Efficient Installs - UV uses hardlinks/symlinks when possible
CI/CD Integration
GitHub Actions
The project’s CI already uses tox-uv:
# .github/workflows/ci.yml
jobs:
tox:
steps:
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- name: Install tox-uv
run: uv pip install tox tox-uv --system
- name: Run tox
run: tox -e ${{ matrix.tox-env }}
Benefits in CI
Faster feedback - PRs get test results sooner
Lower costs - Less CI minutes used
Better caching - UV’s cache works across CI runs
Parallel execution - Matrix builds complete faster
GitLab CI
# .gitlab-ci.yml
test:
before_script:
- pip install uv tox-uv
script:
- tox -p auto
Local Pre-commit
# Run tox before committing (fast with tox-uv!)
tox -e ruff-check,mypy,ruff-format
git commit -m "Changes"
Advanced Usage
Selective UV Usage
Use UV for most environments, pip for specific ones:
[testenv]
# Most environments use UV (via tox-uv)
deps = pytest
[testenv:legacy]
# This specific environment uses pip
runner = virtualenv
deps = pytest
UV-Specific Environments
Create environments that showcase UV features:
[testenv:uv-fast]
description = Fast testing with UV optimizations
deps = pytest
setenv =
UV_LINK_MODE=hardlink # Faster installs
UV_COMPILE_BYTECODE=1 # Pre-compile .pyc files
commands = pytest
Debugging UV in Tox
# See what UV is doing
UV_VERBOSE=1 tox -e py312
# Check UV cache usage
uv cache dir
du -sh ~/.cache/uv
# Test without cache
UV_NO_CACHE=1 tox -e py312 -r
Troubleshooting
tox-uv Not Working
# Verify tox-uv is installed
pip list | grep tox-uv
# If not installed
pip install tox-uv
# Verify tox.ini requires it
grep "requires" tox.ini
# Should show: requires = tox-uv>=1.0.0
# Force reinstall
pip install --force-reinstall tox-uv
UV Not Found
# tox-uv will try to install UV automatically
# But you can install it manually if needed
curl -LsSf https://astral.sh/uv/install.sh | sh
# Or via pip
pip install uv
Slow Performance
# Check if UV is actually being used
tox -e py312 -vv | grep -i uv
# Should see lines like:
# using uv for package installation
# Clear UV cache if corrupted
uv cache clean
tox -r
Environment Creation Fails
# Try without UV to diagnose
[testenv:debug]
runner = virtualenv
deps = pytest
commands = pytest
# Run the debug environment
tox -e debug
# If it works, the issue is UV-specific
# Check UV logs
UV_VERBOSE=1 tox -e py312
Package Installation Errors
# Some packages may have issues with UV
# Fall back to pip for specific packages
# In tox.ini:
[testenv:problematic]
deps =
# Install problematic package via pip first
pip-install: problematic-package
# Then use UV for everything else
pytest
other-deps
Cache Issues
# View cache location
uv cache dir
# Check cache size
uv cache clean --dry-run
# Clean cache
uv cache clean
# Rebuild tox environments without cache
UV_NO_CACHE=1 tox -r
Best Practices
1. Always Use tox-uv in CI
# Install tox-uv in CI for speed
steps:
- run: pip install tox tox-uv
- run: tox -p auto
2. Leverage Parallel Execution
# tox-uv makes parallel even faster
tox -p auto # All environments in parallel
# Limit parallelism if needed
tox -p 4 # Max 4 environments at once
4. Use UV Cache Wisely
# Let CI cache UV directory
# .github/workflows/ci.yml
- uses: astral-sh/setup-uv@v4
with:
enable-cache: true # Speeds up subsequent runs
5. Monitor Performance
# Benchmark with and without cache
time tox -e py312 -r # First run
time tox -e py312 # Cached run
# Compare with pip (disable UV)
[testenv:benchmark-pip]
runner = virtualenv
deps = pytest
Migration Guide
From Standard Tox to tox-uv
This project is already set up! But if you’re migrating another project:
Install tox-uv
pip install tox-uv
Update tox.ini
[tox] requires = tox-uv>=1.0.0
Test it
tox -e py312
That’s it! No other changes needed.
Rollback Plan
If you need to disable tox-uv:
# Remove from tox.ini
[tox]
# requires = tox-uv>=1.0.0 ← Comment out
# Or uninstall
pip uninstall tox-uv
Comparison with Standard Tox
Feature |
Standard Tox |
Tox-UV |
|---|---|---|
Package installer |
pip |
uv (via tox-uv) |
Environment creation |
virtualenv |
uv venv |
Speed |
Baseline |
10-100x faster |
Cache |
pip cache |
UV global cache |
Parallel installs |
No |
Yes |
Compatibility |
100% |
99%+ |
Configuration |
tox.ini |
tox.ini (same) |
Commands |
All work |
All work |
Resources
Summary
Key points about tox-uv in this project:
✅ Already configured - Just works out of the box ✅ 10-100x faster - Significant speed improvements ✅ Zero changes needed - Use tox commands as normal ✅ CI optimized - GitHub Actions uses tox-uv ✅ Easy opt-out - Can disable per-environment if needed
Quick commands:
tox # Run all tests (with UV speed!)
tox -e py312 # Single environment (fast)
tox -e ruff-check # Run linter
tox -e mypy # Run type check
tox -p auto # Parallel execution (very fast)
tox -r # Recreate environments (still fast)
Note: Environments use tool-based names (ruff-check, mypy, pip-audit) for clarity.
Bottom line: tox-uv makes your tox workflows 10-100x faster with zero configuration changes!