Logotipo de Bitdoze

Primeros pasos con uv: configuración de proyectos Python en 2026

¿Empiezas con uv? Aprende a instalar uv, configurar un proyecto Python y gestionar dependencias, entornos virtuales y versiones de Python en esta guía de 2026.

Dragos

Actualizado Publicado 20 min de lectura

Primeros pasos con uv: configuración de proyectos Python en 2026

Si alguna vez has peleado con pip, venv y pyenv para poner en marcha un proyecto de Python, esta guía de primeros pasos con uv es para ti. uv es un gestor de paquetes y proyectos de Python escrito en Rust por el equipo de Astral (los mismos que están detrás del linter ruff). Desde su lanzamiento en febrero de 2024, ha llegado a ~88.800 estrellas en GitHub y ha sustituido un mosaico de cinco o seis herramientas por un único binario entre 10 y 100 veces más rápido que pip.

En este artículo veremos cómo instalar uv, crear un proyecto de Python desde cero, gestionar dependencias y versiones de Python, compilar y desplegar, y evitar los problemas más comunes con los que suele chocar la gente. Todos los comandos están actualizados a uv 0.12.5 (agosto de 2026).

¿Qué es uv?

uv es un gestor de paquetes y proyectos de Python todo en uno que sustituye a pip, venv, pipx, poetry y pyenv en un único binario de Rust. Usa pyproject.toml (PEP 621) para la configuración y un archivo uv.lock multiplataforma para builds reproducibles.

Diferencias clave:

  • Velocidad: entre 10 y 100 veces más rápido que pip gracias a un resolvedor de dependencias escrito en Rust y a una caché agresiva.
  • Flujo de trabajo unificado: paquetes, entornos virtuales, versiones de Python, ejecución de scripts y compilación/publicación, todo en una sola herramienta.
  • Basado en estándares: usa pyproject.toml (PEP 621) y [dependency-groups] (PEP 735), no archivos de configuración propietarios.
  • Sin activación manual: uv run gestiona el entorno virtual automáticamente. Se acabó el source .venv/bin/activate.

Benchmark de velocidad de instalación del gestor de paquetes uv: entre 10 y 100 veces más rápido que pip

uv sustituye más de lo que crees

uv no es solo un instalador de paquetes. Sustituye a pip, venv, pipx, poetry y pyenv en un único binario de Rust. Si lo instalas, puedes olvidarte de todas esas otras herramientas.

Configura tu proyecto de Python con uv

En esta sección instalaremos uv y crearemos un nuevo proyecto de Python desde cero.

Despliega tu proyecto con uv

Para ver cómo desplegar un proyecto con uv en tu VPS, consulta Despliega un proyecto Python con uv, Git y Railpack en Dokploy.

Paso 1: Instalar uv

uv no necesita una instalación previa de Python: puede gestionar las versiones de Python por sí mismo. Instálalo directamente (no con pip) para evitar conflictos de dependencias con el Python de tu sistema.

macOS/Linux

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

Esto descarga e instala uv como un binario independiente. Verás una salida como esta:

bash
downloading uv 0.12.5 aarch64-apple-darwin
no checksums to verify
installing to /Users/user/.local/bin
  uv
  uvx
everything's installed!

Windows

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

Verifica la instalación

bash
uv --version

Deberías ver algo como uv 0.12.5. Comprueba también el binario complementario:

bash
uvx --version

Para confirmar que hay versiones de Python gestionadas disponibles:

bash
uv python list

Muestra todas las versiones de CPython que uv puede descargar y gestionar por ti, sin necesidad de un Python del sistema.

¿Problemas con el PATH?

Si el instalador avisa de que $HOME/.local/bin no está en tu PATH, o indica que los comandos están «shadowed by other commands» (eclipsados por otros), reinicia la terminal o ejecuta:

bash
source $HOME/.local/bin/env

Para hacer el cambio permanente, ejecuta uv python update-shell. En Windows, uv tool update-shell hace lo mismo.

Para mantener uv actualizado cuando lo instalaste con el instalador independiente:

bash
uv self update

Si usas un Mac y necesitas instalar o actualizar Python por separado, consulta instala y actualiza Python en tu Mac.

Paso 2: Inicializar un proyecto nuevo con uv init

Desde uv 0.12.0 (julio de 2026), uv init crea una aplicación empaquetada por defecto, con una estructura src/, un sistema de build y un punto de entrada de script. Es un cambio importante respecto a versiones anteriores.

bash
uv init my-python-project
cd my-python-project

La estructura del proyecto generado:

