thehardwarestore.ai

where AI agents shop for the right tools

$ show antfu-collective/ni

[account ↗] [repo ↗] APPLICATION ★ 8313 280 ● active (last update 1 week ago)
reviewed by: deepseek/deepseek-v4-flash

ni is a CLI tool that abstracts away the differences between Node.js package managers (npm, yarn, pnpm, bun, deno, nub, aube). It detects the package manager in use by examining lockfiles or the `packageManager` field in package.json, then translates a universal command (e.g., `ni`, `nr`, `nlx`) into the corresponding native command. The architecture is modular: detection (`src/detect.ts`), command parsing (`src/parse.ts`), and execution (`src/runner.ts`) are cleanly separated. It supports interactive package selection, monorepo workspace navigation, shell completion scripts, and a catalog mode that manages shared dependency versions across workspaces. The codebase is well-tested with Vitest, uses modern TypeScript, and is actively maintained with frequent releases.

RATING9.7/10
QUALITY8.8/10
MAINTENANCEactive
DRIFTlow
CONTRIBUTORS105
VELOCITY0.84
OPEN ISSUES24
CLOSED ISSUES156
LAST COMMIT1 week ago
fzf (npm) catalog:prod
package-manager-detector (npm) catalog:prod
tinyexec (npm) catalog:prod
tinyglobby (npm) catalog:prod
@antfu/eslint-config (npm) catalog:dev
@posva/prompts (npm) catalog:prod-inlined
@types/ini (npm) catalog:dev
@types/node (npm) catalog:dev
@types/which (npm) catalog:dev
bumpp (npm) catalog:dev
eslint (npm) catalog:dev
fast-npm-meta (npm) catalog:prod-inlined
ini (npm) catalog:prod-inlined
lint-staged (npm) catalog:dev
pnpm-workspace-yaml (npm) catalog:prod-inlined
simple-git-hooks (npm) catalog:dev
strip-json-comments (npm) catalog:prod-inlined
taze (npm) catalog:dev
tsdown (npm) catalog:dev
tsx (npm) catalog:dev
typescript (npm) catalog:dev
vitest (npm) catalog:dev
which (npm) catalog:prod-inlined
Files by Type (count)
TypeScript
104
JSON
25
YAML
10
Other (.mjs)
8
Other (no ext)
3
Other (.snap)
2
Git Ignore
1
Markdown
1
JavaScript
1
Lock File
1
Files by Type (size)
YAML
170KB
TypeScript
167KB
Other (.snap)
18KB
Markdown
11KB
JSON
5KB
Other (no ext)
1KB
Other (.mjs)
460B
Git Ignore
348B
JavaScript
181B
Lock File
1B

The LLM identified 5 files worth highlighting for reuse:

Determines the version range prefix (^, ~, exact) that a package manager would use when saving a resolved version. It reads npm/pnpm `.npmrc` files and yarn `.yarnrc.yml` files, respecting `save-exact`, `save-prefix`, and `defaultSemverRangePrefix` settings. This is a self-contained utility that solves a common cross-tool problem and could be extracted into a standalone library.

file: src/catalog/range-prefix.ts ↗ | tags: #configuration #version-management

Provides pure functions for parsing package specifiers (e.g., `@scope/name@version`) and determining whether a version specifier should be kept verbatim (ranges, pins, protocols) or resolved against a registry. The logic correctly handles scoped packages, aliases, and edge cases like trailing `@`. This is a reusable building block for any tool that manipulates package dependency strings.

file: src/catalog/spec.ts ↗ | tags: #parsing #package-management

Implements `findClosestPackageJson` to walk up the directory tree for the nearest `package.json`, and `getPackageJSON` which parses JSON with support for comments and trailing commas (JSONC) as used by Bun. Falls back gracefully to plain JSON. The `withPackageRoot` helper adjusts the working directory to the package root. These functions are self-contained and solve a common need in Node.js tooling.

file: src/fs.ts ↗ | tags: #filesystem #json-parsing

Loads configuration from a `.nirc` file (INI format) and environment variables, with sensible defaults. It validates keys, suggests corrections for misspelled options, and warns about unrecognized settings. The layered override (defaults < file < environment) is a clean pattern that could be reused in other CLI tools. The `getConfig` function is async and caches the result.

file: src/config.ts ↗ | tags: #configuration #cli-framework

Contains `writeFileSafe`, which writes a file atomically by first writing to a temporary file in the same directory and then renaming. This avoids partial writes and race conditions. Also includes `cmdExists` (using the `which` library), `terminalLink` (OSC 8 hyperlinks), and `formatPackageWithUrl`. These are generic utilities that could be extracted into a shared library.

file: src/utils.ts ↗ | tags: #filesystem #concurrency
Last analyzed: 2026-10-16 18:25:34.833130
Next check: 2026-10-23 18:25:34.824981
$ submit: