npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

nx-selector-cli

v1.0.0

Published

Target-agnostic interactive runner for Nx monorepos. Personal labels, fuzzy selection, streaming output.

Downloads

30

Readme

nxs

Target-agnostic interactive runner for Nx monorepos.

Pick projects with a fuzzy-searchable, grouped checkbox UI — or save them under personal labels and run them with two words. Works with any Nx target (serve, build, test, lint, e2e, storybook, anything), in any workspace, with configuration stored per user — never inside the repository.

nxs serve                 # interactive selector, "default" label pre-checked
nxs serve backend         # nx run-many -t serve --projects=<backend projects>
nxs build frontend        # any target works
nxs test default
nxs set backend           # pick projects, save the label
nxs list                  # show your labels

Install

pnpm install
pnpm build
pnpm add -g .   # exposes `nxs` (and the legacy `nx-serve` shim)

If pnpm complains that its global bin directory is not in PATH, run pnpm setup once and open a new terminal (or source ~/.bashrc).

Requires Node ≥ 18.17 and an nx binary reachable from the workspace.

Why labels live in your config, not the repo

The old nx-serve.json lived in the workspace root: it polluted repositories and forced every developer to share one selection. nxs stores everything in a user-level file keyed by workspace path, so each developer keeps their own labels per repository:

| Platform | Config location | |---|---| | Linux | ~/.config/nxs/config.json (or $XDG_CONFIG_HOME/nxs; fallback ~/.cache/nxs) | | macOS | ~/Library/Application Support/nxs/config.json | | Windows | %APPDATA%\nxs\config.json |

Override with NXS_CONFIG_DIR / NXS_CACHE_DIR.

{
  "version": 1,
  "workspaces": {
    "/home/user/projects/alpha": {
      "labels": {
        "backend": ["identity-server", "project-service", "audit-service"],
        "frontend": ["portal-ui", "workflow-ui"],
        "default": ["portal-ui", "identity-server"]
      },
      "recent": ["portal-ui", "identity-server"],
      "lastRun": { "serve": ["portal-ui"] }
    }
  }
}

Commands

Run any target

nxs <target> [labels...] [options] [-- nx-args...]
nxs serve                        # interactive picker
nxs serve backend                # one label
nxs serve backend frontend       # merge multiple labels
nxs e2e default                  # "default" is just a label
nxs storybook                    # any target a project defines
nxs test --projects=a,b,c        # explicit projects, no label needed
nxs serve --changed              # only affected projects (nx affected)
nxs serve --last                 # re-run the last selection for this target
nxs serve --no-cache             # refresh the project graph first
nxs serve backend --parallel=4   # explicit nx parallelism
nxs build backend -- --verbose --configuration=production   # forwarded to nx

The target is validated against the workspace before anything runs; selections are automatically filtered to projects that actually define the target (with a warning for anything skipped).

Manage labels

Labels are dynamic — nothing is hardcoded:

nxs set backend        # checkbox picker, saves under "backend"
nxs set api
nxs set scheduler
nxs set default        # the label preselected by bare `nxs <target>`
nxs list               # backend, default, frontend, ...
nxs remove backend
nxs rename backend api
nxs config             # pretty-print this workspace's config + recents + last runs

The selector

Select projects to serve
↑↓ move · space toggle · ←→ fold · a all · n none · i invert · type to search · enter run
search: (type to filter)
❯ [~] ▾ Recent (2)
    [x] portal-ui
    [ ] identity-server
  [ ] ▸ apps/ (4)
  [~] ▾ services/ (3)
    [x] identity-server
    [ ] project-service
    [ ] audit-service
2 selected
  • Auto-grouping by top-level folder (apps/, libs/, services/, …), with a Recent section on top built from your execution history.
  • Collapsible groups: folds, expands.
  • Group selection: space on a group row toggles all of its (visible) children; [~] marks partial selection.
  • Bulk keys: a select all, n none, i invert — scoped to whatever is currently visible/filtered.
  • Fuzzy search: just type (identity, or scattered like idsrv) — filters instantly, best matches first. Need to search for a literal a/n/i? Press / first. esc clears.
  • enter runs, ctrl+c cancels.

Execution

Selections run through nx run-many via spawn with inherited stdio — output streams live, colors and interactive logs are preserved, and Ctrl+C / SIGTERM are forwarded to nx (the CLI mirrors nx's exit code). --parallel=N is a first-class option; when omitted it defaults to the number of selected projects (so serve runs everything at once).

Discovery & caching

Projects come from nx graph --file and are cached per workspace. The cache fingerprints nx.json, package.json, workspace.json, pnpm-workspace.yaml, and every project.json in the tree (path + mtime + size), so adding, removing, or editing a project invalidates it automatically. --no-cache forces a refresh.

Migrating from nx-serve

Automatic. The first time you run nxs in a workspace that still has an nx-serve.json (or nx-serve.config.json) and you have no labels there yet, it imports:

  • defaultProjects → label default
  • each groups entry → a lowercase label

…into your personal config and tells you the repo file can be deleted. Your existing labels are never overwritten.

The legacy nx-serve command keeps working as a deprecation shim:

| Old | Runs | |---|---| | nx-serve | nxs serve | | nx-serve --default | nxs serve default | | nx-serve --set-default | nxs set default | | nx-serve --clear-default | nxs remove default | | nx-serve --group=Apps | nxs serve apps | | nx-serve --groups=A,B | nxs serve a b |

Architecture

src/
 ├── cli/
 │    ├── parse.ts      argv → Command (any target, labels, flags, passthrough)
 │    ├── legacy.ts     nx-serve flag translation
 │    └── help.ts
 ├── commands/
 │    ├── run.ts        selection resolution + execution
 │    ├── set.ts  list.ts  remove.ts  rename.ts  config.ts
 │    └── context.ts    workspace root + store + one-time migration
 ├── nx/
 │    ├── discover.ts   nx graph → projects with all their targets
 │    ├── cache.ts      fingerprinted project-graph cache
 │    ├── targets.ts    target validation/filtering
 │    └── runner.ts     spawn-based streaming execution, signal forwarding
 ├── config/
 │    ├── paths.ts      platform-aware config/cache dirs
 │    ├── store.ts      user-level config load/normalize/atomic-save
 │    ├── workspace.ts  per-workspace store (labels, recents, lastRun)
 │    └── migrate.ts    nx-serve.json import
 ├── ui/
 │    ├── selector.ts   raw-mode TUI (rendering + keys)
 │    ├── model.ts      pure selection state (fully unit-tested)
 │    ├── groups.ts     auto-grouping + Recent
 │    ├── fuzzy.ts      fuzzy matcher
 │    └── ansi.ts
 └── index.ts           dispatch + exit codes

Zero runtime dependencies — the selector is built on node:readline raw mode.

Development

pnpm build        # tsc → dist/
pnpm dev          # tsc --watch
pnpm test         # vitest (70 tests across all modules)

Exit codes: 0 success/empty selection, 1 runtime failure (mirrors nx), 2 usage error, 130 cancelled.