WindowsPublished on May 27, 20268 min read

Install Node.js on Windows Server

This guide shows how to install Node.js on Windows Server with the MSI installer or winget, and how to manage several versions with nvm-windows, which winget can install too. It then covers deploying an app, running it as a Windows service at boot and opening the firewall. The commands target a OuiHeberg Windows VPS, delivered with Windows Server 2025. First connect over Remote Desktop, as explained in Connect to a Windows VPS via RDP.

Choose a version and a method

Always install an LTS release, which is supported for longer. Since 28 October 2026, the active LTS is Node.js 26. Node.js 24 and 22 still get security fixes. Node.js 20 has been out of support since 30 April 2026. The official release schedule has the current dates.

There are three ways to install Node.js on Windows Server.

MethodUseStrengthLimit
MSI installerOne app in productionInstalled system-wideChanging major version means reinstalling
wingetThe same in one commandBuilt into Windows Server 2025One version at a time
nvm-windowsTesting several versionsSwitch versions with one commandInstalled in your profile, unusable by a service

For an app that must run all the time, use the MSI or winget. The Windows service described below relies on that Node.js. Keep nvm-windows for a development or test server.


Install Node.js with the MSI installer

  1. On the VPS, open the Node.js download page.

  2. Pick the LTS release for Windows on x64, then download the Windows Installer (.msi).

  3. Run the file and keep the default options. The Add to PATH option must stay enabled.

  4. Open a new PowerShell window and check the installed versions.

node -v
npm -v

The first line shows the Node.js version, for example v26.13.0. The second shows the npm version. To change major version, uninstall Node.js from the Windows settings, then install the MSI of the other version.


Install Node.js with winget

winget, the Windows package manager, is installed by default on Windows Server 2025, according to Microsoft. One command installs the current LTS.

winget install OpenJS.NodeJS.LTS

The package installs the same MSI, system-wide. Close PowerShell, open it again, then check with node -v. This command updates Node.js later on.

winget upgrade OpenJS.NodeJS.LTS

Install nvm-windows to switch versions

nvm-windows installs several Node.js versions side by side and switches between them. It is a separate project from nvm, which only runs on Linux and macOS. Version 2 installs into your user profile, without administrator rights.

Node.js already installed with the MSI or winget? Uninstall it first. Two Node.js installs in the PATH lead to confusion.

Install nvm-windows with winget. You can also download the setup.exe installer from the nvm-windows releases page.

winget install nvm-windows

Open a new PowerShell window. Check that nvm responds, then install and switch to the latest LTS.

# Check that nvm-windows responds
nvm env

# Install and switch to the latest LTS
nvm install lts
nvm use lts

node -v
npm -v

nvm use changes the default version, which is kept for later sessions. The other commands are described in the nvm-windows documentation.


Switch versions and update Node.js

nvm-windows keeps each version in its own folder. You can test your app on another version without uninstalling anything.

# Install other major versions
nvm install 24
nvm install 22

# Switch to Node.js 24
nvm use 24

# List installed versions (* = active version)
nvm list

To move to a new LTS, install it, test your app, then remove the old version.

# Install the new LTS and switch to it
nvm install lts
nvm use lts

# Remove the old version once everything works
nvm uninstall 22

Test your app before switching versions in production. Some npm packages depend on a specific Node.js major version.

With the MSI or winget, you update through winget upgrade or the MSI of the new version.


Deploy a Node.js application on Windows Server

A small Express app checks the whole setup end to end. Create the project folder, then install Express.

mkdir C:\apps\monapp
cd C:\apps\monapp
npm init -y
npm install express

Create the server.js file and open it in Notepad.

New-Item server.js
notepad server.js

Paste this code, save, then close Notepad.

const express = require('express');
const app = express();
const PORT = 3000;

app.get('/', (req, res) => {
  res.send('Hello from OuiHeberg VPS!');
});

app.listen(PORT, () => {
  console.log(`Server started on port ${PORT}`);
});

Start the app.

node server.js

In a browser on the VPS, open http://localhost:3000. The page shows this message.

Hello from OuiHeberg VPS!

Press Ctrl+C to stop the app. Started this way, it also stops when you close PowerShell.


Monitor the app with PM2

PM2 restarts a Node.js app that crashes and gathers its logs. It is free software under the MIT license. Its paid plan, PM2 Plus, adds online monitoring that most projects can do without.

npm install -g pm2
pm2 start C:\apps\monapp\server.js --name "monapp"
CommandEffect
pm2 listLists the processes
pm2 logs monappShows live logs
pm2 restart monappRestarts the app
pm2 stop monappStops the app
pm2 monitShows live CPU and memory use
pm2 delete monappRemoves the app from PM2

