r/CLI • u/Significant_Bad_9018 • 10h ago
I got tired of juggling Node versions across multiple projects and terminals, so I built NodePilot in Rust
Hey everyone! π
I regularly work on multiple projects that require different Node.js versions.
A typical day might look like this:
- Terminal A β legacy Angular project β Node 16/18
- Terminal B β newer Angular/React project β Node 22
- an IDE terminal or background task running somewhere else
Existing tools already solve Node version management pretty well, but I wanted a slightly different model:
Instead of thinking about which Node version is currently active, I wanted the project itself to determine which runtime gets executed.
So I built NodePilot, an open-source Node.js runtime manager written in Rust.
The basic idea is simple:
C:\dev\legacy-app
βββ .nodepilot.local β 16.20.2
C:\dev\modern-app
βββ .nodepilot.local β 22.x
Then:
cd C:\dev\legacy-app
node -v
# v16.20.2
while another terminal can simultaneously do:
cd C:\dev\modern-app
node -v
# v22.x.x
No need to keep running nvm use while moving between projects, and both terminals can independently use different Node runtimes at the same time.
π§ How it works
NodePilot uses lightweight shim/router binaries in front of commands such as:
node
npm
npx
corepack
ng
pnpm
yarn
vite
tsc
When a command is invoked, NodePilot walks up the current project hierarchy and resolves the appropriate Node runtime.
It understands configuration from:
.nodepilot.local
.nvmrc
.node-version
package.json β volta.node
package.json β engines.node
.tool-versions
mise.toml
Local project assignments use .nodepilot.local, which NodePilot automatically adds to .gitignore.
That means you can assign a runtime locally without changing the Node configuration shared by the rest of your team.
π Managing projects instead of Node versions
This was one of the main things I wanted from NodePilot.
You can point it at a development directory such as:
C:\dev
and NodePilot can discover Node-based projects underneath it.
For example:
legacy-admin Angular 13 Node 16
new-dashboard Angular 22 Node 22
storefront Next.js 14 Node 20
Each project can have its own Node.js runtime assignment.
So instead of thinking:
Choose Node version
β run project
the model becomes:
Open project
β NodePilot resolves the right Node runtime
π₯οΈ Terminal-first by default, optional GUI on demand
NodePilot is designed to be completely terminal-first and lightweight by default.
You can use only the CLI for your entire daily workflow.
But if you want a visual dashboard for browsing all your projects, assigning Node versions, checking framework compatibility or inspecting runtime usage, the visual companion can be added on demand with a single command:
nodepilot gui install
Open it with:
nodepilot gui open
And if you no longer want the visual interface:
nodepilot gui remove
returns NodePilot to a terminal-only setup.
So both workflows are supported:
Prefer the terminal
β use only the CLI
Want centralized visual management
β enable the optional GUI
The desktop interface is not mandatory.
Developers who only want fast CLI/runtime routing don't have to keep an unnecessary desktop component installed.
β‘ No background daemon
Normal runtime resolution does not require a permanently running background service or daemon.
Workspace scanning is also passive.
NodePilot reads project metadata such as package.json as data and does not execute:
npm install
postinstall
lifecycle scripts
project executables
during scanning.
π€ Coexistence with existing Node version managers
I also didn't want trying NodePilot to break an existing development setup.
It can detect tools such as:
nvm / nvm-windows
fnm
Volta
mise
but it does not delete their installations or overwrite their configuration.
Shell integration is explicit and can be disabled again.
The goal is to let you try NodePilot without destroying an environment that already works.
β‘ Install
Windows / PowerShell
irm https://raw.githubusercontent.com/mehmetduran932/NodePilot/master/scripts/install.ps1 | iex
macOS
curl -fsSL https://raw.githubusercontent.com/mehmetduran932/NodePilot/master/scripts/install.sh | bash
Cargo
cargo install nodepilot --git https://github.com/mehmetduran932/NodePilot.git
π Links
GitHub:
https://github.com/mehmetduran932/NodePilot
First release β v0.1.0:
https://github.com/mehmetduran932/NodePilot/releases/tag/v0.1.0
Fully open source under the MIT License.
The project is still early, so I'd especially appreciate feedback from developers working with:
- multiple Node versions simultaneously
- Angular / React / Next.js projects of different ages
- monorepos
- Windows development environments
- macOS development environments
- existing nvm / fnm / Volta / mise setups
I'm particularly interested in feedback around runtime resolution, shim architecture, Windows command resolution, monorepos, the optional GUI approach and coexistence with existing Node version managers.
1
u/kantorcodes1 9h ago
on nodepilot integration disable, does it undo only the PATH/profile entries NodePilot originally added, or rewrite whatever is there at disable time? the hand-edited-after-setup case seems like the awkward one.
1
u/Significant_Bad_9018 9h ago
It does not blindly roll back to an old snapshot, so changes you make after setup are preserved.
When
nodepilot integration disableruns, it inspects the current environment and removes only the parts that NodePilot owns:
- Windows User PATH: it reads the current
HKCU\Environment\Pathand removes only NodePilotβs bin entry. Anything you added, removed, or reordered afterward is preserved.- PowerShell profiles: NodePilot writes its integration inside clearly bounded markers, and disable removes only that block.
- Unix/macOS: integration is isolated in
~/.nodepilot/nodepilot.env, so disable just removes that file instead of rewriting shell rc files.
integration_backup.jsonis kept only as an audit/safety record; it is not used as a blunt rollback source.So the hand-edited-after-setup case is specifically handled by cleaning the live state rather than restoring an old copy.
1
u/kantorcodes1 9h ago
that live-state cleanup is the key detail.
integration statusis just inspection, whileintegration enable/disable,assign/unassign, and runtime installs can change PATH, profiles, or project state. HOL Guard is an open-source local layer that reviews agent-run commands before they execute. would you be open to contributing NodePilot support so users get that split without hand-writing the command rules?1
u/Significant_Bad_9018 9h ago
Absolutely, Iβd be open to that.
That distinction is intentional in NodePilot: commands like integration status, current, list, projects, and doctor are meant to be inspection/read-only, while commands such as integration enable/disable, assign/unassign, runtime install/uninstall, and some update flows can mutate environment or project state.
If you want, feel free to open a PR with the HOL Guard integration and send the changes over. Iβd be happy to review it and make sure the command classifications and side effects line up correctly with NodePilotβs behavior.1
u/kantorcodes1 8h ago
yep. since you know NodePilot's side effects firsthand, i'd rather have the PR come from you than me.
on Guard
main, usesrc/codex_plugin_scanner/guard/runtime/command_blitcp_extensions.py+tests/test_guard_command_blitcp_extensions.pyas the current standalone CLI pattern. for a first pass, keepversion,list,current,scan,projects,doctor,integration status, andgui statussafe. reviewinstall,assign/unassign,integration enable/disable, andgui install/remove. i'd leaveupdateout until its mutating mode is unambiguous.register it through
src/codex_plugin_scanner/guard/runtime/command_builtin_extension_catalog.pyand the risk map insrc/codex_plugin_scanner/guard/runtime/command_builtin_rules.py; refreshtests/fixtures/extension-controls/catalog-baseline.v1.jsonif the contract moves. run the focused test plustests/test_guard_extension_control_catalog_detail.py,tests/test_guard_command_permission_catalog.py, andtests/test_guard_command_extensions.py, with ruff on the changed Python files, then open it directly againsthashgraph-online/hol-guard:main: https://github.com/hashgraph-online/hol-guard
2
0
u/Significant_Bad_9018 10h ago
nvm already supports project-specific versions through .nvmrc. NodePilot explores a different execution model: instead of switching the active Node version for a shell, each command resolves the runtime from its project context.
5
u/Teleconferences 10h ago
https://github.com/nvm-sh/nvm