---
title: "Primeros pasos con uv: configuración de proyectos Python en 2026"
description: "¿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."
date: 2025-03-12
categories: ["tools"]
tags: ["uv","python","package-manager"]
---

import Button from "@components/widgets/Button.astro";
import Notice from "@components/widgets/Notice.astro";
import Accordion from "@components/widgets/Accordion.astro";

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](@images/25/03/uv-speed.svg)

<Notice type="info" title="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.
</Notice>

## Configura tu proyecto de Python con uv

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

<YouTubeEmbed
  url="https://www.youtube.com/embed/XkjzP0_fHnU"
  label="Primeros pasos con uv: recorrido de configuración de un proyecto Python"
/>

<Notice type="info" title="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](https://www.bitdoze.com/es/dokploy-python-railpack-uv/).
</Notice>

### 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:

```sh
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.

<Notice type="warning" title="¿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.
</Notice>

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](https://www.bitdoze.com/install-upgrade-python-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:

```
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`.

<Notice type="info" title="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.
</Notice>

<Accordion label="¿Prefieres la antigua estructura plana con main.py?" group="init-styles">
Si quieres la estructura plana más sencilla, sin paquete:

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

Esto crea la estructura antigua:

```
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.
</Accordion>

### 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
```

<Notice type="warning" title="¿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`.
</Notice>

### 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'})"
```

<Notice type="info" title="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](https://www.bitdoze.com/es/guia-uv-run-scripts/) para ver los metadatos en línea de PEP 723 y técnicas con `uv run --with`.
</Notice>

### 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](https://www.bitdoze.com/es/dokploy-python-railpack-uv/). Si necesitas [hosting VPS económico con Hetzner](https://go.bitdoze.com/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](/es/subidas-precios-vps/)._

Para una introducción más amplia a Docker y a ejecutar Python en contenedores, consulta [ejecuta tu app de Python en Docker](https://www.bitdoze.com/docker-run-python/).

## ¿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](https://www.bitdoze.com/best-python-web-frameworks/), `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:

- **Ejecución de scripts**: ejecuta scripts de Python sueltos sin crear proyectos completos — [uv run: ejecuta scripts de Python sin gestionar dependencias](https://www.bitdoze.com/es/guia-uv-run-scripts/)
- **Texto a voz**: crea un script de generación de audio — [Texto a voz en Python con uv: crea audio a partir de texto](https://www.bitdoze.com/es/script-uv-texto-a-voz/)
- **Comprobador de URLs**: [Comprobador masivo de URLs con uv: encuentra enlaces rotos en Python](https://www.bitdoze.com/es/script-uv-comprobador-url/)
- **Despliegue**: [Despliega un proyecto Python con uv, Git y Railpack en Dokploy](https://www.bitdoze.com/es/dokploy-python-railpack-uv/)
- **Agentes de IA**: [Primeros pasos con los agentes de Agno: uv, RAG y memoria](https://www.bitdoze.com/es/empezar-agno/)
- **Equipo de investigación con IA**: [Crea tu equipo de investigación de IA con Agno, Streamlit y uv](https://www.bitdoze.com/es/agno-squad/)
- **Interfaz web**: [Crea una interfaz para tu app de Python con FastHTML](/es/empezar-fasthtml/)
- **Docker**: [Ejecuta tu app de Python en Docker](https://www.bitdoze.com/docker-run-python/)

<Button text="Ver todos los tutoriales de Python" link="/tags/python" variant="outline" color="blue" size="md" icon="arrow-right" />

## 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](https://docs.astral.sh/uv) o el repositorio de GitHub en [github.com/astral-sh/uv](https://github.com/astral-sh/uv).

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

## Solución de problemas y errores comunes

<Accordion label="uv: command not found tras la instalación" group="faq">
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`.
</Accordion>

<Accordion label="«The following commands are shadowed by other commands»" group="faq">
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`).
</Accordion>

<Accordion label="«No solution found» al resolver dependencias" group="faq">
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.
</Accordion>

<Accordion label="uv venv no recrea mi entorno virtual" group="faq">
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
```
</Accordion>

<Accordion label="Errores de TLS/certificados con índices privados" group="faq">
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.
</Accordion>

<Accordion label="Espacio en disco y gestión de la caché" group="faq">
`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.
</Accordion>

## Preguntas frecuentes

<Accordion label="¿Cuánto más rápido es uv que pip?" group="faq">
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.
</Accordion>

<Accordion label="¿Puedo usar uv en proyectos existentes?" group="faq">
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.
</Accordion>

<Accordion label="¿uv sustituye a pip, venv y pyenv?" group="faq">
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.
</Accordion>

<Accordion label="¿uv está listo para producción?" group="faq">
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.
</Accordion>