text
my-python-project/
├── .gitignore
├── .python-version
├── pyproject.toml
├── README.md
└── src/
    └── my_python_project/
        └── __init__.py

El pyproject.toml ahora incluye un sistema de build y un punto de entrada de script:

toml
[project]
name = "my-python-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = []

[project.scripts]
my-python-project = "my_python_project:main"

[build-system]
requires = ["uv_build>=0.12.1,<0.13"]
build-backend = "uv_build"

El src/my_python_project/__init__.py contiene una función inicial:

python
def main():
    print("Hello from my-python-project!")


if __name__ == "__main__":
    main()

Ejecútalo usando el punto de entrada del script:

bash
uv run my-python-project

Deberías ver Hello from my-python-project! impreso en la terminal. Ojo: ejecutas el nombre del punto de entrada, no main.py.

Historial de estructuras de uv init

La estructura por defecto ha cambiado varias veces. La v0.3 usaba una estructura empaquetada (hatchling), la v0.4 cambió a un main.py plano, y la v0.12 volvió al formato empaquetado con el backend uv_build de Astral. Por eso, si ves tutoriales antiguos donde uv init crea un main.py en la raíz, ya sabes la razón.

¿Prefieres la antigua estructura plana con main.py?

Si quieres la estructura plana más sencilla, sin paquete:

bash
uv init --no-package my-python-project

Esto crea la estructura antigua:

text
my-python-project/
├── .python-version
├── main.py
├── pyproject.toml
└── README.md

Con esta estructura, ejecutas el código directamente con uv run main.py. No se genera [build-system] ni [project.scripts].

Otras variantes de uv init:

  • uv init --lib my-project: crea una librería (sin punto de entrada, con la estructura src/ adecuada para publicar).
  • uv init --bare my-project: genera solo un pyproject.toml, nada más.

Paso 3: Configurar un entorno virtual

uv crea un entorno virtual automáticamente al añadir dependencias, pero también puedes crearlo de forma explícita:

bash
uv venv

Esto crea un directorio .venv en la raíz del proyecto. Lo importante: no necesitas activarlo. uv run gestiona el entorno virtual en cada comando:

bash
uv run python -c "print('Running inside the venv')"

Si aun así quieres activarlo manualmente (por ejemplo, para un IDE que lo necesite):

bash
# macOS/Linux
source .venv/bin/activate

# Windows
.venv\Scripts\activate

¿Recreando un entorno virtual?

Desde uv 0.10.0, uv venv no sobrescribe un .venv existente sin el flag --clear. Si necesitas empezar de cero:

bash
uv venv --clear

Para directorios que no sean un venv, usa uv venv --force.

Paso 4: Añadir dependencias

La forma más fácil de añadir dependencias es con uv add, que actualiza pyproject.toml y crea/actualiza uv.lock en un solo paso:

bash
uv add requests

Para dependencias solo de desarrollo (tests, linting):

bash
uv add --dev pytest

Esto usa la tabla [dependency-groups] de PEP 735 en pyproject.toml:

toml
[project]
dependencies = [
    "requests",
]

[dependency-groups]
dev = [
    "pytest",
]

También puedes editar pyproject.toml a mano y luego sincronizar:

bash
uv sync

Lee pyproject.toml, resuelve las dependencias e instala todo en .venv. La velocidad es sorprendente: normalmente termina en menos de un segundo.

Para instalaciones solo de producción (omitiendo las dependencias de desarrollo):

bash
uv sync --no-dev

Nota: la sintaxis antigua [tool.uv] dev-dependencies está obsoleta. Usa [dependency-groups] como se muestra arriba.

Paso 5: Escribir y ejecutar código

Con la nueva estructura empaquetada, tu código vive en src/my_python_project/. Edita src/my_python_project/__init__.py:

python
import requests


def main():
    response = requests.get("https://api.github.com")
    print(response.json())


if __name__ == "__main__":
    main()

Ejecútalo a través del punto de entrada:

bash
uv run my-python-project

O ejecuta Python directamente dentro del entorno del proyecto:

bash
uv run python -c "from my_python_project import main; main()"

Para scripts rápidos de un solo uso con dependencias temporales (sin proyecto):

bash
uv run --with rich python -c "from rich import print; print({'hello': 'world'})"

Ejecución avanzada de scripts

¿Quieres ejecutar scripts de Python sueltos sin crear un proyecto completo? Consulta uv run: ejecuta scripts de Python sin gestionar dependencias para ver los metadatos en línea de PEP 723 y técnicas con uv run --with.

Paso 6: Gestionar tu proyecto

Actualiza las dependencias a sus últimas versiones compatibles:

bash
uv sync --upgrade

