uv, el gestor de paquetes moderno de Python

Intermedio
Python
Python
Actualizado: 05/05/2026

Qué es uv y por qué ha cambiado el ecosistema

flowchart TD
    UV["uv (Astral, Rust)"] --> INIT["uv init: nuevo proyecto"]
    UV --> ADD["uv add / remove: dependencias"]
    UV --> SYNC["uv sync: instalar lock"]
    UV --> LOCK["uv.lock: bloqueo reproducible"]
    UV --> RUN["uv run: ejecuta scripts"]
    UV --> TOOL["uv tool: instala herramientas (pipx)"]
    UV --> PY["uv python: gestión de intérpretes (pyenv)"]
    UV -.->|reemplaza| LEGACY["pip + venv + pip-tools + pipx + pyenv"]

uv es un gestor de paquetes y proyectos Python desarrollado por Astral, la misma empresa que creó el linter ruff. Está escrito en Rust y su objetivo es reemplazar pip, venv, pip-tools, pipx y pyenv con una única herramienta que hace todo lo que antes requería combinar varias.

Sus dos propuestas de valor son la velocidad y la simplificación. En benchmarks habituales, uv es entre 10 y 100 veces más rápido que pip porque resuelve dependencias en paralelo y mantiene una caché global compartida entre proyectos. La instalación de dependencias grandes como numpy o torch pasa de minutos a segundos.

uv no es solo un pip más rápido: es una herramienta de proyecto completa al estilo de Cargo (Rust) o Poetry, con bloqueo de dependencias, scripts y gestión de intérpretes Python integrada.

A día de hoy uv es el estándar de facto para proyectos Python nuevos en empresas modernas. Equipos que antes usaban pip + venv + pip-tools han migrado en bloque porque el flujo de trabajo es más simple y los tiempos de CI bajan drásticamente.

Instalación de uv

uv se instala como un binario autónomo, sin depender de Python previamente instalado. Es portable y no interfiere con las instalaciones de Python del sistema.

En macOS y Linux:

curl -LsSf https://astral.sh/uv/install.sh | sh

En Windows (PowerShell):

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

Tras instalar, verifica que el comando está disponible:

uv --version

Una vez instalado, uv puede gestionar sus propias actualizaciones:

uv self update

Crear un proyecto con uv

El flujo moderno empieza por uv init, que crea la estructura de un proyecto Python con pyproject.toml, entorno virtual y README. No es necesario crear manualmente el venv ni el requirements.txt.

uv init mi-proyecto
cd mi-proyecto

La estructura generada contiene:

mi-proyecto/
  .python-version
  README.md
  hello.py
  pyproject.toml

El archivo pyproject.toml es el manifiesto del proyecto. Allí se declaran el nombre, la versión, las dependencias y el intérprete Python requerido:

[project]
name = "mi-proyecto"
version = "0.1.0"
requires-python = ">=3.13"
dependencies = []

El archivo .python-version fija la versión de Python que debe usar el proyecto, y uv la respeta automáticamente sin necesidad de herramientas externas como pyenv.

Gestionar dependencias

Para añadir una dependencia, se usa uv add. A diferencia de pip install, uv add actualiza automáticamente pyproject.toml, crea el entorno virtual si no existe y regenera el archivo de bloqueo uv.lock.

uv add requests
uv add "fastapi>=0.115" "uvicorn[standard]"

Para dependencias de desarrollo (tests, linters, formatters), usa la bandera --dev:

uv add --dev pytest pytest-cov ruff

Estas quedan aisladas en un grupo separado, se instalan en desarrollo pero no se incluyen cuando alguien instala tu paquete como dependencia.

Para eliminar una dependencia:

uv remove requests

Bloqueo reproducible con uv.lock

Uno de los grandes problemas del pip tradicional es que pip install -r requirements.txt no garantiza que dos máquinas obtengan exactamente las mismas versiones. uv soluciona esto con uv.lock, un archivo generado automáticamente que fija las versiones exactas de todas las dependencias directas y transitivas.