PM2 runs inside your Windows session. Its pm2 startup command, which restarts it at boot, only knows the init systems of Linux, macOS, BSD and Solaris, according to the PM2 documentation. It does not work on Windows. To start the app with the server, install it as a Windows service.


Start the app at boot with a Windows service

A Windows service starts with the server, with no open session, and can restart after a crash. Node.js cannot register itself as a service. WinSW, a free tool under the MIT license, bridges the gap. The service uses the Node.js from the MSI or winget, installed in C:\Program Files\nodejs.

Create a folder for the service and download WinSW as monapp.exe. The last command opens the configuration file in Notepad.

New-Item -ItemType Directory -Path C:\services\monapp
Invoke-WebRequest -Uri "https://github.com/winsw/winsw/releases/download/v2.12.0/WinSW-x64.exe" -OutFile "C:\services\monapp\monapp.exe"
notepad C:\services\monapp\monapp.xml

Paste this configuration, then save. The XML file has the same name as the executable.

<service>
  <id>monapp</id>
  <name>monapp (Node.js)</name>
  <description>Node.js monapp</description>
  <executable>C:\Program Files\nodejs\node.exe</executable>
  <arguments>C:\apps\monapp\server.js</arguments>
  <workingdirectory>C:\apps\monapp</workingdirectory>
  <env name="NODE_ENV" value="production" />
  <startmode>Automatic</startmode>
  <onfailure action="restart" delay="10 sec" />
  <log mode="roll-by-size">
    <sizeThreshold>10240</sizeThreshold>
    <keepFiles>8</keepFiles>
  </log>
</service>

The onfailure tag restarts the app if it stops. The monapp.out.log and monapp.err.log logs are written to the service folder, with a new file every 10 MB.

In PowerShell run as administrator, install and start the service.

# Free the port if PM2 is already running the app
pm2 delete monapp

cd C:\services\monapp
.\monapp.exe install
.\monapp.exe start
.\monapp.exe status
Get-Service monapp

status should return Started, and Get-Service should show Running. The service also appears in the Services console, with automatic startup. Restart the VPS to check that the app comes back on its own.

# After updating the code
.\monapp.exe restart

# Remove the service
.\monapp.exe stop
.\monapp.exe uninstall

By default, WinSW runs the service under the LocalSystem account, which has full rights on the machine. Its documentation shows how to pick a less privileged account with the serviceaccount tag.


Configure the Windows Firewall for Node.js

The client area has no network firewall for VPS. Only the Windows Firewall filters connections. Open the ports in PowerShell run as administrator.

# Port 3000 (testing)
New-NetFirewallRule -DisplayName "Node.js Dev" -Direction Inbound -Protocol TCP -LocalPort 3000 -Action Allow

# Port 80 (HTTP)
New-NetFirewallRule -DisplayName "Node.js HTTP" -Direction Inbound -Protocol TCP -LocalPort 80 -Action Allow

# Port 443 (HTTPS)
New-NetFirewallRule -DisplayName "Node.js HTTPS" -Direction Inbound -Protocol TCP -LocalPort 443 -Action Allow

Then check the rules. Each one should show True in the Enabled column.

Get-NetFirewallRule -DisplayName "Node.js*" | Select Name, Enabled

Only open port 3000 while you test. In production, put a reverse proxy such as IIS or Nginx on ports 80 and 443. It routes requests to your apps, each on its own port (3000, 3001, 3002…). The guide How to install IIS on Windows Server covers the IIS setup. For the rest of the firewall, follow How to open a port in Windows Firewall on a VPS.


Fix common errors

"node" is not recognized

PowerShell has not read the new PATH yet. Close it, then open it again. With nvm-windows, also run nvm use lts.

"nvm" is not recognized

Open a new PowerShell window. If the error persists, reinstall nvm-windows.

EACCES or EPERM error during npm install -g

Restart PowerShell as administrator, then run the command again.

Port 3000 is already in use

Another process holds the port, often a first copy of the app. Find its number, then stop it.

netstat -ano | findstr :3000
taskkill /PID [PID] /F

Replace [PID] with the number shown in the last column.

The service does not start

Read monapp.err.log in C:\services\monapp. Also check the node.exe path in the XML file. The service cannot see a Node.js installed with nvm-windows.

Modules are missing after a version switch

Each Node.js version has its own global modules. After nvm use, run npm install again in the project folder. Reinstall PM2 too if you use it.


Need help?

Open a ticket from Tickets › Open a Ticket, or from the Contact support tile at the bottom of the VPS page. In the Related Service field, pick the VPS so the team saves time. You can also ask your question on the OuiHeberg Discord.

Was this article helpful?

596 views
Share this article
VPS Windows
Need a Windows VPS?

Windows Server 2025 with the license included, Remote Desktop access and management from the client area.

View plans →

Related Articles