Technical Documentation: coreybutler/nvm-windows
βΉοΈ Provenance: Multi-Tier Ingestion Β· CodeWiki Reference
Overview (`README.md`)
NVM for Windows
The Microsoft/Google recommended Node.js version manager for millions of Windows developers.
[!IMPORTANT]
You may already have NVM for Windows. Microsoft Zenith preconfigures NVM, starting with AMD Ryzen AI Halo devices. More devices from OEM and silicon partners will be available in the coming months.
NVM for Windows is not the same thing as nvm! (expand for details)
The original nvm is a completely separate project for Mac/Linux only. This project uses an entirely different philosophy and is not just a clone of nvm.
| π Version 2 is available
NVM for Windows has been fully rewritten for modern workflows.
Explore whatβs new β |
| --- |
| π’ Introducing Certified Builds
Deploy NVM for Windows in controlled environments with commercial Certified Builds and optional add-ons:
**IT-managed deployment** with MSI and Intune
**Centralized policy enforcement**
**Auditable operations** with advanced logging
**Supply-chain confidence** with verifiable trust artifacts
**[Explore Certified Builds β](https://nvm-windows.com/certified)** |Resources
Features
[!IMPORTANT]
Community Edition installers are now code-signed as of v2.0.0-hotfix.2.
| Feature | Description |
|---|---|
| Compatibility | • No mandatory administrator privileges.• Shim mode - no symlinks, fast (written in Zig).• Link mode - Zero-latency, junctions with symlink fallback. |
| Automation | • Per-directory version switching (pinning).• Auto-install missing versions.• Auto-install default global modules. |
| Speed | • Parallel (multiple) simultaneous installations.• Smaller downloads (7z).• Native extraction.• Caching. |
| Native Integrations | • Windows Apps• Logging (Windows Event Viewer)• Windows Registry• Desktop Notification Center |
| Customization | • User-defined aliases.• User-defined default global modules.• Configure local (air-gapped) downloads. |
Certified Builds
Commercial Certified Builds are now available for controlled environments. Learn more.
Not sure which edition is right for you? See Choosing a Build.
| Feature | Description |
|---|---|
| IT-Managed Installation | • Windows-protected installation directory• Administrator-controlled deployment and device management |
| Installers | • MSI/MST• Microsoft Intune |
| Advanced Logging β | • Fully auditable• Structured• Dedicated Event Source• Native SIEM integration |
| Policy Enforcement β | • Active Directory/Entra integration• Restrict Node.js versions/ranges (e.g. no EOL versions, LTS only, etc.)• Control nvm-windows, Node/npm/npx settings• Advanced proxy (IWA, WPAD/PAC) support• Private Node.js download mirror |
| Trust Artifacts β | • SBOM• SLSA Provenance• VEX Reports |
β = Add-on package
:pray: Thanks
Thanks to everyone who has submitted issues on and off GitHub, made suggestions, and generally helped make this a better project. Special thanks and the full contributor list is available here.
Overview (`build/README.md`)
Community build
Authenticode-signed Inno Setup pipeline for NVM for Windows (core / community). No COSE worker signing, no SBOM, no SLSA, no ADMX, no MSI/Intune.
Produces nvm.exe, ETW event provider assets (NVMWindows.Events.man + NVMWindows.Events.dll), shims (node / proxy / reshim), sync.exe, and one Inno Setup .exe. Sync worker DLLs come from the certified release CDN (assets.nvm-windows.com) β this build does not compile them (CDN workers are already COSE Sign1'd by the certified pipeline).
NVMWindows.Events.dll is a wevtutil message/resource DLL (/NOENTRY). It is Authenticode-signed with product .exe/.msi artifacts (same Artifact Signing account). It is not COSE-signed (COSE is for sync workers only).
The sync Git submodule is private. Maintainers/CI compile it from source. Public from-source builds use -DownloadSync to fetch the matching release asset.
Local
Requires: Go (see cli/src/go.mod), qgo, Zig (shim/.zigversion), Inno Setup 6.7.1+, go-winres.
# Maintainer / CI (sync submodule present)
.\build\main.ps1
.\build\main.ps1 -Architecture amd64
.\build\main.ps1 -Architecture arm64 -SkipInstaller
.\build\main.ps1 -Component Cli
.\build\main.ps1 -Hotfix beta.1
.\build\main.ps1 -Hotfix 2
.\build\main.ps1 -Version 2.0.1-hotfix.2
# Public clone (no sync source): download prebuilt sync.exe from the GitHub Release
.\build\main.ps1 -DownloadSync
.\build\main.ps1 -DownloadSync -SyncReleaseTag v2.0.0
.\build\main.ps1 -Component Sync -DownloadSync.\build.ps1 still forwards to .\build\main.ps1.
| Flag | Purpose |
|---|---|
-Hotfix |
Same as GHA prerelease: any stamp β {manifest}-{stamp} (e.g. beta.1 β 2.0.1-beta.1). Bare digit 1 β -hotfix.1 (WiX/Inno revision). Temp-stamps cli/src/manifest.json for qgo embed, sets process NVM_CLI_VERSION, restores both after build (git stays clean). Mutually exclusive with -Version. |
-Version |
Full special version override (e.g. 2.0.1-beta.1). Same temp stamp/restore as -Hotfix. Mutually exclusive with -Hotfix. |
-DownloadSync |
Fetch nvm-<version>-<x64|arm64>-sync.exe from GitHub Releases instead of compiling sync |
-SyncReleaseTag |
Override release tag (default: v + cli/src/manifest.json version) |
-SyncReleaseRepo |
Override owner/repo (default: nvm-windows/nvm) |
Output:
- Executables β
bin\ - Event provider β
bin\NVMWindows.Events.man,bin\NVMWindows.Events.dll(shipped next tonvm.exein the installer) - Installer β
.dist\nvm-<version>-<x64|arm64>-setup.exe(-Architecture amd64writesx64) - Staged sync release asset β
.dist\nvm-<version>-<x64|arm64>-sync.exe
Requires Windows SDK (mc.exe / rc.exe) and Visual Studio link.exe for the event resource DLL.
GHA
Workflow: Release Community Build (workflow_dispatch).
| Input | Default | Purpose |
|---|---|---|
architecture |
both |
amd64, arm64, or both |
publish_release |
true | Draft β upload assets β publish |
override_existing_release |
false | Replace setup.exe and sync.exe on existing tag |
release_kind |
General |
Release Type. General publishes the manifest version. alpha, beta, and rc prerelease that manifest version. hotfix patches a prior general release. The workflow assigns the next number. |
hotfix_base |
(empty) | Hotfix Mainline. Specify the general release to apply the hotfix to, for example 2.0.1. Leave empty to use the latest general release. Ignored unless Release Type is hotfix. |
GitHub Release assets per architecture:
nvm-<version>-x64-setup.exeandnvm-<version>-arm64-setup.exeβ Inno Setup installersnvm-<version>-x64-sync.exeandnvm-<version>-arm64-sync.exeβ prebuilt sync for-DownloadSync
Tag = v + effective version. General uses cli/src/manifest.json (2.0.2). alpha, beta, and rc use that manifest plus the kind and the next unused number (2.0.2-beta.3 already published means the next beta is 2.0.2-beta.4). hotfix uses the Hotfix Mainline plus the next -hotfix.N (2.0.1-hotfix.2 already published means the next hotfix of 2.0.1 is 2.0.1-hotfix.3), not the current manifest. The runner patches the manifest before the CLI and Inno build so the embedded version and AppVersion match. Inno VersionInfoVersion maps the trailing -word.N to the fourth numeric field (2.0.1-hotfix.1 β 2.0.1.1). Any x.y.z-* release is marked GitHub --prerelease.
WinGet
Workflow: Publish to WinGet (workflow_dispatch).
Use it only after a public GitHub Release has both x64 and arm64 setup assets. It:
- Downloads release installers.
- Generates
AuthorSoftware.NVMWindowsmanifests and SHA256 values. - Verifies anonymous public release URLs produce matching hashes.
- Runs
winget validate. - By default, runs a silent install smoke test from the downloaded x64 setup asset, runs
nvm --version, then uninstalls. - Uploads the generated manifests as a workflow artifact.
- When
dry_runis false, opens a pull request fromnvm-windows/winget-pkgsthat addsAuthorSoftware.NVMWindows. The first submission is a new package. Later runs add a version. This does not updateCoreyButler.NVMforWindows.
dry_run defaults to true (validate only). Live submit needs secret WINGET_CREATE_GITHUB_TOKEN (classic PAT with public_repo and workflow for a user who can push nvm-windows/winget-pkgs). The workflow scope is required because syncing that fork fast-forwards Microsoft's Actions workflow changes.
Inputs:
| Input | Default | Purpose |
|---|---|---|
release |
latest |
latest = newest stable GitHub Release (no drafts/pre-releases). custom = use release_tag. |
release_tag |
empty | Tag for custom (e.g. v2.0.0-alpha.2). Ignored when release=latest. |
dry_run |
true | On: generate manifest, winget validate, upload artifact β no PR. Off: open a microsoft/winget-pkgs pull request from nvm-windows/winget-pkgs for AuthorSoftware.NVMWindows. |
install_test |
true | Silent install smoke test via local release-assets installer (not winget install). 4 min process timeout + 5 min step cap. Warns/skips on failure; never fails dry-run. |
verify_public_urls |
true | Anonymous GitHub release download + SHA256 must match manifest hashes. Fails workflow on mismatch (dry-run or publish). |
Secrets
| Name | Purpose |
|---|---|
GH_APP_CLIENT_ID |
GitHub App client ID (submodule checkout) |
GH_APP_PRIVATE_KEY |
App private key PEM |
WINGET_CREATE_GITHUB_TOKEN |
Classic PAT (public_repo and workflow) that can push nvm-windows/winget-pkgs when dry_run=false |
App install on nvm-windows must include nvm, cli, common, shim, sync (or all repos), Contents: Read. Inno Setup lives in-repo at installer/ (not a submodule). Release publish uses github.token (contents: write).
Immutable releases: published tag locks forever. Bump manifest version, or turn immutable off and set override_existing_release.
Overview (`installer/README.md`)
Installer
The installer requires InnoSetup 6.7.1 or above.
--- METRICS ---
- Files Extracted: 3
- Estimated Token Budget: ~3179 tokens
- Canonical Reference: https://codewiki.google/github.com/coreybutler/nvm-windows