CLI tool
ehmicky/nve avatar
ehmicky/nve

nve and the case for running one command on one Node version

Run any command on specific Node.js versions

714 stars12 forksJavaScriptApache-2.0

At a glance

What is it?
nve is a Node module that runs a single command against a chosen Node.js version, without touching your global binaries and without a shell script installer. Its pitch is speed, multiple versions at once, and working on Windows without Administrator rights, at the cost of being useless for switching an entire shell session.
Who is it for?
nve is a good fit for a CI matrix or a script that needs to prove a package works on several Node versions, because it can run 12, 10 and 8 in one invocation and does not need a version manager installed, and because it works on Windows without Administrator rights or Bash.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One command, one Node version, no side effects

nve runs any command on specific Node.js versions. The README is careful about the scope: nve executes a single file or command, and it does not change the node nor npm global binaries.

That last point is the whole design. The usual way to switch Node versions, whether with nvm, nvm-windows, n or nvs, changes the environment of your shell, and that is what you want when you are working on one project for an afternoon. nve is aimed at the other case, where you want to run one thing under a particular version and then get your environment back.

For that case nve claims to beat the alternatives on several axes. It can run multiple Node.js versions at once, it can be run programmatically through the separate nvexeca package, it is described as much faster, it does not need a separate installation step for each Node version, it can run a major release's latest minor or patch version automatically, it works on Windows with no need to run as Administrator, it does not require Bash, and it installs as a Node module rather than as a Bash installation script downloaded with curl.

The Windows point is the one that usually decides it. A tool that needs no Administrator rights and no Bash can run on a corporate Windows machine, on a build agent, and inside a container image without a shell layer.

Version specifiers that mirror what you already write

The version argument accepts a range of forms, and they are the familiar ones. Any version range such as 12, 12.6.0 or a less-than form like a quoted less-than-12 is accepted, using semver semantics.

There are also four named specifiers. latest is the latest available Node version. lts is the latest LTS version. global is the global Node version, resolved from the home directory .nvmrc or from the package.json engines.node field, and it also searches similar files used by other Node.js version managers, falling back to the current process's Node version when nothing is found. local is the current directory's Node version, searched in the current directory and parent directories for the same set of files, defaulting to the global version when nothing is found. Finally, a file path pointing at a .nvmrc, a package.json or one of those similar files can be passed directly.

The local and global distinction is the part worth remembering, because it maps onto how Node projects are actually structured. A repository with an engines.node field is picked up by local, and the .nvmrc in your home directory is what global resolves to, so a CI machine with a personal .nvmrc and a project with its own engines field behave differently.

The examples show both working, with nve local npm test and nve global npm test as the two forms.

Multiple versions in one command

This is the feature that separates nve from a single-version switch, and the output format is designed to be readable in a log.

Running a command against several versions at once looks like this:

bash
# Run multiple versions
$ nve 12,10,8 npm test

The result is reported per version, with the version number, the test summary and the elapsed time shown separately for each. The default behaviour is to abort the remaining versions when one of them fails, which is what you want in a quick manual check.

Two flags change that. The --continue option, aliased -c, disables the abort so the others keep running, which is the sensible setting for a compatibility sweep where you want to see every failure, not just the first. The --parallel option, aliased -p, runs all versions at the same time.

The parallel option has stated limits, and they are the usual ones for concurrent process execution. It does not work if the command requires interactive CLI input, for example a prompt, and it does not work if the command is not concurrency-safe. That second condition is the one to check before trusting a green result.

There is also a caching angle. Running nve 12,10,8 node --version caches the Node downloads, so a later invocation does not re-download the binaries.

Options for mirror, cache and architecture

The options section is where the practical configuration lives, and three of them matter on a real network.

The --mirror option, aliased -m, sets the base URL used to retrieve the Node binaries and defaults to https://nodejs.org/dist. It can be pointed at a mirror such as https://npmmirror.com/mirrors/node, and the same thing can be done through the NODE_MIRROR, NVM_NODEJS_ORG_MIRROR, N_NODE_MIRROR or NODIST_NODE_MIRROR environment variables. On a network where nodejs.org is slow or blocked, this is the difference between a working tool and a hanging one.

The --fetch and --no-fetch options control the cached list of available Node.js versions. The list is fetched and cached, and by default a cached list is used unless it is more than an hour old. --fetch forces a fresh fetch, and --no-fetch always uses the cache even when it is older than an hour.

