uv para Python: guía práctica para reemplazar pip, venv y pip-tools en tu equipo

Por Felipe Traina · 28/9/2026 · 6 min · python, herramientas, uv, productividad

Crear un entorno virtual, instalar dependencias, fijar versiones con pip-tools, manejar versiones de Python con pyenv e instalar herramientas de línea de comandos con pipx: en muchos proyectos Python eso son cinco herramientas distintas. uv, el gestor de paquetes y proyectos de Astral (los creadores de Ruff), propone reemplazarlas con un solo binario escrito en Rust. Su documentación afirma que es entre 10 y 100 veces más rápido que pip.

Lo presentamos en un Short de herramientas; acá va la versión completa, pensada para un equipo que quiere evaluar la migración sin sorpresas.

Qué reemplaza uv

Según la documentación oficial, uv cubre el trabajo de pip, pip-tools, pipx, poetry, pyenv, twine y virtualenv, entre otros. Las piezas principales:

Necesidad Antes Con uv
Crear entorno virtual python -m venv .venv uv venv (o automático con uv sync)
Instalar dependencias pip install -r requirements.txt uv sync o uv pip install -r requirements.txt
Fijar versiones pip-compile uv lock / uv pip compile
Versiones de Python pyenv install 3.12 uv python install 3.12
Herramientas CLI pipx install ruff uv tool install ruff o uvx ruff
Scripts sueltos con dependencias entorno manual uv run script.py con metadatos inline

Además se puede instalar sin tener Rust ni Python previamente, y funciona en macOS, Linux y Windows.

Instalación

El instalador oficial:

# macOS y Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

También se puede instalar con pip, Homebrew y otros métodos listados en la página de instalación. En entornos corporativos, conviene fijar una versión concreta en lugar de "la última".

Flujo de proyecto: init, add, run

El flujo básico para un proyecto nuevo:

uv init mi-app          # crea pyproject.toml y la estructura mínima
cd mi-app
uv add requests         # agrega la dependencia, crea .venv y actualiza uv.lock
uv add --dev pytest     # dependencia de desarrollo
uv run python app.py    # ejecuta dentro del entorno del proyecto
uv run pytest

Dos archivos importan:

uv run verifica que el entorno esté sincronizado con el lockfile antes de ejecutar, así que no hace falta "activar" el entorno virtual para el uso diario.

Migrar un proyecto existente sin romper nada

No hace falta migrar todo de golpe. uv tiene una interfaz compatible con pip que sirve como primer paso:

# Paso 1: mismo flujo, más rápido
uv venv
uv pip install -r requirements.txt

# Paso 2: reemplazar pip-tools
uv pip compile requirements.in -o requirements.txt

Cuando el equipo esté cómodo, el paso siguiente es pasar al flujo de proyecto con pyproject.toml y uv.lock. Si alguna herramienta de despliegue todavía necesita un requirements.txt, se puede generar desde el lockfile:

uv export --format requirements.txt -o requirements.txt

uv export también soporta pylock.toml (PEP 751) y CycloneDX 1.5 en JSON, útil si necesitás un SBOM.

Scripts sueltos con dependencias declaradas

Una de las funciones más prácticas para tareas de mantenimiento o automatizaciones chicas: declarar las dependencias dentro del propio script.

echo 'import requests; print(requests.get("https://astral.sh"))' > ejemplo.py
uv add --script ejemplo.py requests   # agrega metadatos inline al archivo
uv run ejemplo.py                     # lo ejecuta en un entorno aislado

El script queda autocontenido: cualquiera con uv puede ejecutarlo sin preparar nada.

uv en CI

En integración continua, la regla es simple: el pipeline tiene que fallar si el lockfile no refleja pyproject.toml. Para eso existe --locked:

uv sync --locked    # falla si uv.lock tendría que cambiar
uv run pytest

La documentación también ofrece --frozen, que usa el lockfile tal como está sin verificarlo contra pyproject.toml. Para CI, --locked es la opción más segura porque detecta lockfiles desactualizados. Astral mantiene una integración oficial para GitHub Actions y una guía para otros sistemas de CI.

uv en Docker

La guía oficial de Docker muestra cómo copiar los binarios desde la imagen de uv. Conviene fijar la versión (o incluso el digest) en lugar de usar latest:

FROM python:3.12-slim
COPY --from=ghcr.io/astral-sh/uv:0.12.20 /uv /uvx /bin/

WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --locked --no-install-project
COPY . .
RUN uv sync --locked
CMD ["uv", "run", "python", "app.py"]

Separar la instalación de dependencias de la copia del código aprovecha la caché de capas de Docker: si solo cambia tu código, las dependencias no se reinstalan.

Seguridad de dependencias: exclude-newer

uv tiene una opción que ayuda contra paquetes maliciosos recién publicados: exclude-newer, que limita los candidatos a los archivos subidos antes de una fecha o de una ventana de tiempo. Acepta fechas RFC 3339 o duraciones como 7 days:

# pyproject.toml
[tool.uv]
exclude-newer = "7 days"

Con esto, una versión publicada hace unas horas (por ejemplo, tras el robo de credenciales de un mantenedor) no entra en tu resolución hasta que pasen siete días. Tiene un costo: los parches de seguridad urgentes también esperan, así que conviene combinarlo con --exclude-newer-package para excepciones puntuales.

Qué hacer con esto

Un plan de adopción gradual:

La velocidad es lo primero que se nota, pero el beneficio más duradero es tener un solo flujo reproducible para todo el equipo.

¿Tu equipo ya migró a uv o sigue con la combinación de pip, venv y pip-tools?

Lecturas relacionadas

En video (Short de menos de 1 minuto): uv: instala dependencias de Python hasta 100× más rápido

Fuentes

← Volver al blog