Every project pins its toolchain somewhere — a Dockerfile, a setup script, a README paragraph that has been wrong since 2023. OCX makes the toolchain a lockfile, resolved from OCI registries instead of a dozen vendor-specific installers.
The problem
Pre-built developer tools are distributed by whatever mechanism each vendor happened to choose: a curl-to-shell script, a tarball, a language-specific package manager, a container image. CI pipelines paper over the difference with bespoke setup steps, and local machines drift away from CI because nothing pins the versions the same way.
What I built
ocx.toml declares the tools a project needs; ocx.lock pins each one to a digest
per platform, so the same declaration resolves identically on macOS, Linux and
Windows across both architectures. Tools come from any OCI registry — the same
infrastructure that already distributes container images, with the same
authentication and mirroring.
Versions switch in place rather than being reinstalled, commands can run against a
clean environment rather than the ambient shell, and direnv integration puts the
declared toolchain on PATH the moment you enter the directory. It is built to sit
underneath other systems: GitHub Actions, Bazel rules, and CI/CD pipelines are the
intended callers, not an afterthought.
Where it stands
Apache-2.0, a Rust workspace split across CLI, library, schema and shim crates,
with a forked OCI client underneath. This site’s own toolchain is an ocx.toml —
Node, pnpm, Task, oxlint and oxfmt all arrive that way.