pkgx is a 4MB, standalone binary that can run anything.
brew install pkgxdev/made/pkgx || sh <(curl https://pkgx.sh)
$ deno
command not found: deno
$ pkgx deno
Deno 2.1.4
> ^D
$ deno
command not found: deno
# ^^ nothing was installed; your system remains pristine$ pkgx node@14 --version
Node.js v14.21.3
$ pkgx python@2 --version
Python 2.7.18-
macOS
- macOS >= 11
- x86-64 & Apple Silicon
-
Windows
WSL2; x86-64. Native windows is planned.
-
Docker
$ pkgx docker run -it pkgxdev/pkgx (docker) $ pkgx node@16 Welcome to Node.js v16.20.1. Type ".help" for more information. >
Or in a
Dockerfile:FROM pkgxdev/pkgx RUN pkgx [email protected] task start
Or in any image:
FROM ubuntu RUN curl https://pkgx.sh | sh RUN pkgx [email protected] -m http.server 8000
-
CI/CD
- uses: pkgxdev/setup@v2 - run: pkgx shellcheck
Or in other CI/CD providers:
$ curl https://pkgx.sh | sh $ pkgx shellcheck -
Scripts
#!/usr/bin/env -S pkgx +git [email protected] # python 3.12 runs the script and `git` is available during its execution
-
Editors
$ cd myproj myproj $ env +cargo (+cargo) myproj $ code .
Or use
dev; a separate tool that uses the pkgx primitives to automatically determine and utilize your dependencies based on your project’s keyfiles.$ cd myproj myproj $ dev env +cargo +rust (+cargo+rust) my-rust-project $ code .
dev uses pkgx and shellcode to create “virtual environments” consisting
of the specific versions of tools and their dependencies you need for your
projects.
$ cd my-rust-proj && ls
Cargo.toml src/
my-rust-proj $ cargo build
command not found: cargo
my-rust-proj $ dev
+rust +cargo
my-rust-proj $ cargo build
Compiling my-rust-proj v0.1.0
#…pkgm installs pkgx packages to /usr/local. It installs alongside pkgx.
A powerful use of pkgx is scripting, eg. here’s a script to release new
versions to GitHub:
#!/usr/bin/env -S pkgx +gum +gh +npx +git bash>=4 -eo pipefail
gum format "# determining new version"
versions="$(git tag | grep '^v[0-9]\+\.[0-9]\+\.[0-9]\+')"
v_latest="$(npx -- semver --include-prerelease $versions | tail -n1)"
v_new=$(npx -- semver bump $v_latest --increment $1)
gum format "# releasing v$v_new"
gh release create \
$v_new \
--title "$v_new Released 🎉" \
--generate-notes \
--notes-start-tag=v$v_latestAbove you can see how we “loaded” the shebang with +pkg syntax to bring in
all the tools we needed.
We have pretty advanced versions of the above script, eg teaBASE
There’s tools for just about every language ecosystem so you can import
dependencies. For example, here we use uv to run a python script with
pypi dependencies, and pkgx to load both uv and a specific python version:
#!/usr/bin/env -S pkgx [email protected] uv run --script
# /// script
# dependencies = [
# "requests<3",
# "rich",
# ]
# ///
import requests
from rich.pretty import pprint
resp = requests.get("https://peps.python.org/api/peps.json")
data = resp.json()
pprint([(k, v["title"]) for k, v in data.items()][:10])pkgx scripting is so awesome we made a package manager for scripts:
mash.
It can be fun to add magic to your shell:
# add to ~/.zshrc
command_not_found_handler() {
pkgx -- "$@"
}Thus if you type gh and it’s not installed pkgx will magically run it as
though it was installed all along.
Note
Bash is the same function but drop the r from the end of the name.
docs.pkgx.sh is a comprehensive manual and user guide for the pkgx
suite.
- To add packages see the pantry README
- To hack on
pkgxitself; clone it andcargo buildhydrate.rsis where optimization efforts will bear most fruit
If you have questions or feedback:
- github.com/orgs/pkgxdev/discussions
- x.com/pkgxdev (DMs are open)
