Ni
๐ก Use the right package manager
When working in a pnpm workspace with [catalogs](https://pnpm.io/catalogs) configured in `pnpm-workspace.yaml`, `ni` automatically enters **catalog mode**. Instead of adding packages with pinned versions, it writes `catalog:` references into `package.json` and updates the workspace catalog. The project is written primarily in TypeScript, distributed under the MIT License license, first published in 2020. It has gained significant community traction with 8,251 stars and 272 forks on GitHub. Key topics include: cli, npm, package-manager, pnpm, yarn.
ni
npm i in a yarn project, again? F**k!
ni - use the right package manager
<br> <pre> <code> npm i -g <b>@antfu/ni</b> </code> </pre><a href='https://docs.npmjs.com/cli/v6/commands/npm'>npm</a> ยท <a href='https://yarnpkg.com'>yarn</a> ยท <a href='https://pnpm.io/'>pnpm</a> ยท <a href='https://bun.sh/'>bun</a> ยท <a href='https://deno.land/'>deno</a>
<br>ni - install
bashni # npm install # yarn install # pnpm install # bun install # deno install
bashni vite # npm i vite # yarn add vite # pnpm add vite # bun add vite # deno add vite
bashni @types/node -D # npm i @types/node -D # yarn add @types/node -D # pnpm add -D @types/node # bun add -d @types/node # deno add -D @types/node
bashni -P # npm i --omit=dev # yarn install --production # pnpm i --production # bun install --production # (deno not supported)
bashni --frozen # npm ci # yarn install --frozen-lockfile (Yarn 1) # yarn install --immutable (Yarn Berry) # pnpm install --frozen-lockfile # bun install --frozen-lockfile # deno install --frozen
bashni -g eslint # npm i -g eslint # yarn global add eslint (Yarn 1) # pnpm add -g eslint # bun add -g eslint # deno install eslint # this uses default agent, regardless your current working directory
<details> <summary>catalogs support</summary>bashni -i # interactively select the dependency to install # search for packages by name
Since v29.0.0
When working in a pnpm workspace with catalogs configured in pnpm-workspace.yaml, ni automatically enters catalog mode. Instead of adding packages with pinned versions, it writes catalog: references into package.json and updates the workspace catalog.
bash# Given pnpm-workspace.yaml with: # catalogs: # prod: # react: ^18.3.0 ni react # โ detects react in "prod" catalog # โ writes "react": "catalog:prod" to package.json # โ runs pnpm install ni lodash # โ lodash not in any catalog # โ prompts to select a catalog (or skip) # โ fetches latest version, updates pnpm-workspace.yaml # โ writes "lodash": "catalog:prod" to package.json # โ runs pnpm install
When only a default catalog (catalog: top-level) is used, new packages are added directly without prompting. When only named catalogs exist, the default catalog is never offered.
Flags like -D are respected โ the catalog ref is written to the correct package.json section:
bashni typescript -D # โ writes "typescript": "catalog:dev" to devDependencies
Use -w / --workspace to target the workspace root package.json:
bashni react -w # โ writes catalog ref to workspace root package.json
To disable catalog mode, set catalog=false in ~/.nirc or NI_CATALOG=false environment variable.
nr - run
bashnr dev --port=3000 # npm run dev -- --port=3000 # yarn run dev --port=3000 # pnpm run dev --port=3000 # bun run dev --port=3000 # deno task dev --port=3000
bashnr # interactively select the script to run # supports https://www.npmjs.com/package/npm-scripts-info convention
bashnr - # rerun the last command
<details> <summary>shell completion scripts</summary>bashnr -p nr -p dev # interactively select the package and script to run
</details> <br>bash# Add completion script for bash nr --completion-bash >> ~/.bashrc # Add completion script for zsh # For zim:fw mkdir -p ~/.zim/custom/ni-completions nr --completion-zsh > ~/.zim/custom/ni-completions/_ni echo "zmodule $HOME/.zim/custom/ni-completions --fpath ." >> ~/.zimrc zimfw install # Add completion script for fish mkdir -p ~/.config/fish/completions nr --completion-fish > ~/.config/fish/completions/nr.fish
nlx - download & execute
<br>bashnlx vitest # npx vitest # yarn dlx vitest # pnpm dlx vitest # bunx vitest # deno run npm:vitest
nup - upgrade
bashnup # npm upgrade # yarn upgrade (Yarn 1) # yarn up (Yarn Berry) # pnpm update # bun update # deno upgrade
<br>bashnup -i # (not available for npm) # yarn upgrade-interactive (Yarn 1) # yarn up -i (Yarn Berry) # pnpm update -i # bun update -i # deno outdated -u -i
nun - uninstall
bashnun webpack # npm uninstall webpack # yarn remove webpack # pnpm remove webpack # bun remove webpack # deno remove webpack
bashnun # interactively multi-select # the dependencies to remove
<br>bashnun -g silent # npm uninstall -g silent # yarn global remove silent # pnpm remove -g silent # bun remove -g silent # deno uninstall -g silent
nci - clean install
<br>bashnci # npm ci # yarn install --frozen-lockfile # pnpm install --frozen-lockfile # bun install --frozen-lockfile # deno cache --reload
nd - dedupe dependencies
<br>bashnd # npm dedupe # yarn dedupe # pnpm dedupe
na - agent alias
bashna # npm # yarn # pnpm # bun # deno
<br>bashna run foo # npm run foo # yarn run foo # pnpm run foo # bun run foo # deno task foo
Global Flags
<br>bash# ? | Print the command execution depends on the agent ni vite ? # -C | Change directory before running the command ni -C packages/foo vite nr -C playground dev # -v, --version | Show version number ni -v # -h, --help | Show help ni -h
Config
ini; ~/.nirc ; fallback when no lock found defaultAgent=npm # default "prompt" ; for global installs globalAgent=npm ; use node --run instead of package manager run command (requires Node.js 22+) runAgent=node ; prefix commands with sfw useSfw=true ; use catalog mode when catalogs are detected (default true) catalog=true
bash# ~/.bashrc # custom configuration file path export NI_CONFIG_FILE="$HOME/.config/ni/nirc" # environment variables have higher priority than config file if presented export NI_DEFAULT_AGENT="npm" # default "prompt" export NI_GLOBAL_AGENT="npm" export NI_USE_SFW="true" export NI_CATALOG="false" # disable catalog mode
<br>ps# for Windows # custom configuration file path in PowerShell accessible within the `$profile` path $Env:NI_CONFIG_FILE = 'C:\to\your\config\location'
Automatic installation
You can set NI_AUTO_INSTALL=true to enable automatic installation.
If the corresponding package manager (npm, yarn, pnpm, bun, or deno) is not installed, it will install it globally before running the command.
Integrations
Homebrew
You can install ni with Homebrew:
bashbrew install ni
asdf
You can also install ni via the 3rd-party asdf-plugin maintained by CanRau
bash# first add the plugin asdf plugin add ni https://github.com/CanRau/asdf-ni.git # then install the latest version asdf install ni latest # and make it globally available asdf global ni latest
How?
ni assumes that you work with lock-files (and you should).
Before ni runs the command, it detects your yarn.lock / pnpm-lock.yaml / package-lock.json / bun.lock / bun.lockb / deno.json / deno.jsonc to know the current package manager (or packageManager field in your packages.json if specified) using the package-manager-detector package and then runs the corresponding package-manager-detector command.
Trouble shooting
Conflicts with PowerShell
PowerShell comes with a built-in alias ni for the New-Item cmdlet. To remove the alias in your current PowerShell session in favor of this package, use the following command:
PowerShell'Remove-Item Alias:ni -Force -ErrorAction Ignore'
If you want to persist the changes, you can add them to your PowerShell profile. The profile path is accessible within the $profile variable. The ps1 profile file can normally be found at
- PowerShell 5 (Windows PowerShell):
C:\Users\USERNAME\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 - PowerShell 7:
C:\Users\USERNAME\Documents\PowerShell\Microsoft.PowerShell_profile.ps1 - VSCode:
C:\Users\USERNAME\Documents\PowerShell\Microsoft.VSCode_profile.ps1
You can use the following script to remove the alias at shell start by adding the above command to your profile:
PowerShellif (-not (Test-Path $profile)) { New-Item -ItemType File -Path (Split-Path $profile) -Force -Name (Split-Path $profile -Leaf) } $profileEntry = 'Remove-Item Alias:ni -Force -ErrorAction Ignore' $profileContent = Get-Content $profile if ($profileContent -notcontains $profileEntry) { ("`n" + $profileEntry) | Out-File $profile -Append -Force -Encoding UTF8 }
nx, nix and nu are no longer available
We renamed nx/nix and nu to nlx and nup to avoid conflicts with the other existing tools - nx, nix and nushell. You can always alias them back on your shell configuration file (.zshrc, .bashrc, etc).
bashalias nx="nlx" # or alias nix="nlx" # or alias nu="nup"
Contributors
Showing top 12 contributors by commit count.
