5 releases
Uses new Rust 2024
| 0.0.2 | Mar 15, 2026 |
|---|---|
| 0.0.1-alpha-4 | Mar 8, 2026 |
#686 in Development tools
280KB
6K
SLoC
hni

Fast package manager routing for npm, yarn, pnpm, bun, and deno.
hni is inspired by Antfu's ni, but packaged as a single multicall binary with extra shell setup for a node shim.
hni is still beta software and may have bugs.
One install gives you:
hnini,nr,nlx,nu,nun,nci,na,np,nsnodeshim viahni init <shell>(shell plugin only)
Install
npm (global)
npm install -g @happytoolin/hni
hni --version
This installs hni and the ni-family aliases (ni, nr, nlx, nu, nun, nci, na, np, ns) onto your global npm bin path.
The node shim is only enabled through hni init <shell>.
Under the hood, npm resolves a platform-specific optional dependency package that contains the native hni binary.
Homebrew
brew tap happytoolin/happytap
brew install hni
hni --version
Script install (macOS / Linux)
TODO: https://happytoolin.com/hni/install.sh is not live yet. Use the raw GitHub script for now:
curl -fsSL https://raw.githubusercontent.com/happytoolin/hni/main/install.sh | bash
Optional environment variables:
HNI_VERSION- install a specific version, for examplev0.0.2HNI_INSTALL_DIR- install somewhere other than~/.local/binHNI_NODE=off- disable thenodeshim for the current environment
Script install (PowerShell)
TODO: https://happytoolin.com/hni/install.ps1 is not live yet. Use the raw GitHub script for now:
irm https://raw.githubusercontent.com/happytoolin/hni/main/install.ps1 | iex
Optional parameters:
-Version latest-InstallDir "$env:LOCALAPPDATA\hni\bin"
Deno / JSR
Install hni:
deno install -gA -n hni jsr:@happytoolin/hni/hni
hni --version
Install alias commands (example):
deno install -gA -n ni jsr:@happytoolin/hni/ni
deno install -gA -n nr jsr:@happytoolin/hni/nr
Commands
ni
Install dependencies or add new ones.
ni
ni vite
ni -D vitest
ni -g eslint
ni --frozen
ni --frozen-if-present
ni --interactive
nr
Run package scripts.
nr
nr dev
nr build
nr test -- --watch
nr --if-present lint
nr --repeat-last
nlx
Execute binaries without adding them permanently to your project.
nlx vitest
nlx eslint .
nlx create-vite@latest
nu
Upgrade dependencies.
nu
nu react react-dom
nu --interactive
nun
Remove dependencies.
nun lodash
nun react react-dom
nun --multi-select
nun -g typescript
nci
Run a clean install. If a lockfile exists, hni uses the package-manager-specific frozen install command.
nci
na
Print or forward directly to the detected package manager.
na --version
na config get registry
np / ns
Run shell commands in parallel or sequentially.
np "pnpm dev" "pnpm test"
ns "pnpm lint" "pnpm test"
node
hni can also act as a package-manager-aware node shim.
Enable it by adding hni init <shell> to your shell config first.
node install vite
node run dev
node exec vitest
node ci
node p "echo one" "echo two"
Regular Node.js usage still passes through:
node script.js
node -v
node -- --trace-warnings
Utilities
hni help ni
hni completion zsh
hni init bash
hni doctor
Shell Setup
If you want node-shim behavior, add the init line at the end of your shell config file, after anything that manages Node or rewrites PATH, such as nvm, mise, asdf, fnm, or volta.
Do not append the hni directory to the end of PATH. Put the init line at the end of the shell config file and let it prepend the correct path for you.
zsh
Add to ~/.zshrc:
eval "$(hni init zsh)"
bash
Add to ~/.bashrc:
eval "$(hni init bash)"
fish
Add to ~/.config/fish/config.fish:
hni init fish | source
PowerShell
Add to $PROFILE:
Invoke-Expression (& hni init powershell)
Nushell
Generate a stable init file, then source it from the end of ~/.config/nushell/config.nu:
hni init nushell | save --force ~/.config/nushell/hni.nu
source ~/.config/nushell/hni.nu
Global Flags
These work across hni and the multicall aliases:
? --dry-run --print-command
--explain
-C <dir>
-v --version
-h --help
Use -- to forward flags to the underlying package manager or script:
hni ni -- --help
nr test -- --watch
Configuration
Config file:
~/.hnirc
Supported keys:
defaultAgent=prompt
globalAgent=npm
runAgent=node
useSfw=false
Environment overrides:
HNI_CONFIG_FILEHNI_DEFAULT_AGENTHNI_GLOBAL_AGENTHNI_USE_SFWHNI_AUTO_INSTALL
How It Works
hni detects the package manager from:
packageManagerinpackage.json- lockfiles such as
pnpm-lock.yaml,yarn.lock,package-lock.json,bun.lockb, ordeno.lock - config defaults if detection is unavailable
Then it maps the command family to the right native command:
ni-> install or addnr-> run or tasknlx->npx/pnpm dlx/yarn dlx/bun xnu-> update / upgradenci-> frozen install when lockfiles exist
Troubleshooting
PowerShell ni alias conflict
PowerShell ships with a built-in ni alias for New-Item.
If that conflicts with hni, remove or override it in your profile before loading hni:
Remove-Item Alias:ni -ErrorAction SilentlyContinue
Invoke-Expression (& hni init powershell)
Check what hni resolved
ni vite --debug-resolved
nr dev --explain
hni doctor
Dependencies
~7–23MB
~280K SLoC