{"id":15168422,"url":"https://github.com/debbl/nci","last_synced_at":"2026-05-19T09:01:31.082Z","repository":{"id":238484316,"uuid":"795777244","full_name":"Debbl/nci","owner":"Debbl","description":"💡 Use the right package manager","archived":false,"fork":false,"pushed_at":"2024-12-02T23:46:56.000Z","size":110,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-31T07:11:44.723Z","etag":null,"topics":["bun","ni","node","npm","pnpm","rust","yarn"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/nci","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Debbl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-04T03:12:09.000Z","updated_at":"2024-10-11T03:11:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"76113526-4bf9-48c7-973e-ffce221880bf","html_url":"https://github.com/Debbl/nci","commit_stats":{"total_commits":29,"total_committers":2,"mean_commits":14.5,"dds":0.06896551724137934,"last_synced_commit":"96dad218332a4d86cb3995bcee345958f7117be6"},"previous_names":["debbl/nci"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Debbl%2Fnci","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Debbl%2Fnci/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Debbl%2Fnci/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Debbl%2Fnci/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Debbl","download_url":"https://codeload.github.com/Debbl/nci/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238137886,"owners_count":19422721,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bun","ni","node","npm","pnpm","rust","yarn"],"created_at":"2024-09-27T06:02:31.217Z","updated_at":"2026-05-19T09:01:31.065Z","avatar_url":"https://github.com/Debbl.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nci\n\nA Rust port of [antfu-collective/ni](https://github.com/antfu-collective/ni).\n\n**nci** — use the right package manager.\n\n\u003ca href='https://docs.npmjs.com/cli/v6/commands/npm'\u003enpm\u003c/a\u003e · \u003ca href='https://yarnpkg.com'\u003eyarn\u003c/a\u003e · \u003ca href='https://pnpm.io/'\u003epnpm\u003c/a\u003e · \u003ca href='https://bun.sh/'\u003ebun\u003c/a\u003e · \u003ca href='https://deno.land/'\u003edeno\u003c/a\u003e\n\n## Install\n\n```bash\ncargo install nci\n```\n\nThis installs eight binaries: `ni`, `nr`, `nlx`, `nup`, `nun`, `nci`, `nd`, `na` (plus `nu` as a legacy alias for `nup`).\n\n## Credits\n\n- [antfu-collective/ni](https://github.com/antfu-collective/ni)\n- [zhazhazhu/ni](https://github.com/zhazhazhu/ni)\n\n---\n\n### `ni` — install\n\n```bash\nni\n\n# npm install\n# yarn install\n# pnpm install\n# bun install\n# deno install\n```\n\n```bash\nni vite\n\n# npm i vite\n# yarn add vite\n# pnpm add vite\n# bun add vite\n# deno add vite\n```\n\n```bash\nni @types/node -D\n\n# npm i @types/node -D\n# yarn add @types/node -D\n# pnpm add -D @types/node\n# bun add -d @types/node\n# deno add -D @types/node\n```\n\n```bash\nni -P\n\n# npm i --omit=dev\n# yarn install --production\n# pnpm i --production\n# bun install --production\n# (deno not supported)\n```\n\n```bash\nni --frozen\n\n# npm ci\n# yarn install --frozen-lockfile (Yarn 1)\n# yarn install --immutable (Yarn Berry)\n# pnpm i --frozen-lockfile\n# bun install --frozen-lockfile\n# deno install --frozen\n```\n\n```bash\nni -g eslint\n\n# npm i -g eslint\n# yarn global add eslint (Yarn 1)\n# pnpm add -g eslint\n# bun add -g eslint\n# deno install -g eslint\n\n# uses the global agent, regardless of your current working directory\n```\n\n```bash\nni -i\n\n# interactively search the npm registry and pick a package to install\n```\n\n\u003cdetails\u003e\n\u003csummary\u003epnpm catalogs\u003c/summary\u003e\n\nWhen a pnpm workspace declares [catalogs](https://pnpm.io/catalogs) in `pnpm-workspace.yaml`, `nci` writes `catalog:` references into `package.json` instead of pinning versions:\n\n```bash\n# pnpm-workspace.yaml:\n#   catalog:\n#     react: ^18.3.0\n\nni react\n# → detects react in the default catalog\n# → writes \"react\": \"catalog:\" to package.json\n# → runs `pnpm i`\n\nni lodash\n# → lodash isn't in any catalog\n# → with only a default catalog: silently adds to it\n# → with multiple named catalogs: prompts for a catalog (or skip / create new)\n# → fetches latest from the npm registry, updates pnpm-workspace.yaml\n# → writes \"lodash\": \"catalog:...\" to package.json\n# → runs `pnpm i`\n```\n\nThe dependency flag picks the right `package.json` section:\n\n```bash\nni typescript -D\n# → writes \"typescript\": \"catalog:dev\" to devDependencies\n```\n\n`-w` / `--workspace` targets the workspace root's `package.json`:\n\n```bash\nni react -w\n```\n\nTo disable catalog mode, set `catalog=false` in `~/.nirc` or `NI_CATALOG=false`.\n\n\u003c/details\u003e\n\n\u003cbr\u003e\n\n### `nr` — run\n\n```bash\nnr dev --port=3000\n\n# npm run dev -- --port=3000\n# yarn run dev --port=3000\n# pnpm run dev --port=3000\n# bun run dev --port=3000\n# deno task dev --port=3000\n```\n\n```bash\nnr\n\n# interactive picker (fzf-style fuzzy filtering)\n# supports https://www.npmjs.com/package/npm-scripts-info convention\n```\n\n```bash\nnr -\n\n# rerun the last command\n```\n\n```bash\nnr -p\nnr -p dev\n\n# pick a workspace package (auto-selects when only one matches), then\n# run the script there\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eshell completion\u003c/summary\u003e\n\n```bash\n# bash\nnr --completion-bash \u003e\u003e ~/.bashrc\n\n# zsh — for example with zim:fw\nmkdir -p ~/.zim/custom/ni-completions\nnr --completion-zsh \u003e ~/.zim/custom/ni-completions/_ni\necho \"zmodule $HOME/.zim/custom/ni-completions --fpath .\" \u003e\u003e ~/.zimrc\nzimfw install\n\n# fish\nmkdir -p ~/.config/fish/completions\nnr --completion-fish \u003e ~/.config/fish/completions/nr.fish\n```\n\n\u003c/details\u003e\n\n\u003cbr\u003e\n\n### `nlx` — download \u0026 execute\n\n```bash\nnlx vitest\n\n# npx vitest\n# yarn dlx vitest\n# pnpm dlx vitest\n# bun x vitest\n# deno x vitest\n```\n\n\u003cbr\u003e\n\n### `nup` — upgrade\n\n```bash\nnup\n\n# npm update\n# yarn upgrade (Yarn 1)\n# yarn up (Yarn Berry)\n# pnpm update\n# bun update\n# deno outdated --update\n```\n\n```bash\nnup -i\n\n# (not available on npm)\n# yarn upgrade-interactive (Yarn 1)\n# yarn up -i (Yarn Berry)\n# pnpm update -i\n# bun update -i\n# deno outdated --update\n```\n\n\u003e Earlier versions of nci shipped this command as `nu`. The `nu` binary is still installed as a deprecated alias to keep old scripts working; new shells should use `nup` (matching upstream's rename away from a clash with Nushell).\n\n\u003cbr\u003e\n\n### `nun` — uninstall\n\n```bash\nnun webpack\n\n# npm uninstall webpack\n# yarn remove webpack\n# pnpm remove webpack\n# bun remove webpack\n# deno remove webpack\n```\n\n```bash\nnun\n\n# interactively multi-select dependencies to remove\n```\n\n```bash\nnun -g silent\n\n# npm uninstall -g silent\n# yarn global remove silent\n# pnpm remove -g silent\n# bun remove -g silent\n# deno uninstall -g silent\n```\n\n\u003cbr\u003e\n\n### `nci` — clean install\n\n```bash\nnci\n\n# npm ci\n# yarn install --frozen-lockfile\n# pnpm i --frozen-lockfile\n# bun install --frozen-lockfile\n# deno install --frozen\n```\n\nIf the detected agent isn't installed, `nci` will offer to globally install it for you (or just do it when `NI_AUTO_INSTALL=true`).\n\n\u003cbr\u003e\n\n### `nd` — dedupe dependencies\n\n```bash\nnd\n\n# npm dedupe\n# yarn dedupe (Yarn Berry only — Yarn 1 doesn't support it)\n# pnpm dedupe\n# (bun / deno not supported)\n```\n\n`nd -c` rewrites to `--check` on pnpm and `--dry-run` on npm — both ways to preview without writing.\n\n\u003cbr\u003e\n\n### `na` — agent alias\n\n```bash\nna\n\n# npm\n# yarn\n# pnpm\n# bun\n# deno\n```\n\n```bash\nna run foo\n\n# npm run foo\n# yarn run foo\n# pnpm run foo\n# bun run foo\n# deno run foo\n```\n\n\u003cbr\u003e\n\n### Global flags\n\n```bash\n# ?               | dry-run: print the resolved command and exit\nni vite ?\n\n# -C              | change directory before running anything\nni -C packages/foo vite\nnr -C playground dev\n\n# --agent         | print the detected agent name (for shell scripts)\nnci --agent          # prints \"pnpm\", \"npm\", \"deno\", or \"unknown\"\n\n# --programmatic  | suppress prompts and the \"Running:\" banner\nni react --programmatic\n\n# -v, --version   | show nci / node / detected agent / global agent versions\nni -v\n\n# -h, --help      | show help\nni -h\n```\n\n\u003cbr\u003e\n\n### Config\n\n```ini\n; ~/.nirc\n\n; fallback when no lock file is detected\ndefaultAgent=npm                # default: \"prompt\"\n\n; agent used for `-g` global installs\nglobalAgent=npm\n\n; use `node --run \u003cscript\u003e` instead of `\u003cagent\u003e run \u003cscript\u003e` (requires Node 22+)\nrunAgent=node\n\n; wrap every spawned command with `sfw \u003cagent\u003e \u003cargs\u003e`\nuseSfw=true\n\n; pnpm catalog support; set to false to opt out\ncatalog=true\n\n; suppress the `nr` picker's behaviour of surfacing the last-run script\nnoLastCommand=false\n```\n\nKeys are also accepted in `snake_case` (`default_agent`, `global_agent`, …) for backward compatibility.\n\nEvery option has a matching environment variable that takes precedence over `~/.nirc`:\n\n```bash\nexport NI_CONFIG_FILE=\"$HOME/.config/ni/nirc\"   # alternate rc path\nexport NI_DEFAULT_AGENT=pnpm\nexport NI_GLOBAL_AGENT=npm\nexport NI_RUN_AGENT=node\nexport NI_USE_SFW=true\nexport NI_CATALOG=false\nexport NI_NO_LAST_COMMAND=true\nexport NI_AUTO_INSTALL=true                     # auto `npm i -g` missing agents\n```\n\nOn Windows (PowerShell):\n\n```powershell\n$Env:NI_CONFIG_FILE = 'C:\\path\\to\\your\\nirc'\n```\n\n\u003cbr\u003e\n\n### Integrations\n\n#### asdf\n\n`ni` is available via the [3rd-party asdf-plugin](https://github.com/CanRau/asdf-ni.git) maintained by [CanRau](https://github.com/CanRau):\n\n```bash\nasdf plugin add ni https://github.com/CanRau/asdf-ni.git\nasdf install ni latest\nasdf global ni latest\n```\n\n\u003cbr\u003e\n\n### How?\n\n`nci` assumes you work with lockfiles. Before running, it inspects (in order of precedence):\n\n1. `deno.json` / `deno.jsonc` → deno\n2. `bun.lock` / `bun.lockb` → bun\n3. `pnpm-lock.yaml` → pnpm\n4. `yarn.lock` → yarn\n5. `package-lock.json` / `npm-shrinkwrap.json` → npm\n6. `packageManager` field in `package.json`\n\n`yarn@\u003e1` is treated as Yarn Berry; `pnpm@\u003c7` is treated as pnpm 6. The full command table lives in [`src/agents.rs`](src/agents.rs) and mirrors [`package-manager-detector`'s commands](https://github.com/antfu-collective/package-manager-detector/blob/main/src/commands.ts).\n\n\u003cbr\u003e\n\n### Troubleshooting\n\n#### Conflicts with PowerShell's `ni`\n\nPowerShell ships with a built-in alias `ni` for the `New-Item` cmdlet. Remove it in the current session:\n\n```powershell\nRemove-Item Alias:ni -Force -ErrorAction Ignore\n```\n\nTo persist, drop the same line into your PowerShell profile (`$PROFILE`):\n\n```powershell\nif (-not (Test-Path $profile)) {\n  New-Item -ItemType File -Path (Split-Path $profile) -Force -Name (Split-Path $profile -Leaf)\n}\n\n$profileEntry = 'Remove-Item Alias:ni -Force -ErrorAction Ignore'\n$profileContent = Get-Content $profile\nif ($profileContent -notcontains $profileEntry) {\n  (\"`n\" + $profileEntry) | Out-File $profile -Append -Force -Encoding UTF8\n}\n```\n\n#### `nx` / `nix` / `nu`\n\nUpstream renamed `nx`/`nix` to `nlx` (clashes with [nx](https://nx.dev/) and [nix](https://nixos.org/)) and `nu` to `nup` (clashes with [Nushell](https://www.nushell.sh/)). `nci` keeps `nu` as an alias for `nup`. For `nlx`, alias the others yourself if you prefer:\n\n```bash\nalias nx=\"nlx\"\nalias nix=\"nlx\"\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdebbl%2Fnci","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdebbl%2Fnci","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdebbl%2Fnci/lists"}