Per anni, lavorare con Python ha significato tenere in equilibrio un numero imbarazzante di strumenti. pip per installare i pacchetti, virtualenv o venv per isolare gli ambienti, pyenv per gestire le versioni dell’interprete, pip-tools per generare lockfile riproducibili, pipx per installare utility globali, poetry o pdm per la gestione avanzata dei progetti.
Ogni strumento risolve un problema specifico, ma l’insieme forma un ecosistema frammentato, lento e spesso incoerente. Poi, nel 2024, Astral, la stessa azienda che ha rilasciato Ruff (il linter Python scritto in Rust che ha spazzato via flake8, isort e black in termini di velocità), ha presentato uv. Un singolo binario da 2MB, scritto in Rust, che sostituisce tutti gli strumenti citati sopra.
Nessuna dipendenza da Python per funzionare, nessun bootstrap runtime, nessun ambiente virtuale da attivare manualmente prima di ogni operazione. A distanza di oltre un anno dal rilascio, con la versione 0.11.8 pubblicata nell’aprile 2026, uv non è più uno strumento da tenere d’occhio: è diventato lo standard de facto per chi sviluppa in Python seriamente.
Se sei ancora su pip + venv, questa guida ti mostra cosa ti stai perdendo e come passare senza traumi.
Rust sotto il cofano: 10-100x più veloce
La velocità di uv non è un’esagerazione promozionale. Il motivo strutturale sta nell’architettura: il resolver delle dipendenze è implementato in Rust usando l’algoritmo PubGrub, lo stesso che gestisce la risoluzione dei pacchetti in Dart. Il risultato è una risoluzione parallela e deterministica che consuma una quantità di RAM irrisoria rispetto a Poetry, circa 85MB contro 850MB in scenari complessi con molte dipendenze transitive.
Altro fattore è la cache globale. Quando installi numpy in un progetto, uv scarica e compila il wheel una volta sola, poi lo hard-linka (o usa Copy-on-Write su filesystem che lo supportano) in tutti i progetti successivi che richiedono la stessa versione. Un’installazione successiva di quel pacchetto con cache pronta avviene in decine di millisecondi, non secondi. In ambienti CI con caching correttamente configurato, questo trasforma pipeline che impiegavano 5 minuti in operazioni da sotto 30 secondi.

