Skip to content

Backends

Three ecosystems, three backends — auto-detected from the package name.

ixt supports three backends, each targeting a different tool ecosystem. Backend selection happens automatically unless you override it with a @pypi: / @npm: / @gh: / @gl: prefix.

Format Backend Example
name PyPI ruff, mypy, httpie
@scope/name npm @google/gemini-cli
owner/repo GitHub Releases BurntSushi/ripgrep
gitlab.com/owner/repo GitLab Releases gitlab.com/gitlab-org/cli

Python (PyPI)

Trigger: simple package name — ruff, mypy, httpie

ixt creates and manages one isolated venv per tool under $IXT_HOME/installed/envs/<installed-id>/.venv/, using uv venv + uv pip install under the hood (not uv tool install — ixt owns the venv lifecycle).

ixt tool install ruff
ixt tool install ruff==0.5.0            # pinned version
ixt tool install ruff>=0.5.0            # minimum version

Install additional packages into a tool's environment:

ixt tool config jc inject art           # inject art into jc's env
ixt tool config jc uninject art         # remove the injected package

Runtime

Uses uv as low-level tooling (venv creation + pip operations). Since you installed ixt with uv tool install, uv is already on your PATH; if not, ixt auto-downloads it to $IXT_HOME/installed/runtimes/uv on first use.


Node (npm)

Trigger: scoped package name — @scope/name (e.g., @biomejs/biome, @anthropic-ai/claude-code)

Uses bun for fast, isolated installation. Each tool gets its own node_modules in $IXT_HOME/installed/envs/<installed-id>/.

ixt tool install @biomejs/biome
ixt tool install @anthropic-ai/claude-code
ixt tool install @npm:prettier
ixt tool install @npm:eslint

Runtime

Uses bun, bootstrapped automatically on first Node tool install. Falls back to system npm if bun is unavailable.

Exposed binaries

ixt reads node_modules/.bin/ to discover available binaries and applies the configured exposure rules.


Binary (GitHub / GitLab Releases)

Trigger: owner/repo (GitHub default) or host/owner/repo (explicit host, GitHub or GitLab) — BurntSushi/ripgrep, gitlab.com/gitlab-org/cli

Downloads pre-built binaries from GitHub or GitLab Releases. GitLab self-hosted instances (gitlab.company.com/…) are supported transparently — any host containing gitlab routes through the GitLab API v4. No runtime needed — uses Python stdlib (urllib, tarfile, zipfile).

ixt tool install BurntSushi/ripgrep
ixt tool install sharkdp/fd@10.2.0      # pinned version
ixt tool install sharkdp/fd@10          # latest 10.x.x (semver partial)
ixt tool install gitlab.com/gitlab-org/cli
ixt tool install @gl:gitlab-org/cli     # shorthand for gitlab.com/...
ixt tool install gitlab.company.com/team/tool   # self-hosted

Day-one installs

A tool ships its first GitHub release today — ixt tool install org/new-tool works immediately, no formula, registry entry, or plugin required.

This works because most tools follow one of two release conventions that ixt covers natively:

Convention Example asset Ecosystem
cargo-dist ripgrep-14.1.0-x86_64-unknown-linux-musl.tar.gz Rust
goreleaser lazygit_0.44.1_Linux_x86_64.tar.gz Go

And a dozen more variations. Compare: Homebrew needs a formula PR, Aqua needs a registry entry, mise needs a plugin. ixt needs nothing.

How the scoring works

ixt scores assets against your platform in three passes:

  1. Pattern match — tries cargo-dist, goreleaser, and other known templates in order; first match wins
  2. Prefer / avoid — boosts musl, static; penalizes debug, android, freebsd, non-target platforms
  3. Archive priority — prefers .tar.gz over .zip; hard-skips checksums (.sha256, .sig) and OS packages (.deb, .rpm)

In 95% of cases the right asset is picked with zero configuration.

Bare binaries and clean command names

Some releases publish the executable itself instead of an archive. In that case, ixt derives the installed filename from the selected asset, then strips trailing version, OS, architecture, and configured build-flavour tokens from heuristics.toml.

Examples:

Release asset Exposed command
shfmt_v3.13.1_linux_amd64 shfmt
envx-linux-amd64-static envx
tool-x86_64-unknown-linux-musl tool

Only separator-delimited suffix tokens are stripped. A name such as static-envx is left alone.

Partial semver

The @version suffix accepts partial semver — ixt resolves it to the highest matching tag:

ixt tool install sharkdp/fd@10          # latest 10.x.x (e.g. resolves to 10.2.0)
ixt tool install sharkdp/fd@10.2        # latest 10.2.x
ixt tool install sharkdp/fd@10.2.0      # exact tag

v prefixes in tags are stripped automatically — v10.2.0 and 10.2.0 are equivalent.

--asset-pattern — escape hatch

When the heuristic picks the wrong asset, override it explicitly:

ixt tool install oddproject/weirdtool \
    --asset-pattern 'weird-{version}-{os}-{arch}.tar.gz'

Placeholders: {version}, {tag}, {os}, {arch}. The pattern is persisted in the tool's metadata and survives upgrades — specify it once.

Learned asset patterns

For GitHub releases, ixt learns the asset URL template after a successful install and stores it in $IXT_CACHE_HOME/metadata/asset_patterns.json. Later installs and upgrades of the same tool can resolve the latest tag through the regular github.com/.../releases/latest redirect and download the matching asset directly, avoiding api.github.com on the common path.

If a maintainer changes the asset naming convention, ixt invalidates the learned pattern and falls back to the release API to relearn it.

Asset index and no-API mode

asset_index.json is portable resolution metadata for GitHub binary assets. A team or CI pipeline can preload one or more local files and optionally forbid the GitHub Releases API fallback:

export IXT_ASSET_INDEX="/org/asset_index.json;/project/asset_index.json"
export IXT_GITHUB_API=never
ixt tool install BurntSushi/ripgrep

Asset index details

Registry

Common tools are available by short name:

ixt tool install ripgrep                 # short name → registry → BurntSushi/ripgrep
ixt tool install @gh:ripgrep             # explicit prefix, same result

Registry details


Forcing a backend

When auto-detection isn't sufficient, use namespace prefixes:

ixt tool install @pypi:ruff
ixt tool install @npm:prettier
ixt tool install @gh:BurntSushi/ripgrep
ixt tool install @gl:gitlab-org/cli              # shorthand for gitlab.com/...
ixt tool install gitlab.company.com/team/tool    # self-hosted (no prefix needed)