abxpkg

Modern, strongly-typed Python library and CLI for detecting, installing, and managing system binaries across apt, brew, pip, npm, cargo, and more.

Library
PyPI
v1.12.117
28stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
70/100Good
Development Activity96
Maintenance100
Community16
Maturity48
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
80/100Excellent
Architecture82
Code Quality85
Innovation78
Learning Curve75

abxpkg is a Pydantic-typed Python library and CLI built by ArchiveBox for detecting, installing, and managing binary dependencies across a wide range of system package managers, including apt, brew, pip, uv, npm, pnpm, yarn, bun, deno, cargo, gem, go get, nix, docker, ansible, and pyinfra. Instead of shelling out to curl | sh installers or hardcoding platform-specific package names, applications declare a Binary with an ordered list of BinProviders and let abxpkg resolve, install, version-check, and cache the right binary at runtime.

Originally built by ArchiveBox to auto-install and update its own extractor dependencies (chrome, wget, curl, yt-dlp) across macOS, Linux, and Docker, abxpkg exposes both a Python API (from abxpkg import Binary, env, npm, brew) and a companion abxpkg/abx CLI for scripting, uv-style shebang-line script dependency declarations, and Django admin/OpenAPI integration via django-jsonform and django-ninja.

What You Get

  • Typed Binary and BinProvider Pydantic models for declaring installable dependencies with ordered provider fallback chains
  • Built-in providers for apt, brew, pip, uv, npm, pnpm, yarn, bun, deno, cargo, gem, go get, nix, docker, bash, puppeteer, playwright, chromewebstore, ansible, and pyinfra
  • An abxpkg CLI (install/update/uninstall/load/run/env/activate/search/list) plus an abx npx-style auto-install-and-run shortcut
  • Shebang-line script dependency declarations (abxpkg run --script) inspired by uv’s inline script metadata, usable from any language
  • Safe-by-default installs: minimum release age checks, opt-in post-install scripts, and an isolated library directory instead of touching the host system
  • Django integration via django-jsonform/django-ninja for admin UIs and OpenAPI schemas over declared dependencies

Common Use Cases

  • Auto-installing and version-pinning CLI tool dependencies (yt-dlp, ffmpeg, chromium) at application runtime instead of documenting manual setup steps
  • Serializing a project’s binary dependency graph to a database or config file for auditing and reproducibility
  • Writing cross-platform install logic that picks the right package manager per OS without conditional shell scripting
  • Declaring per-script dependencies in standalone automation scripts via shebang headers, mirroring uv’s script metadata format
  • Building admin dashboards (Django) that show which system binaries are installed, where, and at what version

Under The Hood

Architecture abxpkg is organized around two core Pydantic model families: BinProvider (one per package manager, e.g. AptProvider, BrewProvider, NpmProvider in abxpkg/binprovider_*.py) and Binary/ShallowBinary (abxpkg/binary.py, abxpkg/shallowbinary.py), which declare a name plus an ordered list of BinProviders to try. Resolution flows through binprovider.py’s shared load/install/update/uninstall contract, with each concrete provider overriding only the OS/package-manager-specific pieces (package name mapping, install command construction, version parsing) while inheriting caching, PATH management, and subprocess execution from the base class. The CLI layers (cli.py, click_cli.py) are thin dispatchers over this same model layer, so abxpkg install foo and a Python call to Binary(name='foo').install() share one code path — there is no separate CLI-only logic to drift out of sync with the library.

Tech Stack The library targets Python 3.12-3.14 and is built on Pydantic v2 (pydantic>=2.12.5) for all model validation and JSON (de)serialization, rich-click for the CLI’s help/output formatting, and platformdirs for cross-platform cache/lib directory resolution. Packaging uses hatchling with uv as the dependency manager and task runner (uv sync, uv run); optional extras add rich (pretty CLI output), abxbus (event bus integration), pyinfra, and ansible/ansible-core/ansible-runner as alternate execution drivers. A django_example_project/ demonstrates optional Django 4-6 integration via django-pydantic-field and django-jsonform.

Code Quality The tests/ directory has one dedicated test module per provider (test_aptprovider.py, test_npmprovider.py, test_cargoprovider.py, etc.) plus shared contract tests (test_binprovider.py, test_installer_binary_contracts.py) that parametrize the same assertions across every provider class, and a test_cli.py for the command surface — around 30 test files total, run with pytest (including pytest-codeblocks, which executes the README’s own code samples as tests). Typing is enforced through a layered pre-commit setup: ruff for lint/format, both ty and pyright for static type checking, and codespell/pyupgrade for hygiene, all wired into .pre-commit-config.yaml. Exceptions are typed and hierarchical (ABXPkgError -> BinProviderError -> BinProviderInstallError, etc.) with structured messages rather than bare strings. The project’s own AGENTS.md explicitly forbids mocks/fakes in tests, requiring real subprocesses and real provider calls, which is an unusually strict bar for a dependency-installer library.

What Makes It Unique Most dependency-bootstrapping tools are scoped to one ecosystem (uv for Python, npm for Node); abxpkg’s distinguishing choice is a single typed abstraction spanning nineteen different package managers and drivers (including alternate execution backends like pyinfra and ansible) behind one Binary/BinProvider contract, so a caller can express “try env, then npm, then brew” as ordered data rather than branching shell logic. Its shebang-line script dependency format, modeled directly on uv’s inline script metadata but made comment-syntax-agnostic (works with #, //, --, ; prefixes), extends that idea to arbitrary scripts in any language, not just Python. Supply-chain-safety defaults (minimum release age before install, opt-in-only post-install scripts, isolated install roots) are enabled by default rather than left to the caller to configure, which is a deliberate stance among tools in this space.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search