You could either call novm
not a version manager, or, a very opinionated one. Read PS for my thoughts.
novm
does not ask for a version, it tries to detect one from known sources, installs, runs them. You don't manage a new binary, you just replace node
with this.
Only support linux and macos, see windows support.
Download as a node binary
curl -L https://github.com/debdutdeb/novm/releases/latest/download/novm-$(uname -s | tr '[[:upper:]]' '[[:lower:]]')-$(uname -m) -o ~/.local/bin/node && chmod +x ~/.local/bin/node
Or, as an npm binary
curl -L https://github.com/debdutdeb/novm/releases/latest/download/novm-$(uname -s | tr '[[:upper:]]' '[[:lower:]]')-$(uname -m) -o ~/.local/bin/npm && chmod +x ~/.local/bin/npm
Either way, once run the first time, it will link itself to the other binary automatically.
I highly recommend installing in a folder that doesn't require sudo. Else it'll try to install first version onto /root
as linking won't work otherwise.
Or, link manually before running either of the commands,
sudo ln -s $(which node) $(dirname $(which node))/npm
# or
sudo ln -s $(which npm) $(dirname $(which npm))/node
If at fresh install symlink fails, novm won't try again. This is to allow manual symlinking.
Make sure you add $HOME/.novm/bin
to your PATH
. More here.
As I said, opinionated. Updates are automatic. For example, check the output below
*[main][~/Documents/Repos/node-proxy]$ node
2024/05/06 00:59:07 no nodejs version detected from sources, using latest installed
Welcome to Node.js v21.7.3.
Type ".help" for more information.
> process.stdout.write("hello world")
hello worldtrue
>
2024/05/06 00:59:19 Updating novm to v1.3.0
I was on v1.2.x, and got automatically upgraded to current latest. Why? Because I don't want to be bothered to update yet another tool.
Currently the following sources are supported -
NODE_VERSION
environment variable.NP_NODE_VERSION
environment variable.engines.node
underpackage.json
volta.node
underpackage.json
.nvmrc
file
Contributions to more sources will be very much appreciated.
If there is no source, novm
will either run latest version found locally or install the latest version.
Just run as node or npm. That's all.
[/tmp/example]$ jq .engines package.json
{
"node": "~16"
}
[/tmp/example]$ node --version
[Node v16.20.2] [==========================================================================================================================================================================================] 100.00%v16.20.2
2024/05/06 01:04:05 no new novm updates found.
novm
installs the actual versions in $HOME/.novm/versions
folder.
All global installs go under $HOME/.novm/bin
folder.
It all depends on what you have in your source. If it is an exact version, obviously won't auto update. If you have a constraint, at some point, if a new patch matches the constraint, or a new minor matches, it will be installed automatically.
Use NOVM_WAKE=1
with node
or npm
call, to get novm
options.
[/tmp/example]$ NOVM_WAKE=1 node --help
Usage:
novm [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
help Help about any command
version
Flags:
-h, --help help for novm
Use "novm [command] --help" for more information about a command.
Check novm version
[/tmp/example]$ NOVM_WAKE=1 node version
Version: v1.3.0
GitCommit: cf13d8741fee6959d72dd8bae05cdb5750ca30e9
BuildTime: Mon May 6 00:47:46 IST 2024
Without NOVM_WAKE
, you'd be calling node itself.
[/tmp/example]$ node version
node:internal/modules/cjs/loader:1031
throw err;
^
Error: Cannot find module '/private/tmp/example/version'
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:1028:15)
at Function.Module._load (node:internal/modules/cjs/loader:873:27)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:22:47 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
2024/05/06 01:08:26 exit status 1
I wrote it precisely to not have to think about node versions. There is nvm
, n
, asdf
, volta
some of which (volta) I never touched. They may and do some of them, bring more than just managing node versions, but at the end of the day I get tooling-exhaustion. Specifically since I use so many node versions across different projects, whether work, personal playing, freelance projects, doesn't matter.
For example, at Rocket.Chat, the main repo uses node 14, another internal tool used to use node 12. So many times I forgot to make the switch. I have yet another of my own script that uses node 16. Sometimes versions are not a problem, sometimes they are, and I am tired to tracking them all the time.
There are solutions like oh-my-zsh's nvm plugin, but all of them (afaik, within my limited knowledge) are constrained to a single source, their own source ("use me" much?). There is even talk of I believe .voltarc
. I don't want it. Not right now at least. Not unless I must. Whatever project decides to use whatever version, I just want to use node as a simple binary without always thinking about switching, no matter what project I am in, or what folder.
So this is opinionated. And I want to keep it that way. There isn't much to configure, nor am I planning to add.
Please feel free to contribute. What brings more joy than that? Not many things in this world.
I don't have a windows machine with me. But will accept PRs.