Website: alur.happytoolin.com
alur is a native package-manager command router for npm, yarn, pnpm, bun, and deno.
It has three main jobs:
- Fast mode runs eligible scripts and local bins directly, skipping package-manager CLI startup.
- The
nicommand family gives you one set of commands across every package manager. - The optional
nodeshim lets you typenode install,node run, andnode execlike Node had Bun-style package commands.
alur is beta software. The supported interface is the CLI; Rust crate modules are internal and do not carry a stable API guarantee.
Install it on macOS / Linux:
curl -fsSL https://bin.happytoolin.com/alur | sh
alur --versionInstall it with PowerShell:
irm https://bin.happytoolin.com/alur.ps1 | iex
alur --versionOr install from npm:
npm install -g @happytoolin/alur
alur --versionOr install globally from JSR with Deno:
deno install --global -A -n alur jsr:@happytoolin/alur/alur
alur --versionUse the short commands:
ni vite # add vite with the detected package manager
nr dev # run the dev script, using fast mode when safe
nex eslint . # run a local bin directly when possible
nci # clean install from the lockfileOr use the explicit alur commands:
alur install vite
alur run dev
alur exec eslint .
alur ciEnable the optional node shim when you want Node to behave like an all-in-one package command:
eval "$(alur init zsh)"
node install vite
node run dev
node exec vitestnpm install -g @happytoolin/alur
alur --versionThe npm package installs alur plus the multicall aliases: ni, nr, nex, nrm, nci, npar, and nseq.
The node shim is not enabled by npm install. It is always opt-in through alur init <shell>.
Under the hood, npm postinstall downloads the matching native alur binary from the GitHub release.
brew tap happytoolin/happytap
brew install alur
alur --versiondeno install --global -A -n alur jsr:@happytoolin/alur/alur
alur --versionmacOS / Linux:
curl -fsSL https://bin.happytoolin.com/alur | shShell script alias:
curl -fsSL https://bin.happytoolin.com/alur.sh | shPowerShell:
irm https://bin.happytoolin.com/alur.ps1 | iexDirect GitHub release URLs are available too:
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/happytoolin/alur/releases/latest/download/alur-installer.sh | shPin a specific version:
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/happytoolin/alur/releases/download/v0.0.7/alur-installer.sh | shCI example:
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/happytoolin/alur/releases/download/v0.0.7/alur-installer.sh | sh
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> "$GITHUB_ENV"Use releases/latest/download to follow the latest release. Use a versioned release URL for repeatable automation.
Fast mode is the default for eligible nr, alur run, nex, alur exec, and matching node shim commands.
Instead of starting npm run, pnpm exec, or another package-manager CLI, alur resolves the script or local executable itself and launches it directly.
nr dev
alur run test -- --watch
nex eslint .
node run dev
node exec vitestFast mode currently targets common local work:
package.jsonscripts, includingpre<script>andpost<script>lifecycle hooks- nearest
deno.json/deno.jsonctasks in Deno projects - local bins in
node_modules/.bin - pnpm hoisted bins under
node_modules/.pnpm/node_modules/.bin - package-local
binentries - Yarn Plug'n'Play local bins through the project
.pnp.cjs/.pnp.jsloader
If alur cannot prove the fast path is correct, it falls back to package-manager mode.
Common fallback cases include Yarn Plug'n'Play scripts, Deno workspaces, remote package exec, and scripts that depend on package-manager-specific env expansion.
Control it per command:
nr --fast dev # prefer fast mode
nr --pm dev # force package-manager mode
nex --pm create-vite@latest
node run --pm devInspect what happened:
nr dev --print-command
nr dev --explain
alur doctorLatest tracked fast benchmark snapshot: fast mode averaged 4.59x faster than package-manager mode, with local-bin exec cases like nex hello --flag reaching 47.43x.
See benchmark/LATEST.md for the current snapshot and docs/fast-compat.md for the exact compatibility rules.
Use one command vocabulary and let alur pick the right package manager from the project.
| Task | Short command | Explicit command |
|---|---|---|
| Install dependencies or add packages | ni |
alur install |
| Run scripts | nr |
alur run |
| Execute package binaries | nex |
alur exec |
| Uninstall packages | nrm |
alur uninstall |
| Clean install | nci |
alur ci |
| Run shell commands in parallel | npar |
alur parallel |
| Run shell commands sequentially | nseq |
alur sequential |
ni installs dependencies when called with no package names. It adds packages when package names are present.
ni
ni vite
ni react react-dom
ni -D vitest
ni -g eslint
ni --frozen
ni --frozen-if-presentExamples by detected package manager:
| Project | ni |
ni vite |
|---|---|---|
| npm | npm i |
npm i vite |
| yarn | yarn install |
yarn add vite |
| pnpm | pnpm i |
pnpm add vite |
| bun | bun install |
bun add vite |
| deno | deno install |
deno add vite |
Global installs use global_package_manager, which defaults to npm.
nr runs package scripts. With no script name, it runs start.
nr
nr dev
nr -r build
nr --filter "@org/app..." test
nr build
nr test -- --watch
nr --if-present lintIn fast mode, nr can skip the package manager and run the script directly. Use --pm when you need exact package-manager behavior.
Workspace fast mode supports -r / --recursive, repeated --filter / -F, --parallel, --workspace-concurrency, --resume-from, --stream, --workspace-root, and --include-workspace-root for common npm/pnpm-style monorepos.
nex runs package binaries.
nex vitest
nex -r tsc --version
nex --filter "@org/app" eslint .
nex eslint .
nex create-vite@latestWhen a local executable can be resolved confidently, nex runs it directly. Remote or ambiguous cases fall back to the detected package manager.
Workspace nex fast mode runs an installed local bin in each selected package.
nrm lodash
nrm react react-dom
nrm -g typescript
nci
nci --prefer-offlinenci uses a package-manager-specific frozen install when a lockfile exists. Without a lockfile, it falls back to normal install behavior.
Each argument is a separate shell command.
npar "pnpm dev" "pnpm test"
nseq "pnpm lint" "pnpm test"npar runs all commands concurrently and returns the first non-zero exit code. nseq runs commands in order and stops on the first failure.
The node shim is for people who want package commands to feel built into Node.
After init, these work:
node install
node install vite
node add react
node uninstall lodash
node remove lodash
node run dev
node exec vitest
node x eslint .
node ci
node p "echo one" "echo two"
node s "pnpm lint" "pnpm test"That gives Node a Bun-like command surface, while still using your project's real package manager.
The shim routes known alur shim verbs and aliases:
node input |
Routes to |
|---|---|
node install, node i |
install or add behavior |
node add |
add behavior |
node uninstall, node remove |
uninstall behavior |
node run |
script runner |
node exec, node x, node dlx |
binary executor |
node ci |
clean install |
node p |
parallel shell commands |
node s |
sequential shell commands |
Everything else passes through to the real Node.js binary:
node script.js
node -v
node --run dev
node --watch server.js
node -- --trace-warningsRun alur init for your shell and put the output at the end of your shell config, after tools like nvm, mise, asdf, fnm, or volta.
zsh (~/.zshrc):
eval "$(alur init zsh)"bash (~/.bashrc):
eval "$(alur init bash)"fish (~/.config/fish/config.fish):
alur init fish | sourcePowerShell ($PROFILE):
Invoke-Expression (& alur init powershell)Nushell (~/.config/nushell/config.nu):
alur init nushell | save --force ~/.config/nushell/alur.nu
source ~/.config/nushell/alur.nuRestart your shell after editing your config.
alur init creates a managed node launcher and prints shell-specific PATH setup. On routed commands, alur finds the real Node.js binary and keeps normal Node behavior available.
If real Node cannot be found, set ALUR_REAL_NODE=/absolute/path/to/node.
To disable the node shim, remove the alur init line from your shell config and restart the shell.
alur pm which
alur pm use pnpm@9.15.4
alur pm shimalur pm which prints the detected package-manager binary. alur pm use writes packageManager in the nearest package.json. alur pm shim creates managed npm, npx, pnpm, pnpx, yarn, yarnpkg, bun, bunx, and deno wrappers that route to the package manager detected for the current project.
These tools do not download package managers or rewrite lockfiles yet.
alur detects the package manager from:
packageManagerinpackage.json- lockfiles such as
pnpm-lock.yaml,pnpm-workspace.yaml,yarn.lock,package-lock.json,bun.lockb, ordeno.lock devEngines.packageManagerinpackage.json- install metadata such as
.pnp.cjs,node_modules/.pnpm, ornode_modules/.package-lock.json - config defaults if detection is unavailable
When detection fails, add a packageManager field, commit a lockfile, or set default_package_manager.
Config file:
$XDG_CONFIG_HOME/alur/config.toml- macOS default:
~/Library/Application Support/alur/config.toml - Windows default:
%APPDATA%\alur\config.toml
Supported keys:
default_package_manager = "pnpm"
global_package_manager = "npm"
fast_mode = trueEnvironment overrides:
ALUR_CONFIG_FILEALUR_DEFAULT_PACKAGE_MANAGERALUR_GLOBAL_PACKAGE_MANAGERALUR_FAST_MODEALUR_REAL_NODE
These work across alur, the ni aliases, and routed node shim commands:
--fast
--pm
--print-command
--explain
-C <dir>
-v --version
-h --helpFor the node shim, alur only parses these flags after a routed verb. Normal
Node.js flags and non-routed first arguments are passed through untouched:
node run --pm dev --print-command
node --run dev --print-command
node --conditions=dev script.jsUse -- to forward flags to the underlying package manager or script:
alur install -- --help
nr test -- --watch
node run test -- --watchalur help
alur help ni
alur completion zsh
alur init bash
alur doctor
alur pm whichPowerShell ships with a built-in ni alias for New-Item.
If that conflicts with alur, remove or override it in your profile before loading alur:
Remove-Item Alias:ni -ErrorAction SilentlyContinue
Invoke-Expression (& alur init powershell)Use --print-command for the resolved command and --explain for detection details:
ni vite --print-command
nr dev --explain
node install vite --print-commandalur doctor also reports project signal warnings, such as conflicting lockfiles, packageManager / devEngines.packageManager disagreement, package-manager declarations that do not match the lockfile, and Yarn Plug'n'Play script fallback cases.
Fast mode intentionally does not emulate every package-manager edge case.
Use --pm for Yarn PnP scripts, Deno workspaces, package-manager-specific env expansion, remote package exec, or debugging exact package-manager behavior:
nr --pm build
nex --pm create-vite@latest
node run --pm devThe benchmark suite lives in benchmark/.
Common local commands:
npm ci
npm run bench
npm run bench -- --track=all --runs=100 --warmups=10Generate flamegraphs:
./benchmark/profile.shTracked benchmark docs:
- current snapshot:
benchmark/LATEST.md - lightweight history:
benchmark/HISTORY.md - benchmark guide:
benchmark/README.md - fast-mode compatibility:
docs/fast-compat.md
The short command family follows the spirit of Antfu's ni.
