Get AI summaries of any video or article — Sign up free
Python Tutorial: UV - A Faster, All-in-One Package Manager to Replace Pip and Venv thumbnail

Python Tutorial: UV - A Faster, All-in-One Package Manager to Replace Pip and Venv

Corey Schafer·
5 min read

Based on Corey Schafer's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.

TL;DR

UV consolidates pip, venv, lockfile creation, and pipx-style tool installation into one workflow with commands like uv add, uv run, and uv tool install.

Briefing

UV is positioned as a single, faster replacement for several core Python workflow tools—installing packages, creating and managing virtual environments, generating lock files, and installing command-line tools—while also making environments reproducible and easier to run without manual activation. Built and maintained by Astral (the same team behind Ruff), UV aims to collapse the usual pip + venv + lockfile + pipx toolchain into one interface, with speed attributed to its Rust implementation.

The tutorial starts with installation options, then moves into a side-by-side comparison of the “old way” workflow versus UV’s streamlined approach. Traditionally, a new project typically means creating a directory, creating a virtual environment with Python 3 venv, activating it, installing packages with pip, and later freezing dependencies into requirements.txt using pip freeze. That process is not only multi-step, it also tends to be error-prone for newcomers because it requires understanding activation, dependency capture, and re-creation on another machine.

With UV, project setup becomes more direct. Instead of manually creating a project folder and virtual environment, UV can initialize a project directory itself (uv init). The default application template generates a ready-to-edit structure including a .gitignore, a Python version file to keep interpreter selection consistent, a starter main.py, and a pyproject.toml for dependency configuration. Crucially, UV defers environment creation: the first time a command needs an environment, UV automatically creates a .venv directory and installs dependencies.

Adding dependencies is done with uv add. Installing Flask and request via uv add flask request updates pyproject.toml automatically and creates a uv.lock file that records exact package versions—including transitive dependencies—so the environment can be reproduced precisely. UV also provides uv tree to visualize dependency relationships, showing which packages depend on which sub-dependencies.

Running code shifts the workflow away from “always-activated” environments. Instead of python main.py, UV uses uv run main.py, which selects the correct environment even when none is active. The tutorial demonstrates resilience: if the .venv directory is deleted, uv run recreates the environment from uv.lock and installs dependencies again before executing the script. For sharing without requiring the recipient to run the app first, uv sync rebuilds the environment to match the lock file. Dependency changes are handled with commands like uv remove flask, which updates both pyproject.toml and uv.lock.

Speed and disk efficiency are presented as major advantages. UV’s global caching system stores shared package versions once across multiple projects, preserving isolation while reducing duplicate downloads and storage. Recreating environments that used to take minutes with pip and venv can become near-instant.

For users hesitant to abandon pip immediately, UV includes a uv pip subcommand that behaves like pip but faster and integrated with project environments. It also supports migrating existing projects by generating UV project structure and installing dependencies from requirements.txt.

Finally, UV extends beyond project dependencies by replacing pipx for Python-based command-line tools. Commands like uv tool install rough install Ruff in an isolated environment while exposing it on the system PATH; uv tool run (and its shortcut uvx) can run tools temporarily without permanent installation. The tutorial closes by emphasizing UV’s “one tool” philosophy: pip, venv, lockfiles, and pipx-style tooling become a cohesive workflow, with additional capabilities for Python version management, package publishing, and optimized Docker builds reserved for later coverage.

Cornell Notes

UV is a unified Python package manager that replaces pip, venv, lockfile generation, and pipx-style tool installation with one workflow. It initializes projects with pyproject.toml and creates a uv.lock file that pins exact dependency versions (including transitive packages) for reproducible environments. UV automatically creates a .venv only when needed, and it can run code without manual activation using uv run. If the virtual environment is deleted, UV recreates it from uv.lock, and uv sync helps teammates rebuild the same environment. UV also supports a uv pip subcommand for gradual migration and includes uv tool / uvx for installing or temporarily running command-line tools like Ruff.

What problem does UV try to solve in the typical Python setup workflow?

UV targets the multi-tool, multi-step workflow that usually combines pip (install packages), venv (create/manage virtual environments), pip freeze (capture dependencies), and pipx (install command-line tools). Instead, UV provides one interface that handles package installation, virtual environment creation, lockfile generation, and tool installation—reducing manual steps and newcomer confusion.

How does UV make environments reproducible across machines?

UV generates a uv.lock file that records exact versions of installed packages, including sub-dependencies. When someone runs uv run or uv sync, UV recreates the environment to match uv.lock, preventing the common “works on one machine, fails on another” problem caused by small version discrepancies.

What changes when running a Python script under UV instead of activating a venv?

With UV, there’s no need to keep a virtual environment activated. The command uv run main.py runs the script using the project’s environment automatically. If the .venv folder is missing, UV detects that and recreates the environment, installs dependencies quickly, and then runs the code.

How does UV handle dependency management after initial setup?

Dependencies are added with uv add (which updates pyproject.toml) and removed with uv remove (which updates both pyproject.toml and uv.lock). For sharing or onboarding, uv sync recreates the environment from uv.lock. UV also offers uv tree to visualize dependency relationships.

How can users transition from pip without fully switching immediately?

UV includes a uv pip subcommand that acts like pip but integrated with UV’s environment detection. This allows commands like uv pip install numpy and uv pip list to work in a familiar way, though it won’t automatically create pyproject.toml/uv.lock updates the way UV-native commands do.

How does UV replace pipx for command-line tools?

UV uses uv tool install to install tools (like Ruff) into an isolated environment while making the executable available on PATH. It can remove them with uv tool uninstall. For temporary use, uv tool run (or uvx) runs the tool in a temporary environment, then cleans up afterward—useful for one-off checks without permanent installation.

Review Questions

  1. When would you use uv run versus uv sync, and what role does uv.lock play in each?
  2. What files does UV generate during project initialization, and how do pyproject.toml and uv.lock relate to dependency management?
  3. How does UV’s uv pip subcommand differ from using UV-native commands like uv add in terms of updating dependency metadata?

Key Points

  1. 1

    UV consolidates pip, venv, lockfile creation, and pipx-style tool installation into one workflow with commands like uv add, uv run, and uv tool install.

  2. 2

    UV generates a uv.lock file that pins exact dependency versions (including transitive dependencies) to make environments reproducible across machines.

  3. 3

    UV creates the .venv automatically when a command needs it, so users don’t have to activate environments manually.

  4. 4

    Running code shifts from python main.py to uv run main.py, and UV can recreate missing environments from uv.lock.

  5. 5

    UV sync rebuilds a project’s environment to match uv.lock, which simplifies onboarding and collaboration.

  6. 6

    UV’s global caching reduces disk usage and speeds up installs by storing shared package versions once across projects.

  7. 7

    UV supports gradual migration via uv pip and can replace pipx with uv tool / uvx for installing or temporarily running tools like Ruff.

Highlights

UV can run code even after deleting the .venv directory: uv run recreates the environment from uv.lock automatically.
The uv.lock file is the reproducibility backbone—exact versions of direct and transitive dependencies are recorded for consistent results.
UV’s global caching stores shared dependencies once across projects, preserving isolation while cutting download time and disk usage.
UV replaces pipx with uv tool install and uv tool run (or uvx), enabling both permanent and temporary tool usage on PATH.

Topics

Mentioned