shim installs CLI tools into isolated, managed environments and exposes them through executable shims.
The built-in provider is currently npm, backed by a managed node runtime.
Global npm tools usually run with whichever node is currently selected in your shell. If prettier was installed for Node 22 but your shell now points at Node 24, running prettier depends on today's shell state instead of the runtime it was installed for.
shim installs npm tools into managed prefixes, records the selected Node runtime, and exposes deterministic wrappers from ~/.shim/bin. This makes global tools predictable while still supporting npm compatibility features such as --expose when one managed tool needs to resolve another managed package.
brew install awwoken/tap/shimAdd the shim bin directory to PATH:
export PATH="$HOME/.shim/bin:$PATH"Install a tool:
shim install prettier
shim install npm:prettier@3.8.3List installed tools:
shim listFind a shim path:
shim which prettierRemove a tool:
shim remove prettierUpgrade tools:
shim upgrade
shim upgrade prettierPreview and remove orphaned managed runtimes:
shim prune --dry-run
shim prune --yesCheck installation health:
shim doctordoctor validates the shim home, registry state, runtime/provider files, PATH shadowing, and generated shim file contents.
Repair generated shim files from registry metadata:
shim repairUseful install options:
shim install prettier --runtime 24
shim install prettier --force
shim install prettier --ignore-scripts
shim install typescript --exposeUse --expose when an npm package should be resolvable by other managed Node tools at runtime. Exposed packages are linked into shim's managed npm module namespace, and generated Node shims include that namespace in NODE_PATH.
For example, to let typescript-language-server discover the managed typescript package automatically:
shim install typescript --expose
shim install typescript-language-servershim reads config from:
~/.shim/config.jsonUse SHIM_HOME to override the home directory:
SHIM_HOME=/tmp/shim-test shim install prettierExample config:
{
"providers": {
"npm": {
"registry": "https://registry.npmjs.org"
}
},
"runtimes": {
"node": {
"bootstrapVersion": "24.16.0",
"mirror": "https://nodejs.org/dist"
}
}
}Run from source:
bun run dev -- <command>Build a local development binary:
bun install
bun run build
build/shim <command>Common checks:
bun run fmt:check
bun run lint
bun run typecheck
bun run build
bun testReleases use a release PR followed by a version tag.
To prepare a release, open a PR that bumps package.json. Review and merge that PR normally.
After the release PR is merged, tag the merged main commit and push the tag:
git checkout main
git pull
git tag vX.Y.Z
git push origin vX.Y.ZThe Release workflow runs from pushed v* tags. It verifies the tag matches package.json, runs checks, creates or updates the GitHub release, and updates awwoken/homebrew-tap with the new formula checksums.
Required repository secret:
HOMEBREW_TAP_TOKEN— token that can push toawwoken/homebrew-tap.
Optional repository secret:
RELEASE_TOKEN— token used instead ofGITHUB_TOKENfor creating or updating GitHub releases.
MIT