The --arch option selects the CPU architecture for the downloaded binaries, with x32 given as the example, which is how you get a 32-bit Node build on a 64-bit machine.

The --progress option controls the download progress bar and defaults to true, so it can be turned off for quieter CI output.

Install, usage syntax, and what nve will not do

Installation is a single global npm install:

bash
npm install -g nve

Node 18.18.0 or newer must be globally installed to run nve itself, but the command that nve runs can use any Node version, as long as that command is compatible with it. That last constraint is the compatibility rule to respect: npm is only compatible with Node 6 and later, for instance, so a test run on Node 4 is meaningless regardless of what nve does.

The usage syntax is nve followed by options, then one or more comma-separated versions, then the command and its arguments. It is exactly the same as running the command directly, but under the specified Node version. Both global and local binaries can be executed, so nve 8 ava runs a local ava binary under Node 8.

The alternative, for programmatic use from Node.js, is the separate nvexeca package, which is also listed as a runtime dependency of nve itself. The repository layout has a benchmark directory, which matches the README's claim to being much faster, plus a CHANGELOG.md and an ava.config.js for the test runner.

The one thing nve explicitly refuses to do is switch a whole session. For running a specific Node.js version for an entire project or shell session, the README points you at nvm, nvm-windows, n or nvs instead.

Maintenance, licence and the shape of the dependency list

The repository is not archived and the last push was on 2026-10-13. The published versions are v18.0.3 from 2025-06-03, v18.0.2 from 2025-03-29 and v18.0.1 from 2024-06-21. The version number of the package tracks the Node major it targets, which makes reading the changelog a matter of looking at which Node release an npm install will expect.

The licence is Apache-2.0, and the package.json says so directly. No legal advice is offered here beyond naming the identifier.

The dependency list explains the design. The process execution is delegated to execa, argument parsing to yargs, version range handling to semver, and terminal colours to chalk with figures for symbols. Two dependencies carry the version-resolution logic: node-version-alias for turning a specifier like 8 into a concrete version, and preferred-node-version for the .nvmrc and package.json lookup behind the global and local specifiers. nvexeca is a dependency too, since the programmatic API is a separate package that nve uses internally.

update-notifier is also in the list, which means the tool checks for a newer version of itself. That is convenient, and it is worth knowing about if you run nve in a locked-down environment where an outbound request to a version check endpoint is not welcome.

The build is a plain src directory compiled to build/src, with the binary entry point at build/src/bin.js, and the test script runs through gulp.

Editorial conclusion

nve is a good fit for a CI matrix or a script that needs to prove a package works on several Node versions, because it can run 12, 10 and 8 in one invocation and does not need a version manager installed, and because it works on Windows without Administrator rights or Bash. It is the wrong tool for changing the Node version of your whole shell or project, since nve executes a single file or command and leaves the global node and npm binaries alone, and it is the wrong tool if you need Administrator-level installation. Before adopting, confirm that the command you intend to run is compatible with the oldest Node version you plan to test, since npm itself is only compatible with Node 6 and later, and check whether the command is concurrency-safe before using the parallel flag.

Frequently asked questions

How do I install nve?

Run npm install -g nve. Node 18.18.0 or newer must be globally installed for nve itself, although the command nve runs can use any Node version that the command is compatible with.

What is the difference between nve and nvm?

nve executes a single file or command under a chosen Node version and does not change the global node or npm binaries. To run a specific Node version for an entire project or shell session, the README points to nvm, nvm-windows, n or nvs instead.

Can nve run a command against several Node versions at once?

Yes. Several comma-separated versions can be given, for example nve 12,10,8 npm test. By default the other versions are aborted when one fails, which the --continue flag disables, and the --parallel flag runs them at the same time, which does not work for commands needing interactive input or that are not concurrency-safe.

How do I use a different mirror for the Node.js downloads?

Pass the --mirror option with a base URL such as https://npmmirror.com/mirrors/node, or set the NODE_MIRROR, NVM_NODEJS_ORG_MIRROR, N_NODE_MIRROR or NODIST_NODE_MIRROR environment variables. The default is https://nodejs.org/dist.

Official sources

  1. ehmicky/nve on GitHub
  2. Issues
  3. License: Apache-2.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/ehmicky-nve.svg)](https://hysenlabs.com/projects/ehmicky-nve)

Was this useful?