uv
Recipe card from the charly-coder plugin (Images — the deployable catalog).
uv – Python package / project manager (astral-sh/uv)
Section titled “uv – Python package / project manager (astral-sh/uv)”Candy Properties
Section titled “Candy Properties”| Property | Value |
|---|---|
| Kind | Direct-download binary candy |
| Install files | charly.yml (no pixi.toml, no dependencies) |
| Depends | (none) — uv is a self-contained Rust binary |
| Binaries | /usr/local/bin/uv, /usr/local/bin/uvx |
Why direct download (not pixi)
Section titled “Why direct download (not pixi)”uv is a completely self-contained Rust binary needing no Python runtime, so
installing it via pixi (pixi.toml with uv = "*" + require: python,
landing it in $HOME/.pixi/envs/default/bin/ inside a conda-forge Python
environment) would be the wrong fit. Pixi would bring three problems uv
doesn’t warrant:
- Image bloat — the pixi env drags in ~500 MB of Python stdlib + numpy transitively, nothing of which uv actually uses.
- HOME-dependency — the binary path would vary per-image’s
$HOME, and HOME-relative PATH entries in child images go subtly wrong when thecharlyauto-intermediate machinery bakes uid=1000 paths into boxes deployed at uid=0 (handled insdk/deploykit/intermediates.go— see/charly-internals:generate-source“UID-keyed sibling grouping”). - Confusion — “uv is installed but
which uvsays not found” for anyone who isn’t in a pixi shell.
So uv installs the way /charly-coder:typst and /charly-languages:pixi itself do
— fetch the upstream binary, unpack to /usr/local/bin, done. System-wide
reachable, always on PATH, no HOME gymnastics.
Install plan
Section titled “Install plan”# a plan step in the uv candy's plan: listplan: - run: download and unpack the uv binary to /usr/local/bin download: "https://github.com/astral-sh/uv/releases/latest/download/uv-${BUILD_ARCH}-unknown-linux-gnu.tar.gz" extract: tar.gz strip_components: 1 to: /usr/local/bin run_as: root${BUILD_ARCH} expands to x86_64 / aarch64 at build time. Upstream
ships per-arch tarballs under stable latest-download URLs, nested one
level deep (uv-x86_64-unknown-linux-gnu/uv, …/uvx). The
strip_components: 1 modifier (see /charly-image:layer “Download verb”)
collapses that wrapper so both binaries land directly at
/usr/local/bin/uv and /usr/local/bin/uvx.
Three build-scope tests ship with the candy:
| Test | Purpose |
|---|---|
uv-binary |
/usr/local/bin/uv exists |
uv-version |
uv --version exits 0 |
uvx-binary |
/usr/local/bin/uvx exists (the per-run tool runner) |
Used In Boxes
Section titled “Used In Boxes”/charly-coder:fedora-coder— the canonical kitchen-sink dev box.- Any box composing
hermes-fullor directly includinguv.
Related Candies
Section titled “Related Candies”/charly-languages:pixi— direct-download pattern this candy now mirrors. Pixi remains a legitimate multi-binary Python env manager for boxes that genuinely need one (jupyter, whisper, openwebui); uv is too small to justify the overhead./charly-coder:typst— sibling direct-download binary pattern./charly-languages:python— the pixi-python meta-layer this candy does not depend on./charly-coder:rust— system Rust toolchain, if you want to build uv from source instead (cargo install uv). Usually not worth it — the Astral binary is pre-optimized.
Related Commands
Section titled “Related Commands”/charly-image:layer— authoring reference (coversdownload:verb +strip_components:modifier)/charly-core:shell— runuvinside a container
When to Use This Skill
Section titled “When to Use This Skill”MUST be invoked when:
- Adding
uvto a box’s candy list. - Authoring a sibling candy for a small Rust/Go CLI tool — this is the canonical pattern (direct download > pixi > anything else).
- Debugging why
uv --versionfails: it’s a$PATHor binary-landing- at-wrong-path issue, not a Python env problem. - Understanding why “uv has no dependencies” is correct even though it manages Python packages.
Related
Section titled “Related”/charly-check:check— declarative testing (check:block,charly check box,charly check live)