---
# System prepended metadata

title: '`node` versioning w/ `npm`'

---

# `node` versioning w/ `npm` 

## Goals & Action Items
- globally installed package binarys have some safe-guards/reasonable way to determine which one wins when there's duplicate names
- [x] help transfer `node` package/namespace on `npmjs.com` to the Node.js Project
- [x] ask Node.js Project to begin distributing releases on `npmjs.com` using dist-tags as mutable references for things like `LTS` versions
  - benefit: support policies, version management & updates come out-of-the-box with the `npm` CLI or any other tool/package manager that interfaces with `npmjs.com` (not really different then using canonical git tags/releases on `github.com` or hosting distributions on `nodejs.org` - these can continue to exist)
- there should be no need for third-party tools (ie. `npm` comes with `node`, you should be able to use _that_ to update/upgrade your system `node` without the need for a third-party tool)
- [x] remove references to node version managers in `npm/cli`'s `README.md`
- [ ] add reference to upgrading/updating `node` using `npm` in `npm/cli` `README.md`
- [x] investigate `nvm` & missing features of `npm i node`
  - https://github.com/nvm-sh/nvm#migrating-global-packages-while-installing `nvm install node --reinstall-packages-from=node`
- [x] investigate `volta` & whether it is doing something unkosher license-wise (re. similar to `corepack`)
- [x] make `npm i node -g -f && npm outdated -g` work (currentlty fails because of expected paths not existing)

## Example Use Cases & Usage

### Install & Manage `node` System-wide

```bash=
npm i node -g
npm i node@14 -g
npm i node@19 -g
```

> Note: this currently requires the `--force` flag to install `node` if you already have it installed to overwrite the `bin`

### Execute `node` in an individual process

```bash=
npx node@14 -e "console.log(process.version)"
```

### Check for outdated `node` version

```bash=
npm outdated -g

Package  Current  Wanted  Latest  Location           Depended by
node     10.0.1   10.9.2  19.0.1  node_modules/node  global
```

> Note: this currently fails after `npm i node -g` since there are paths we expect to exist, that don't, under `{prefix}/lib/node_modules`

### Updating `node` to a specific version

```bash=
npm update node@19 -g
```

### Project-specific

```bash=
npm i node
```
```json=
// package.json
{
    "dependencies": {
        "node": "*"
    },
    "engines": {
        "node": ">=14"
    }
}
```

### Set Project-specific `node` versions with `engines`

```bash=
npm pkg set engines.node="^14.17.0||^16.13.0||>=18.0.0"
```

### Enforce `node` specific versions

```bash=
# command specific
npm install --engines-strict
npm ci --engines-strict
# project-specific config
npm config set engines-strict=true --location=project
# user-specific config
npm config set engines-strict=true --location=user
# global config
npm config set engines-strict=true -g
```

### Add Net-new Config for Maintaining Packages across Version Updates

`node` & `npm` become unique package names where we are able to provide unique flags/context when doing an `install` or `update`.

```bash=
npm i node@14 -g -f -k
# -k | --keep-installed-packages 
# maybe `--keep-installed-packages=node@12` to allow only copying/reinstalling deps from a previous spec of node
```

> Note: consider 

> Note: switching `npm` or `node` bins may loose context of previously installed packages; adding this flag should resolve this use-case of retaining packages across these package versions at the system-level

> Note: two (or more?) types of node installations:
> - "main" node - the version that all your globally installed packages are linked
> - "test/project" nodes - the versions that are used on specific projects. when those are installed as set as the primary `node`, you should not lose access to your globally installed packages. those should be callable and will use the "main" node

### Net-new Global Manifest & Improved Linking

#### `npm link`

```bash=
# current:
cd ./pkg && npm link . && cd ../project && npm link <pkg> 

# future: interfaces with the global `package.json`
npm link <get|set|list>
npm link set <name>=<path>

npm link set lodash=.
npm link <path> # is equivalent to...
npm link <pkg>=<path>

npm link ls # returns all project deps that are symlinked
npm link ls -g # returns all globally available links
npm link get <pkg> # returns path to project linked package
npm link get <pkg> -g # returns path to globally linked package
```

#### Global `package.json`

```json=
// {global prefix}package.json
{
  "linkedDependencies": {
    "node": ["json", "diff-so-fancy"],
  },
  "dependencies": {
    "json": "*",
    "diff-so-fancy": "^3.0.0",
    "node-19": "npm:node@19",
    "node-18": "npm:node@18",
    "node-12": "npm:node@12",
    "node-current": "npm:node@current",
    "node": "node@lts"
  },
  "node": "12"
}
```

```
npm update|install node -g
# will update and save `json` and `diff-so-fancy` (if necessary?) and update global/package.json
# due to them being listed in linkedDependencies#node
```

**Questions**

- how does the name of a bin on disk get inferred when multiple packages have the name and bin?
    - eg, `node`

**Global + Project Example**
```json=
// root/package.json
{
  "dependencies": {
    "json": "1"
  }
}
```

```json=
// root/project/package.json
{
  "dependencies": {
    "json": "2"
  },
  "scripts": {
    "run-json": "json"
  }
}
```

```sh=
cd /root
json --version # 1.0.0
cd /root/project
npm run run-json -- --version # 2.0.0
json --version # 1.0.0
npx json --version # 2.0.0
cd /root
npx json --version # 1.0.0
```

### Net-new Command to manage `PATH`

```bash=
npm path <get|set|list>
```

> Note: this is a global operation by default (aka. `--global=true`)

## Questions
- how to manage multiple installed versions and have one aliases to `node`?
  - `--install-strategy=linked -g` could create a global store where multiple versions of `node` can co-exist (_hypothetically_)
- how to ensure compatability between other globally installed npm packages and npm installed version of node?

## Links & References
- Add `node` version checker to core: https://github.com/nodejs/node/issues/44942
- `node` package: https://www.npmjs.com/package/node
