A fast, interactive TUI for running npm scripts.
Note: This project was created using Claude Code and AI tools. I am not a Rust expert, and most of the code was generated by AI. Bugs, errors, and unexpected behavior are likely. Contributions, bug reports, and PRs are welcome! If you are sensitive to AI-generated code, please use with caution.
- Fast - Sub-50ms startup time (native Rust binary)
- Interactive - Beautiful TUI with fuzzy search and keyboard navigation
- Smart - Auto-detects your package manager (npm, yarn, pnpm, bun)
- Powerful - Multi-select, history tracking, script descriptions
- Zero-config - Works out of the box, optional config for power users
# Run in any Node.js project
cd your-project
nrsUse arrow keys to navigate, Enter to run, or press 1-9 for quick selection.
brew install tx2z/tap/npm-run-scriptscargo install npm-run-scriptscargo install --git https://github.com/tx2z/nrsGenerate shell completions for your shell:
# Bash
nrs --completions bash > ~/.local/share/bash-completion/completions/nrs
# Zsh
nrs --completions zsh > ~/.zfunc/_nrs
# Fish
nrs --completions fish > ~/.config/fish/completions/nrs.fish# Launch interactive TUI
nrs
# Launch TUI for specific project
nrs ./my-project
# List scripts without TUI
nrs --list
# Run a specific script directly
nrs -n dev
# Rerun last executed script
nrs --last
# Run script with arguments
nrs -n test --args "--watch --coverage"
# Dry run (show command without executing)
nrs -n build --dry-runnrs [OPTIONS] [PATH]
ARGUMENTS:
[PATH] Path to project directory (default: current directory)
OPTIONS:
-h, --help Show help message
-V, --version Show version
-L, --last Rerun last executed script
-l, --list List scripts non-interactively
-n, --script <NAME> Run script directly without TUI
-a, --args <ARGS> Arguments to pass to the script
-e, --exclude <PATTERN> Exclude scripts matching pattern (repeatable)
-s, --sort <MODE> Sort mode: recent, alpha, category
-r, --runner <RUNNER> Override package manager: npm, yarn, pnpm, bun
-d, --dry-run Show command without executing
-c, --config <PATH> Path to config file
--no-config Ignore config files
--debug Enable debug output
--completions <SHELL> Generate shell completions
| Key | Action |
|---|---|
↑ / k |
Move up |
↓ / j |
Move down |
← / h |
Move left |
→ / l |
Move right |
g / Home |
Go to first |
G / End |
Go to last |
| Key | Action |
|---|---|
Enter |
Run selected script |
1-9 |
Quick run numbered script |
a |
Add arguments |
m |
Toggle multi-select |
Space |
Toggle selection (multi-select) |
| Key | Action |
|---|---|
/ or type |
Enter filter mode |
Escape |
Clear filter |
s |
Cycle sort mode |
| Key | Action |
|---|---|
q / Ctrl+C |
Quit |
? |
Show help |
nrs works without configuration, but you can customize it with a config file.
.nrsrc.tomlin project directory~/.config/nrs/config.toml(global)
# ~/.config/nrs/config.toml
[general]
# Default package manager (overrides auto-detection)
runner = "pnpm"
# Default sort mode: "recent", "alpha", "category"
default_sort = "recent"
# Show command preview in description panel
show_command_preview = true
[appearance]
# Show icons
icons = true
# Show help footer
show_footer = true
# Compact mode (less padding)
compact = false
[filter]
# Search in descriptions too
search_descriptions = true
# Enable fuzzy matching
fuzzy = true
[history]
# Enable history tracking
enabled = true
# Max projects to remember
max_projects = 100
# Max scripts per project
max_scripts = 50
[exclude]
# Global patterns to exclude
patterns = [
"pre*",
"post*",
]
[scripts]
# Custom descriptions (override package.json)
[scripts.descriptions]
dev = "Start development server"
build = "Build for production"
# Script aliases
[scripts.aliases]
d = "dev"
b = "build"
t = "test"Create .nrsrc.toml in your project root:
[general]
runner = "yarn"
[exclude]
patterns = ["internal:*"]nrs automatically detects your package manager:
--runnerCLI flag (highest priority)runnerin config filepackageManagerfield inpackage.json- Lock file detection:
bun.lockb→ bunpnpm-lock.yaml→ pnpmyarn.lock→ yarnpackage-lock.json→ npm
- Fallback: npm
nrs reads script descriptions from multiple sources:
{
"scripts": {
"dev": "vite",
"build": "vite build"
},
"scripts-info": {
"dev": "Start development server",
"build": "Build for production"
}
}{
"scripts": { "dev": "vite" },
"ntl": {
"descriptions": {
"dev": "Start development server"
}
}
}{
"scripts": {
"//dev": "Start development server",
"dev": "vite"
}
}| Feature | nrs | ntl |
|---|---|---|
| Language | Rust | Node.js |
| Startup time | ~30ms | ~300ms |
| Binary | Yes | No (requires Node) |
| Fuzzy search | Yes | Yes |
| Multi-select | Yes | Yes |
| History | Yes | Yes |
| Configuration | Full TOML | Limited |
| Package managers | npm, yarn, pnpm, bun | npm, yarn, pnpm |
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | General error |
| 2 | No package.json found |
| 3 | No scripts defined |
| 4 | Script execution failed |
| 5 | Invalid configuration |
| 130 | Interrupted (Ctrl+C) |
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
# Clone the repository
git clone https://github.com/tx2z/nrs
cd nrs
# Run tests
cargo test
# Run with debug output
cargo run -- --debug
# Build release
cargo build --releaseMIT License - see LICENSE for details.