Exporta a requirements.txt (forma moderna, infiere el formato de la extensión):

bash
uv export -o requirements.txt

También puedes exportar al formato de lockfile estándar PEP 751:

bash
uv export -o pylock.toml

Inspecciona el árbol de dependencias:

bash
uv tree

Ejecuta cualquier comando en el entorno del proyecto:

bash
uv run pytest

Paso 7: Gestionar versiones de Python

uv puede descargar y gestionar versiones de Python sin una instalación del sistema. Lista las versiones disponibles:

bash
uv python list

Instala una versión concreta:

bash
uv python install 3.14

Fíjala para tu proyecto:

bash
uv python pin 3.14

Esto escribe la versión en .python-version.

Actualiza a la última versión de parche:

bash
uv python upgrade

uv python upgrade (estable desde uv 0.10.0) actualiza de forma transparente al último parche. Las actualizaciones de nivel patch ocurren automáticamente; las de nivel minor (por ejemplo, de 3.13 a 3.14) nunca son automáticas: tienes que activarlas tú.

A agosto de 2026, Python 3.14 es la versión estable actual (usa el último parche 3.14.x). Python 3.15 está en release candidate.

Dato aparte: el Python free-threaded (sin GIL) está disponible para 3.13+ con uv python install 3.14t, por si quieres experimentar.

Paso 8: Eliminar paquetes con uv

Elimina un paquete de pyproject.toml, .venv y uv.lock con un solo comando:

bash
uv remove requests

Para una dependencia de desarrollo:

bash
uv remove --dev pytest

Tras la eliminación, tu pyproject.toml queda actualizado y el paquete se desinstala del entorno virtual. uv.lock también se actualiza para mantener la reproducibilidad.

Si editas pyproject.toml a mano para quitar una dependencia, ejecuta uv sync después. De lo contrario, uv no la desinstalará de .venv automáticamente. Mejor usa uv remove para mantener todo limpio.

Compilar, publicar y desplegar

Desde uv 0.12.0, uv init crea un proyecto empaquetado por defecto, así que compilar y publicar es el siguiente paso natural.

Compila tu proyecto:

bash
uv build

