Skip to main content

uv-launch

Install Python commands that start immediately and update in the background. The foreground shell shim executes an already installed environment. It does not invoke uv or wait for network access.

Requires macOS or Linux, Python 3.11+, and uv. Use uvx uv-launch from PyPI to install commands without maintaining a bootstrap environment. A stable uv tool install uv-launch also works. Each managed application includes its own updater, so later launches do not depend on the bootstrap interpreter. Then install commands:

uv-launch install ruff ruff
uv-launch install my-command 'package-name @ git+https://github.com/owner/project.git@main' \
  --entrypoint actual-console-script --with another-package --python 3.13
my-command --help
uv-launch update my-command
uv-launch status my-command

--bin-dir defaults to ~/.local/bin. Use a separate directory for evaluation. The installer refuses to overwrite commands it does not own. UV_LAUNCH_HOME selects the installation-state directory; its default is ~/.local/share/uv-launch.

Each invocation captures the current immutable generation and starts a detached update check. Concurrent checks for the same tool coalesce under a process lock. A check resolves all requested packages together, pinning Git dependencies to concrete revisions. If the resolved installation is unchanged, it keeps the existing environment. Otherwise it creates a new environment at its final path, checks dependencies and loads the Python entrypoint (or verifies ownership of a wheel-provided executable), then atomically switches the generation used by future launches. Virtual environments are never moved after creation, because their scripts contain absolute paths.

The launched command retains its arguments, working directory, environment and exit status. Updates never mutate its environment. An offline or failed update leaves the installed version usable. status reports the current generation and the last completed update result; background diagnostics are in <UV_LAUNCH_HOME>/<command>/update.log. Checks use the existing uv/Git authentication configuration and do not change it.

An initial installation requires dependency access. Automatic updates have a 600-second timeout per subprocess by default; configure it with install --timeout. Validation checks installation and entrypoint integrity, not application-specific behavior. Keep old generations while processes may still use them; this release deliberately does not automatically delete them. The updater is resolved with the application and runs from the captured generation. A successful update can therefore deliver a newer updater as well as newer application code. Existing installations created before 0.2.1 need one reinstall to adopt this behavior.

Source toolfuncs

Install a standalone toolfunc together with its adjacent repository files:

uvx uv-launch install-source wiki https://github.com/owner/wiki scripts/wiki --prepare prepare-runtime

SOURCE must be a repository-relative PEP 723 toolfunc whose filename matches the command. --revision defaults to main; --with, --python, --bin-dir and --timeout work as for package installations. Put --prepare last: its remaining arguments invoke a candidate's toolfunc to prepare and validate application-specific integrations before activation.

Each check fetches one exact Git revision and resolves the script's declared dependencies together with toolfuncs and uv-launch. It validates the prepared tool and optional preparation command, then selects the complete generation atomically. Source-only changes reuse the same immutable dependency environment. Running commands keep their captured source and interpreter; failed builds and offline checks keep the last successful installation.

The foreground calls toolfuncs run-prepared, which loads the selected source in its already prepared environment. It does not resolve or install another environment. managed_target resolves a source installation to its executable source for static discovery. The source repository is delivery state; applications should keep mutable user work elsewhere.

Service startup and companion commands

A service can require the latest successfully resolved dependencies at startup:

uv-launch run --refresh my-command -- serve --port 8080

Unlike the ordinary background-updating shim, run --refresh waits for a successful update and fails without executing stale code when that update fails. It then replaces itself with the selected command. Arguments, environment, working directory and exit status are preserved. SIGTERM during refresh terminates and reaps the resolver/build process group; after execution the application receives signals directly. Old generations remain available for workers that outlive their launcher.

Run a companion executable from the same installation with uv-launch run --command python my-command -- -c 'print("probe")'. Options to run precede the installation name. For several operations that must use exactly the same generation, capture once and pass the returned opaque generation value:

uv-launch select --refresh my-command
uv-launch run --generation GENERATION --command python my-command -- -c 'print("probe")'
uv-launch run --generation GENERATION my-command -- serve