Il terzo elemento è l’assenza di overhead interpretativo. pip è scritto in Python e per eseguirsi ha bisogno di Python, che deve essere già avviato e caricare i propri moduli. uv è un binario nativo che parte e termina in microsecondi.
Su benchmark reali con 11 pacchetti comuni tra cui FastAPI, NumPy, Pandas, HTTPX, con cache già popolata (warn cache) pip impiega circa 11 secondi, mentre uv sempre con warm cache si ferma a 0,15 secondi.
Un binario per governare tutto: dalla versione Python agli script
La caratteristica più sottovalutata di uv non è la velocità: è la centralizzazione. Puoi eliminare pyenv dal tuo sistema perché uv gestisce direttamente il download e la selezione delle versioni CPython e anche PyPy.
# Installa Python 3.12, 3.13 e 3.14 in un colpo solo
uv python install 3.12 3.13 3.14
# Imposta la versione di default per la directory corrente
uv python pin 3.13
# Aggiorna all'ultimo patch release
uv python upgrade 3.13Inizializzare un nuovo progetto è un’operazione da tre righe, dopo le quali hai già pyproject.toml, uv.lock e .venv popolato:
uv init my-project
cd my-project
uv add fastapi uvicorn ruffPer gli script one-off, uv introduce qualcosa di decisamente comodo: le dipendenze script inline (o inline script dependencies). Puoi specificare le dipendenze direttamente nell’header dello script, e uv run le installa in un ambiente effimero isolato prima di eseguire il file:
# /// script
# dependencies = ["requests", "rich"]
# ///
import requests
from rich import print
print(requests.get("https://httpbin.org/json").json())uv run script.py # installa le dipendenze al volo, non tocca il tuo sistemaQuesto pattern è particolarmente utile per script di automazione condivisi in team, dove non vuoi richiedere un ambiente preconfigurato su ogni macchina.
uv in CI/CD e nei Dockerfile: il guadagno è ancora superiore
uv porta un vantaggio misurabile anche nelle pipeline CI e nelle build Docker.
In GitHub Actions, il passaggio da actions/setup-python + pip install ad astral-sh/setup-uv è immediato. Il flag --frozen garantisce che il lockfile venga rispettato alla lettera, senza aggiornamenti silenziosi e con build perfettamente riproducibili:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
python-version: "3.13"
enable-cache: true
- run: uv sync --frozen --dev
- run: uv run pytest tests/Nei Dockerfile, il pattern consigliato separa l’installazione delle dipendenze dalla copia del codice sorgente, sfruttando il layer caching di Docker. Se pyproject.toml e uv.lock non cambiano, lo strato delle dipendenze viene riusato integralmente:
FROM python:3.13-slim
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev --no-editable
COPY . .
CMD ["uv", "run", "python", "app.py"]Il risultato è un’immagine costruita più velocemente, con layer cache efficienti e senza dover installare pip manualmente. In ambienti con build frequenti, la differenza nei tempi di CI è immediatamente percepibile.
Workspace, uv format e uvx
Con uv 0.10.0, rilasciato all’inizio del 2026, sono diventate stabili tre funzionalità che completano il quadro per i progetti complessi.
I workspace seguono il modello Cargo di Rust: un repository mono-repo con più pacchetti Python coordinati da un unico lockfile condiviso. Se sviluppi un’applicazione con un backend FastAPI, una libreria condivisa e un client CLI come sotto-pacchetti separati, un workspace uv li gestisce con un singolo uv sync dalla root. È esattamente il tipo di organizzazione che i progetti grandi aspettavano nell’ecosistema Python.
uv format porta Ruff 0.15 direttamente nell’ecosistema di uv, con il nuovo style guide 2026 che risolve alcune lamentele storiche su Black. Le lambda ora rimangono su una riga, la spaziatura attorno ai magic literal è più coerente. In pratica puoi usare uv format come sostituto completo di Black, isort e parte di Flake8, senza installare nulla di aggiuntivo.
uvx è l’alias di uv tool run e rimpiazza pipx per l’esecuzione di tool CLI in ambienti effimeri:
uvx ruff check . # esegui ruff senza installarlo globalmente
uvx black --check src/ # prova black su un progetto legacy
uvx cookiecutter gh:tiangolo/full-stack-fastapi-templateLa differenza rispetto a pipx è che uvx condivide la stessa cache globale di tutto uv. Se ruff è già in cache da un progetto precedente, l’esecuzione è istantanea.
Un valido tool per l’ecosistema Python
Il vero successo di uv si misura nell’adozione. In poco tempo è diventato lo strumento consigliato in molti template di progetto open source, nella documentazione di FastAPI, e nella configurazione standard di chi mantiene librerie distribuite su PyPI. Il motivo è semplice: semplifica la gestione dell’ambiente Python per i nuovi contributor, basta clonare il repository ed eseguire uv sync.
Il passaggio dalla configurazione attuale non richiede una riscrittura. Se usi requirements.txt, il comando uv pip install -r requirements.txt funziona senza modifiche. Se usi Poetry, uv legge pyproject.toml direttamente. Puoi adottarlo in modo incrementale: inizia sostituendo solo pip nei tuoi progetti esistenti, e nel tempo aggiungi la gestione delle versioni Python e il lockfile.
L’unica obiezione legittima riguarda i progetti che dipendono da comportamenti molto specifici di Poetry o da plugin dell’ecosistema pdm. In quei casi, la migrazione richiede un’analisi più attenta. Per tutto il resto, non esiste più un motivo logico per usare la vecchia catena di strumenti. uv fa di più, più veloce, con meno configurazione.
Nell’ecosistema Python, dove la frammentazione del tooling è stata una delle critiche ricorrenti da parte di chi arriva da altri linguaggi, questo è un grande risultato.