Esto genera dist/*.whl (wheel) y dist/*.tar.gz (distribución fuente).

Publica en PyPI:

bash
uv publish

Necesitarás un token de API de PyPI. uv publish también admite índices privados.

Reproducibilidad y CI

Sube siempre uv.lock a git. Fija las versiones exactas de las dependencias en todas las plataformas.

En pipelines de CI, usa --frozen para instalar exactamente lo que indica uv.lock (falla si el lockfile fuera a cambiar):

yaml
# GitHub Actions example
- uses: astral-sh/setup-uv@v9
- run: uv sync --frozen

Otros flags útiles para CI:

  • uv lock --check: verifica que el lockfile está sincronizado con pyproject.toml (basado en código de salida, útil para pre-commit).
  • uv sync --check: verifica que .venv coincide con el lockfile.

Docker

La imagen oficial de Docker es ghcr.io/astral-sh/uv. Un build multi-etapa típico:

dockerfile
FROM ghcr.io/astral-sh/uv:latest AS uv
FROM python:3.14-slim

COPY --from=uv /uv /usr/local/bin/uv
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev
COPY . .
CMD ["uv", "run", "my-python-project"]

Para desplegar en un VPS con Dokploy, consulta Despliega un proyecto Python con uv, Git y Railpack en Dokploy. Si necesitas hosting VPS económico con Hetzner para tus runners de CI o para el despliegue en producción, es lo que yo uso en la mayoría de mis proyectos personales.

Los precios de los VPS subieron en todos los proveedores en 2026: si estás reconsiderando una máquina alquilada, mira qué cambió y cuándo un mini PC sale ganando.

Para una introducción más amplia a Docker y a ejecutar Python en contenedores, consulta ejecuta tu app de Python en Docker.

¿Por qué elegir uv en 2026?

uv ha pasado de ser un instalador de paquetes experimental a una herramienta completa de gestión de proyectos de Python. Con ~88.800 estrellas en GitHub y adopción por parte de grandes proyectos (FastAPI, entre otros), ya es una herramienta de uso generalizado.

La diferencia de velocidad es real: entre 10 y 100 veces más rápido que pip en la instalación y resolución de dependencias. Pero la mayor ventaja es la simplificación del flujo de trabajo. Un único binario sustituye a pip, venv, pipx, poetry y pyenv. El archivo uv.lock te da builds reproducibles sin la fragilidad de los requirements.txt con versiones fijadas.

Para principiantes, uv elimina la fricción de gestionar entornos de Python. Para desarrolladores con experiencia, los flags pensados para CI (--frozen, --locked, --check), las versiones de Python gestionadas y el pipeline integrado de compilación/publicación ahorran tiempo real. Tanto si construyes un pequeño script como si escalas con uno de los mejores frameworks web de Python, uv se ocupa de las herramientas para que tú te centres en el código.

¿Qué sigue?

Ahora que dominas lo básico, aquí tienes más cosas que puedes hacer con uv:

Ver todos los tutoriales de Python

Conclusión

Empezar con uv es sencillo: instala el binario, ejecuta uv init, añade dependencias con uv add y corre todo con uv run. Todo el flujo de trabajo lleva minutos, no la tarde entera que pasarías peleando con pip y venv a mano.

En 2026, uv es la forma más rápida de gestionar proyectos de Python. Se encarga de paquetes, entornos virtuales, versiones de Python, scripts e incluso de la compilación y publicación. Una herramienta, un lockfile, builds reproducibles en cualquier máquina y en CI.

Para mantenerte al día, consulta la documentación oficial en docs.astral.sh/uv o el repositorio de GitHub en github.com/astral-sh/uv.

Instala uv, inicializa un proyecto y comprueba la diferencia por ti mismo.

Solución de problemas y errores comunes

uv: command not found tras la instalación

El instalador añade uv a $HOME/.local/bin, que puede no estar en tu PATH. Solución:

bash
source $HOME/.local/bin/env

Para hacerlo permanente, ejecuta uv python update-shell y reinicia la terminal. En Windows, usa uv tool update-shell.

«The following commands are shadowed by other commands»

Significa que existe otro binario de uv o uvx antes en tu PATH (por ejemplo, de un pip install uv o de Homebrew). Opciones:

  1. Reordena tu PATH para que $HOME/.local/bin vaya primero.
  2. Usa la ruta completa: ~/.local/bin/uv.
  3. Elimina la otra instalación (pip uninstall uv o brew uninstall uv).
«No solution found» al resolver dependencias

Significa que uv no encuentra un conjunto de versiones de paquetes que satisfaga todas tus restricciones. Causas habituales:

  • Versión fijada demasiado estricta: "requests>=2.31.0,<=2.31.5" puede entrar en conflicto con otro paquete.
  • Necesitas una pre-release: añade --pre para permitir versiones preliminares, o especifica "pkg>=Xa0" en tu dependencia.

Desde uv 0.12.0, la política por defecto de pre-releases es if-necessary: uv solo instala versiones preliminares si ninguna versión estable satisface las restricciones.

uv venv no recrea mi entorno virtual

Desde uv 0.10.0, uv venv no sobrescribe un directorio .venv existente. Usa:

bash
uv venv --clear    # removes and recreates .venv
uv venv --force    # for non-venv directories
Errores de TLS/certificados con índices privados

Desde uv 0.11.0, el flag --native-tls está obsoleto. Para índices de paquetes corporativos o autoalojados con certificados propios:

  • Usa --system-certs para confiar en el almacén de certificados del sistema.
  • Define las variables de entorno SSL_CERT_FILE o SSL_CERT_DIR apuntando a tu CA personalizada.
Espacio en disco y gestión de la caché

uv usa una caché global para deduplicar los paquetes descargados. En un VPS con almacenamiento limitado:

bash
uv cache dir    # find the cache location
uv cache clean  # reclaim disk space

La caché se comparte entre todos los proyectos, así que limpiarla afecta a todo.

Preguntas frecuentes

¿Cuánto más rápido es uv que pip?

Entre 10 y 100 veces más rápido, según la carga de trabajo. El resolvedor de dependencias en Rust y la caché agresiva marcan la mayor diferencia en proyectos con muchas dependencias.

¿Puedo usar uv en proyectos existentes?

Sí. Ejecuta uv sync en cualquier proyecto con un pyproject.toml o requirements.txt para instalar las dependencias. uv lee los archivos estándar de proyectos Python: no hace falta migrar nada.

¿uv sustituye a pip, venv y pyenv?

Sí. uv se encarga de la instalación de paquetes, los entornos virtuales, la gestión de versiones de Python, la ejecución de scripts y la compilación/publicación en un solo binario. Puedes desinstalar pip, venv, pipx, poetry y pyenv si usas uv para todo.

¿uv está listo para producción?

Sí. ~88.800 estrellas en GitHub, adoptado por grandes proyectos y muy usado en pipelines de CI/CD. El archivo uv.lock garantiza builds reproducibles en todas las plataformas. Los flags de CI --frozen y --locked están diseñados para pipelines de producción.