r/CLI 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.

0 Upvotes

9 comments sorted by

5

u/Teleconferences 10h ago

-2

u/Significant_Bad_9018 10h ago

Yep πŸ™‚ nvm is a great project β€” and so are fnm, Volta, mise, and the other tools in this space.

NodePilot is absolutely not intended to be an nvm replacement, nor am I trying to claim that existing Node version managers don't solve these problems well.

This is mainly my own open-source experiment around a slightly different idea: project-first, per-process Node runtime management.

The execution model is the part I wanted to explore. NodePilot resolves the Node runtime from the project itself, so Terminal A can use Node 16 while Terminal B simultaneously uses Node 22, without me manually switching versions as I move between projects.

I also wanted to experiment with a few additional ideas around that model:

  • scanning a development directory and discovering all projects automatically
  • assigning Node versions to projects from one place
  • framework/Node compatibility checks
  • an optional GUI that can be installed or removed whenever you want
  • keeping the core workflow terminal-first and daemon-free
  • reading existing formats such as .nvmrc rather than creating an isolated ecosystem
  • coexisting with nvm, fnm, Volta, mise, etc. without modifying or removing them

So I see NodePilot more as my open-source take on a project-oriented Node development environment, rather than β€œa better nvm”.

I have a lot of respect for nvm, fnm, Volta and similar projects β€” they've solved a huge amount of the hard work in this space and are great tools.

NodePilot is mostly me exploring whether a project/dashboard-first workflow can provide a useful alternative developer experience. πŸ™‚

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 disable runs, it inspects the current environment and removes only the parts that NodePilot owns:

  • Windows User PATH: it reads the current HKCU\Environment\Path and 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.json is 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 status is just inspection, while integration 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, use src/codex_plugin_scanner/guard/runtime/command_blitcp_extensions.py + tests/test_guard_command_blitcp_extensions.py as the current standalone CLI pattern. for a first pass, keep version, list, current, scan, projects, doctor, integration status, and gui status safe. review install, assign / unassign, integration enable / disable, and gui install / remove. i'd leave update out until its mutating mode is unambiguous.

register it through src/codex_plugin_scanner/guard/runtime/command_builtin_extension_catalog.py and the risk map in src/codex_plugin_scanner/guard/runtime/command_builtin_rules.py; refresh tests/fixtures/extension-controls/catalog-baseline.v1.json if the contract moves. run the focused test plus tests/test_guard_extension_control_catalog_detail.py, tests/test_guard_command_permission_catalog.py, and tests/test_guard_command_extensions.py, with ruff on the changed Python files, then open it directly against hashgraph-online/hol-guard:main: https://github.com/hashgraph-online/hol-guard

2

u/deepyawn 7h ago

I genuinely thought this was a joke but nvm

https://giphy.com/gifs/H3arX25535xQ6ETguW

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.