# Pin Node version with nvm and .nvmrc - Status: accepted - Date: 2026-04-26 ## Context and Problem Statement Angular 18 requires Node.js `^18.19.1 || ^20.11.1`. The system Node version on a development machine may not meet this requirement, causing silent build failures or CLI errors. How should the required Node version be enforced? ## Considered Options - nvm with `.nvmrc` - System Node (no version management) - Other version managers (fnm, volta) ## Decision Outcome Chosen option: "nvm with `.nvmrc`", because it pins the version explicitly in the repository, is already in use on the development machine, and integrates directly with the Husky pre-commit hook. A `.nvmrc` file at the repository root pins Node to `20.19.6`. The Husky pre-commit hook explicitly calls `nvm use 20.19.6` before running tests to ensure the correct version is active in the hook's shell environment. ### Positive Consequences - Consistent Node version across all commands: dev server, build, tests, pre-commit hook. - `.nvmrc` documents the required Node version explicitly in the repository. ### Negative Consequences - Requires nvm. Developers using other version managers (fnm, volta) must align manually. ## Pros and Cons of the Options ### nvm with `.nvmrc` - Good, because explicit version pinning visible in the repository. - Good, because integrates with Husky hook via `nvm use`. - Bad, because tied to nvm — other version managers need manual alignment. ### System Node - Good, because no tooling required. - Bad, because version is not pinned — any system upgrade can silently break the build. ### Other version managers (fnm, volta) - Good, because faster and more ergonomic than nvm for some workflows. - Bad, because not the currently installed tool — switching would require migration. ## Links - The `package.json` `engines` field (`^18.19.1 || ^20.11.1`) provides a secondary signal for tooling that reads it.