Cada vez que ejecutas uv add, uv actualiza el lock. Para sincronizar el entorno al estado exacto del lock:

uv sync

Este comando instala las versiones exactas registradas en uv.lock, garantizando reproducibilidad entre desarrolladores y entre entornos (local, CI, producción). Es el equivalente a npm ci en Node o cargo build --locked en Rust.

Commits típicos: pyproject.toml y uv.lock van siempre al repositorio. El directorio .venv/ se añade a .gitignore. Cualquier persona que clone el repo reconstruye el entorno idéntico con un solo uv sync.

Ejecutar código y herramientas

uv run ejecuta cualquier comando dentro del entorno virtual del proyecto sin necesidad de activarlo manualmente.

uv run python app.py
uv run pytest
uv run ruff check .

Es mucho más práctico que source .venv/bin/activate en cada terminal nueva.

Para herramientas globales (equivalente a pipx), usa uv tool:

uv tool install ruff
uv tool install httpie
ruff check .

uv tool instala cada herramienta en su propio entorno aislado, igual que pipx, pero con la velocidad y la caché compartida de uv.

Gestionar versiones de Python

uv integra la instalación de intérpretes, cubriendo el rol de pyenv:

uv python install 3.13
uv python install 3.12 3.11
uv python list

Para usar una versión concreta en un proyecto:

uv python pin 3.13

Esto actualiza el archivo .python-version y uv descargará e instalará esa versión si no la tienes.

Scripts independientes con PEP 723

Una funcionalidad moderna es ejecutar scripts sueltos con dependencias declaradas en el propio archivo, siguiendo el estándar PEP 723.

# analizar.py
# /// script
# requires-python = ">=3.13"
# dependencies = [
#     "requests",
#     "rich",
# ]
# ///
import requests
from rich import print

r = requests.get("https://api.github.com/repos/astral-sh/uv")
print(r.json()["stargazers_count"])
uv run analizar.py

uv detecta las dependencias del script, crea un entorno efímero, las instala y ejecuta el archivo. Ideal para scripts de automatización que necesitan librerías sin crear un proyecto entero.

Flujo de trabajo completo

Un día a día típico con uv se reduce a cuatro comandos:

uv init mi-app              # crear proyecto
uv add fastapi pydantic     # añadir dependencias de producción
uv add --dev pytest ruff    # añadir dependencias de desarrollo
uv sync                     # instalar todo lo del lock

uv run python src/main.py   # ejecutar
uv run pytest               # tests
uv run ruff check .         # linter

Con esto reemplazas por completo la combinación clásica de python -m venv, source .venv/bin/activate, pip install, pip freeze > requirements.txt, pyenv install, pyenv local y pipx install.

Migración desde requirements.txt

Si tienes un proyecto con requirements.txt, puedes migrarlo en un paso:

uv init --lib mi-lib       # o uv init para app
uv add -r requirements.txt

Esto importa cada línea de requirements.txt al pyproject.toml y genera el uv.lock correspondiente. Tras verificar, puedes archivar o eliminar el requirements.txt antiguo.

Para exportar compatibilidad temporal con herramientas que aún dependen de requirements.txt (CI antiguos, Dockerfiles):

uv export --format requirements-txt > requirements.txt

Esto regenera el fichero a partir del lock en cualquier momento, sin perder la fuente de verdad que vive en pyproject.toml y uv.lock.

Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Python es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Python

Explora más contenido relacionado con Python y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

Instalar uv en cualquier sistema operativo. Crear proyectos Python con uv init y gestionar dependencias con uv add y uv remove. Sincronizar entornos reproducibles con uv sync y uv lock. Ejecutar scripts y herramientas con uv run y uv tool. Instalar y cambiar entre versiones de Python con uv python.