The Python equivalents are select_installation(name, refresh_dependencies=True) and execute_installation(installation, arguments, command=None) from uv_launch. execute_installation uses exec, so successful execution does not return. Consumers should use these interfaces instead of reading installation symlinks or reconstructing generation paths.

Script runtimes and Python imports

uv_launch.dependencies provides shared preparation for tools such as toolfuncs:

  • prepare_environment(requirements, python=..., background=True) returns a ready immutable virtual environment. Warm calls reuse a generation without foreground resolution; first use and changed requirements wait for preparation. It does not snapshot the caller's script.
  • resolve_dependencies(requirements, python=..., constraints=(), background=True) returns an immutable pinned requirements file. Resolutions are cached by requirements, interpreter/platform and constraints.
  • install_dependencies(requirements) adds missing packages to the current interpreter's environment. It reuses satisfying installed dependencies, constrains resolution to preserve existing distributions, checks the selected graph before installation, and raises DependencyConflictError if preservation is impossible. It never synchronizes the whole environment or replaces existing distributions. Background resolution refresh does not install into the active interpreter or reload modules.
  • managed_target(path) statically resolves a generated uv-launch command to its installed executable. It validates the shim against its recorded installation without executing shell code, importing the application, or requesting an update. This lets discovery tools inspect package metadata behind managed commands.

The shared resolver accepts floating Git branches and records exact commit IDs in each cached resolution. No separate script registration or checked-in lockfile is required. A process already using an installed package retains that package; a new cached resolution is not a hot reload. Use a compatible environment when requirements conflict. Each installed source distribution is identified by its recorded origin or package version via distribution_requirement(distribution).

Codex-router example

All five packages are resolved in one operation, so a moving Git ref produces one consistent suite revision:

uv-launch install codexr \
  'codex-router @ git+https://github.com/nimashoghi/codex-router.git@main#subdirectory=packages/codex-router' \
  --with 'codex-router-sdk @ git+https://github.com/nimashoghi/codex-router.git@main#subdirectory=packages/codex-router-sdk' \
  --with 'codex-monitor @ git+https://github.com/nimashoghi/codex-router.git@main#subdirectory=packages/codex-monitor' \
  --with 'codex-recovery @ git+https://github.com/nimashoghi/codex-router.git@main#subdirectory=packages/codex-recovery' \
  --with 'codex-accounts @ git+https://github.com/nimashoghi/codex-router.git@main#subdirectory=packages/codex-accounts' \
  --bin-dir ~/.local/share/codexr-evaluation/bin

Use that isolated command before choosing to replace an existing launcher. Updating the local codexr suite and preparing that exact suite on an SSH host remain separate responsibilities; uv-launch contains no Codex or SSH runtime logic.

Development

uv sync
uv run pytest -q
uv run ruff check .
uv run ruff format --check .

Integration tests create local Git packages and exercise installation, immutable revisions, background publication, failed updates, concurrent checks, offline launches, and preservation of unrelated commands.

Metadata

Release files for uv-launch 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for uv-launch 0.2.1
File Size Uploaded
uv_launch-0.2.1.tar.gz 14.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for uv-launch 0.2.1
File Interpreter ABI Platform
uv_launch-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 32.8 kB

Release files / uv_launch-0.2.1.tar.gz

Download URL uv_launch-0.2.1.tar.gz
Size 14.9 kB
Tags Source
SHA-256 checksum
How to use checksums
232259c49f3fa36fe65aaabe1898e71aaecda6bf849aa4878ceb256f0a6a7252
BLAKE2b-256 checksum
How to use checksums
1f692dece5c99d309aaa4263bd8b0d01f29c6069ecec52bc44a267d2ad3e4f23
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / uv_launch-0.2.1-py3-none-any.whl

Download URL uv_launch-0.2.1-py3-none-any.whl
Size 17.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cbc18ef98d347ee33aef283228ecafd43e6e2875694bd62ab67b5784b08f09e6
BLAKE2b-256 checksum
How to use checksums
f5c1fd02bf68cbf9064b837c5d488e7c109bcacb174841634ce5e3b59138cc73
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.3

2 release files

0.2.2

2 release files

This release

0.2.1 This release

2 release files

0.2.0

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page