Durante años el setup de un proyecto Python requería varios pasos: instalar pyenv para gestionar la versión de Python, crear un entorno virtual con venv o virtualenv, instalar paquetes con pip y, si querías un lockfile serio, añadir pip-tools o pasarte a poetry. Cuatro herramientas distintas, cuatro documentaciones, cuatro formas de romperse.
uv hace todo eso desde un único binario escrito en Rust. Lo desarrolla Astral, la empresa detrás de Ruff (el linter de Python). La versión 0.11.8 salió en abril de 2026 y en este momento es la herramienta de gestión de proyectos Python con mayor crecimiento en GitHub.
Qué sustituye exactamente
La tabla es directa:
Herramienta anterior | Equivalente en uv |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Por qué es tan rápido
uv está escrito en Rust y aprovecha un caché global de dependencias: una vez descargado un paquete, no se vuelve a descargar aunque crees diez entornos distintos que lo usen. La creación de entornos virtuales tarda milisegundos en lugar de segundos porque en lugar de copiar ficheros usa hardlinks o reflinks según el sistema de archivos.
En benchmarks publicados, instalar JupyterLab tarda 21 segundos con pip y 2,6 con uv. En proyectos más grandes la diferencia es mayor. Para CI/CD, donde se crea el entorno desde cero en cada ejecución, el ahorro es significativo.
Flujo de trabajo básico
Iniciar un proyecto nuevo:
uv init mi-proyecto cd mi-proyecto uv add requests pandas
Esto crea un pyproject.toml, un uv.lock (el lockfile universal) y el entorno virtual. El lockfile se incluye en el repositorio para reproducibilidad exacta en todos los entornos.
Para sincronizar dependencias en otro equipo o en CI:
uv sync
Para ejecutar un script sin activar el entorno manualmente:
uv run python app.py uv run pytest
Scripts con dependencias inline (PEP 723)
Una funcionalidad especialmente útil para scripts de automatización: puedes declarar las dependencias del script dentro del propio fichero con el formato PEP 723, y uv las instala y ejecuta automáticamente:
# /// script
# requires-python = ">=3.11"
# dependencies = ["requests", "rich"]
# ///
import requests
from rich import print
print(requests.get("https://api.github.com").json())
Ejecutas el script con uv run script.py y uv se encarga del resto, sin necesidad de crear un proyecto ni un entorno previo.
Gestión de versiones de Python
Ya no necesitas pyenv. uv puede descargar e instalar cualquier versión de CPython:
uv python install 3.13 uv python install 3.11 3.12 # instalar varias a la vez
El proyecto puede fijar la versión en pyproject.toml con requires-python = ">=3.12" y uv la usará automáticamente al crear el entorno.
Workspaces para monorepos
Si tienes varios paquetes Python en el mismo repositorio (por ejemplo, una librería y una API que la usa), uv soporta workspaces al estilo Cargo. Cada subpaquete tiene su propio pyproject.toml pero comparten el lockfile raíz, lo que evita conflictos de versiones entre paquetes del mismo repo.
Migración desde un proyecto existente
Si ya tienes un requirements.txt, puedes importarlo directamente:
uv pip install -r requirements.txt
Para proyectos con pyproject.toml existente (poetry, setuptools), uv lo lee sin cambios. El camino de migración recomendado es: añadir uv.lock al repositorio, reemplazar pip install por uv sync y python por uv run en los scripts de CI.
Limitaciones actuales
uv no gestiona dependencias que no son Python: si tu proyecto necesita CUDA, cuDNN, ffmpeg u otras librerías de sistema, eso sigue siendo responsabilidad tuya. La versión todavía no llega a 1.0 (la última estable es 0.11.x), aunque en la práctica el proyecto es muy estable en producción.
Para proyectos de machine learning que sí usen librerías como las de Python con LLMs, uv gestiona perfectamente las dependencias Python (transformers, torch, etc.) aunque el driver CUDA lo tengas instalado aparte.
Imagen: Pexels / Jakub Zerdzicki
