How to run Python scripts on a Raspberry Pi with uv
Running pip install requests on a fresh Raspberry Pi OS Bookworm install prints error: externally-managed-environment and refuses to install anything into the system Python. uv is the cleanest fix on a Pi: install the prebuilt binary, then run scripts inline with inline metadata or inside a project venv that uv manages for you. This guide covers both paths.
It assumes a Pi running 64-bit Raspberry Pi OS. The 32-bit edition has its own quirks; see How to install uv on 32-bit Raspberry Pi OS. If your project needs picamera2, gpiozero, or another apt-installed library, see How to use picamera2 and GPIO with uv on Raspberry Pi.
Install uv on Raspberry Pi OS
Run the official standalone installer over SSH or from a terminal on the Pi:
curl -LsSf https://astral.sh/uv/install.sh | shThe installer downloads uv-aarch64-unknown-linux-gnu.tar.gz on 64-bit Pi OS and writes the binary to ~/.local/bin/uv. It also appends a line to your shell profile so ~/.local/bin is on PATH. Open a new shell so the change takes effect, then verify:
uv --versionConfirm the binary matches the OS architecture:
uv self version --output-format json | grep -E '"(version|target)"'On 64-bit Pi OS, the target field reports aarch64-unknown-linux-gnu. If the standalone installer can’t run at all, How to install uv on Linux covers fallbacks like wget and Homebrew.
uv is listed as a Tier 2 platform on aarch64 Linux. Astral builds releases for it but does not run the full test suite there, so individual edge cases occasionally lag the x86_64 builds.
Tip
Do not run the installer with sudo. uv installs into your home directory, and running the installer as root makes ~/.local/bin/uv owned by root, which causes permission errors later when uv self update or uv tool install writes to the cache.
Run a one-off script with inline metadata
For a single-file script, the PEP 723 inline metadata format is the most direct path. uv run reads the requirements out of the script itself, creates a temporary environment, and runs the script. There is no pip install, no manual python3 -m venv, and nothing to trigger the externally-managed-environment error.
Save this as pi-info.py:
# /// script
# requires-python = ">=3.11"
# dependencies = ["psutil"]
# ///
import psutil
print(f"CPU cores: {psutil.cpu_count()}")
print(f"Load avg: {psutil.getloadavg()}")
print(f"RAM used: {psutil.virtual_memory().percent}%")Then run it:
uv run pi-info.pyuv downloads a managed CPython if needed, resolves psutil, builds or fetches a wheel, and prints the metrics. The environment lives in uv’s cache (~/.cache/uv) and is reused on later runs. If you change the dependency list at the top of the file, uv re-resolves automatically.
For deeper background, see How to convert a script with requirements.txt to PEP 723 inline metadata.
Create a project for a longer script
When a script grows into multiple files, switch to a project so the dependencies live in pyproject.toml and a virtual environment on disk:
uv init temperature-logger
cd temperature-logger
uv add adafruit-circuitpython-dhtuv init writes a pyproject.toml, picks a Python version (or downloads one with uv python install if none is suitable), and creates .venv/ in the project root. uv add resolves the dependency, writes it to pyproject.toml, and installs it into .venv/. The lockfile (uv.lock) records the exact versions, so cloning the project onto another Pi reproduces the same environment with uv sync.
Run the project’s script with:
uv run python main.pyuv keeps .venv/ in sync with pyproject.toml and uv.lock automatically before each uv run.
Frequently asked questions
Does uv work on a Raspberry Pi Zero?
uv’s standalone installer ships armv6l-compatible armv7l binaries that run on the original Pi Zero and Zero W. Performance on a single 700MHz core is far below the Pi 4 baseline most uv benchmarks reference, but resolution and install still work. The Pi Zero 2 W is aarch64-capable; flash 64-bit Pi OS on it to get the full aarch64 wheel ecosystem.
Should I install uv on Pi OS through apt?
There is no official Debian package for uv in Raspberry Pi OS Bookworm or Trixie. The standalone installer is the supported install path. Snap publishes an astral-uv snap that works on Pi OS, but it bundles snapd on a system that ships without it; the standalone installer is lighter.
Why is uv add slow on the first run?
Wheel availability on aarch64 is good but not universal. Packages without a manylinux_*_aarch64 wheel build from source on the Pi, which is slow on a Pi Zero and noticeable on a Pi 4. Check what’s happening with uv add --verbose if a command stalls; an “Building wheel for X” line means uv didn’t find a precompiled wheel and is compiling on the Pi.
Learn More
- How to install uv on Linux covers shell completions and PATH troubleshooting that apply on Pi OS too.
- How to fix the externally-managed-environment error explains the marker that Raspberry Pi OS Bookworm ships with.
- How to use picamera2 and GPIO with uv on Raspberry Pi covers projects that need apt-installed system bindings.
- How to install uv on 32-bit Raspberry Pi OS covers armv7l-specific install quirks and piwheels.
- How to install Python with uv walks through
uv python installon every platform. - uv platform support policy lists every architecture uv targets and the support tier for each.