Si llevas tiempo trabajando con Python, sabes lo que toca hacer al arrancar un proyecto nuevo: instalar pip, crear el virtualenv, activarlo, instalar pip-tools para compilar dependencias, y si encima necesitas cambiar de versión de Python, añadir pyenv a la mezcla. Cuatro herramientas distintas para algo que debería ser trivial.
pip funciona, pero es lento. Resuelve las dependencias de forma secuencial, sin caché agresiva, y en proyectos con muchos paquetes puedes esperar minutos para algo que uv resuelve en segundos. No es exageración: la documentación oficial de uv habla de ser entre 10 y 100 veces más rápido, y en la práctica se nota desde el primer uso.
uv lo ha creado Astral, la misma empresa detrás de Ruff, el linter Python que ya ha desplazado a flake8 y pylint en muchos proyectos. Está escrito en Rust, resuelve dependencias en paralelo y mantiene una caché local que hace que instalaciones repetidas sean casi instantáneas. Un solo binario para todo.
Instalación y primeros pasos
Instalar uv es rápido. En Linux o macOS:
curl -LsSf https://astral.sh/uv/install.sh | sh
En Windows, desde PowerShell:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Una vez instalado, crear un virtualenv y activarlo:
uv venv
source .venv/bin/activate
Si tienes un requirements.txt y quieres seguir con el flujo clásico de pip, uv es un drop-in replacement exacto:
uv pip install -r requirements.txt
La diferencia de velocidad se nota sobre todo aquí. Un proyecto con 50 dependencias que tardaba 45 segundos con pip puede bajar a 3-4 segundos con uv, dependiendo de la caché.
Hay algo que cambia el flujo de trabajo desde el principio: no tienes que activar el virtualenv para ejecutar código. Con uv run, uv detecta el entorno del proyecto y lo usa directamente:
uv run python script.py
Proyectos con uv: el flujo moderno
El modo más interesante de usar uv no es como sustituto de pip, sino como gestor de proyecto completo. Para empezar uno desde cero:
uv init mi-proyecto
cd mi-proyecto
Esto crea un directorio con pyproject.toml, .python-version y un README.md básico. A partir de aquí, añadir dependencias:
uv add requests fastapi
uv actualiza el pyproject.toml y genera (o actualiza) el uv.lock automáticamente. Para dependencias que solo necesitas en desarrollo:
uv add --dev pytest ruff
Para instalar todo lo que especifica el lockfile, por ejemplo al clonar el repositorio en otra máquina:
uv sync
Y para actualizar el lockfile a las últimas versiones compatibles con las restricciones del pyproject.toml:
uv lock --upgrade
uv.lock: instalaciones reproducibles de verdad
El lockfile de uv no es un requirements.txt glorificado. Incluye los hashes de todos los paquetes, lo que garantiza que la instalación en tu máquina es byte a byte idéntica a la del servidor de CI o la del compañero que clonó el repo la semana pasada.
Otra diferencia importante: uv.lock es multiplataforma. Un solo archivo funciona en Linux, macOS y Windows, sin que tengas que mantener varios requirements-*.txt por entorno.
Para CI, donde no quieres que el lockfile cambie sin querer:
uv sync --frozen
Esto instala exactamente lo que dice el lockfile y falla si hay discrepancias. Útil para detectar que alguien tocó las dependencias sin actualizar el lock.
Gestión de versiones de Python
Una de las partes que más convence a quienes venían usando pyenv es que uv también gestiona las versiones de Python. Para instalar Python 3.13:
uv python install 3.13
Para ver qué versiones tienes instaladas y cuáles están disponibles:
uv python list
Si el proyecto tiene un archivo .python-version (que uv init crea por defecto), uv usa esa versión de forma automática. No tienes que acordarte de cambiar con pyenv local cada vez que cambias de directorio.
Para proyectos con Python 2, dependencias de sistema muy específicas o configuraciones raras de entorno corporativo puede que pyenv siga siendo necesario, pero para el 95% de los casos de uso habituales, uv lo cubre sin complicaciones.
uv run: ejecutar sin activar el entorno
Ya lo hemos mencionado antes, pero merece su propia sección porque cambia bastante el día a día. uv run detecta el proyecto actual, usa su entorno y ejecuta lo que le pidas:
uv run script.py
uv run pytest
uv run python -m mymodule
Lo que hace especialmente útil es la opción --with, que instala un paquete de forma temporal solo para esa ejecución, sin que quede en el proyecto:
uv run --with httpx script.py
httpx se instala en un entorno efímero, se ejecuta el script y listo. No contamina el pyproject.toml ni el lockfile.
uv tool y uvx: herramientas globales sin ensuciarlo todo
Antes de uv, la forma más limpia de instalar herramientas de línea de comandos Python de forma global era pipx. uv lo reemplaza con uv tool:
uv tool install ruff
uv tool install black
Cada herramienta se instala en su propio entorno aislado, así que no hay conflictos entre versiones y no ensucias el Python del sistema. Para ejecutar una herramienta sin instalarla permanentemente, uvx:
uvx ruff check .
uvx black --check .
Es el equivalente de pipx run, pero más rápido porque uv descarga y cachea en segundos. Si ya tienes ruff instalado con uv tool install, uvx ruff usa la versión instalada directamente.
uv vs pip, Poetry y conda en 2026
Dependiendo de dónde vengas, la comparación que te interesa es distinta:
- pip + venv: La opción más simple y la que todo el mundo conoce. El problema es la velocidad y la falta de un lockfile serio. uv es compatible con este flujo y lo hace más rápido sin cambiar nada.
- Poetry: Buena gestión de dependencias y lockfile, pero más lento y con una curva de configuración que a veces da guerra. uv cubre los mismos casos con menos fricción y mayor velocidad.
- conda: Sigue siendo necesario cuando tienes dependencias que no son Python puro, como paquetes con extensiones C, CUDA o binarios del sistema para machine learning. Para proyectos ML con dependencias de sistema, conda o mamba son todavía la opción más cómoda. Para Python puro, uv gana sin discusión.
El resumen práctico: si tu proyecto es Python sin dependencias de sistema raras, uv es hoy la mejor opción. Si trabajas con ML y necesitas paquetes como CUDA toolkit o librerías C compiladas, conda sigue ahí para eso.
Referencia rápida de comandos
uv venv crear virtualenv en.venv/uv pip install requests instalar paquete en modo compatibilidad pipuv init mi-proyecto inicializar proyecto conpyproject.tomluv add requests añadir dependencia al proyectouv add --dev pytest añadir dependencia de desarrollouv sync instalar todo lo del lockfileuv sync --frozen instalar sin actualizar el lockfile (para CI)uv lock --upgrade actualizar el lockfileuv run script.py ejecutar en el entorno del proyectouv run --with httpx script.py ejecutar con dependencia temporaluv python install 3.13 instalar una versión de Pythonuv python list listar versiones disponibles e instaladasuv tool install ruff instalar herramienta global aisladauvx ruff check . ejecutar herramienta sin instalar permanentemente
Si te interesa estructurar bien un proyecto Python desde cero, este artículo sobre herramientas Python: del script al proyecto completo cubre el proceso desde el script suelto hasta el paquete distribuible. Y si usas Python para machine learning y quieres saber cómo gestionar los entornos en ese contexto, mira también entornos Python para ML: de virtualenv a uv.
Imagen: Pexels / Markus Winkler
