{"id":835,"date":"2026-10-14T13:00:00","date_gmt":"2026-10-14T13:00:00","guid":{"rendered":"https:\/\/vpslake.com\/blog\/?p=835"},"modified":"2026-10-14T13:00:00","modified_gmt":"2026-10-14T13:00:00","slug":"install-nodejs-windows-server-2019","status":"publish","type":"post","link":"https:\/\/vpslake.com\/blog\/2026\/10\/14\/install-nodejs-windows-server-2019\/","title":{"rendered":"How to Install Node.js on Windows Server 2019"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">To install nodejs on Windows Server 2019, use the official 64-bit LTS installer and test both Node.js and npm from a fresh PowerShell session. You can go from a clean RDP server to a working local web app in about ten minutes, without exposing a new internet port.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>A patched, 64-bit Windows Server 2019 installation.<\/li>\n\n\n<li>An RDP session and a local Administrator account, or an account that can approve User Account Control and run an elevated installer.<\/li>\n\n\n<li>At least 2 GB of free disk space and outbound HTTPS access so the server can download the MSI and npm packages.<\/li>\n\n\n<li>A domain name is not needed for the local test. If you will publish an application, prepare its domain, TLS certificate, and intended listening port first.<\/li>\n\n\n<li>A <a href=\"https:\/\/vpslake.com\/buy-windows-rdp\">VPSLake Windows VPS<\/a> with administrator access if you need a Windows Server environment for Node.js.<\/li>\n\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: Confirm Windows Server 2019 is 64-bit<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The x64 MSI is the normal choice for a Server 2019 VPS, but checking first prevents installing a package for the wrong architecture.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Open <strong>Start \u2192 Windows PowerShell<\/strong>, then run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Get-CimInstance Win32_OperatingSystem | Select-Object Caption, Version, OSArchitecture<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected output resembles:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Caption                         Version        OSArchitecture\n-------                         -------        --------------\nMicrosoft Windows Server 2019  10.0.17763    64-bit<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Continue only when <code>OSArchitecture<\/code> says <code>64-bit<\/code>. If the server is 32-bit, do not force an x64 installer onto it; use a 64-bit server image before deploying current Node.js releases.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: Download the official Node.js LTS MSI<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The LTS line is the safer starting point for a server because it prioritizes a longer maintenance window over the newest short-lived features.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use a browser in the RDP session to open the <a href=\"https:\/\/nodejs.org\/en\/download\/\" target=\"_blank\" rel=\"noopener\">official Node.js download page<\/a>. Select the release marked <strong>LTS<\/strong>, then download <strong>Windows Installer (.msi)<\/strong> for <strong>x64<\/strong>. Save it in <code>C:\\Users\\Administrator\\Downloads<\/code> or another folder you control.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you prefer PowerShell, this command discovers the current LTS release from the official Node.js distribution index and downloads its x64 MSI:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\n$release = Invoke-RestMethod -Uri 'https:\/\/nodejs.org\/dist\/index.json' | Where-Object { $_.lts -and $_.files -contains 'win-x64-msi' } | Select-Object -First 1\n$version = $release.version\n$installer = Join-Path $env:TEMP \"node-$version-x64.msi\"\nInvoke-WebRequest -Uri \"https:\/\/nodejs.org\/dist\/$version\/node-$version-x64.msi\" -OutFile $installer\nGet-Item $installer | Select-Object Name, Length<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The final line should show an MSI with a non-zero size. The <code>$version<\/code> value includes the leading <code>v<\/code>, which is part of the official file name.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 3: Install Node.js and npm<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The MSI adds the runtime and npm to the machine PATH, so applications and new terminal sessions can find them without custom environment variables.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you downloaded the MSI with PowerShell in Step 2, launch its normal setup wizard with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Start-Process msiexec.exe -ArgumentList \"\/i `\"$installer`\"\" -Wait -Verb RunAs<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Otherwise, open the downloaded <code>.msi<\/code> in File Explorer. In the wizard:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n\n<li>Select <strong>Next<\/strong>, accept the license, and keep the default destination <code>C:\\Program Files\\nodejs\\<\/code>.<\/li>\n\n\n<li>Leave <strong>Node.js runtime<\/strong>, <strong>npm package manager<\/strong>, and <strong>Add to PATH<\/strong> selected.<\/li>\n\n\n<li>Leave <strong>Tools for Native Modules<\/strong> clear unless an application specifically needs to compile a native C or C++ addon. Those tools are not required for ordinary JavaScript packages.<\/li>\n\n\n<li>Select <strong>Install<\/strong>, approve the elevation prompt, and choose <strong>Finish<\/strong>.<\/li>\n\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">The installer does not create a Node.js service or open an inbound Windows Firewall rule. Close old PowerShell and Command Prompt windows before checking the PATH, because they keep the environment from when they were opened.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 4: Check Node.js, npm, and the PATH<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A new terminal verifies that the installation completed and that Windows resolves the expected executable rather than an older copy elsewhere on the server.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Open a new <strong>Windows PowerShell<\/strong> window and run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>node --version\nnpm --version\nGet-Command node | Select-Object -ExpandProperty Source<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The exact release numbers change over time. A successful result looks like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vMAJOR.MINOR.PATCH\nN.N.N\nC:\\Program Files\\nodejs\\node.exe<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The first line must begin with <code>v<\/code>, the second must be a numeric npm version, and the final line should point to <code>C:\\Program Files\\nodejs\\node.exe<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 5: Run a localhost Node.js application<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Executing a small HTTP server proves that the runtime works and keeps the test private by binding only to the loopback address.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In PowerShell, create the test application:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>New-Item -ItemType Directory -Path C:\\node-demo -Force | Out-Null\n@'\nconst http = require(\"http\");\nconst server = http.createServer((request, response) =&gt; {\n  response.writeHead(200, { \"Content-Type\": \"text\/plain\" });\n  response.end(\"Node.js is running on Windows Server 2019\\n\");\n});\nserver.listen(3000, \"127.0.0.1\", () =&gt; {\n  console.log(\"Listening on http:\/\/127.0.0.1:3000\");\n});\n'@ | Set-Content -Path C:\\node-demo\\server.js -Encoding utf8\nSet-Location C:\\node-demo\nnode .\\server.js<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Leave that window running. You should see:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Listening on http:\/\/127.0.0.1:3000<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Open a second PowerShell window and request the page locally:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(Invoke-WebRequest -UseBasicParsing http:\/\/127.0.0.1:3000).Content.Trim()<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Node.js is running on Windows Server 2019<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Press <code>Ctrl+C<\/code> in the server window when the test is complete. The test listens only on <code>127.0.0.1<\/code>, so another computer cannot reach it and no firewall exception is needed.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Verify Node.js on Windows Server 2019<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Run this final check from the account that will operate the application. It confirms the platform, CPU architecture, runtime version, and npm&#8217;s ability to create a local project manifest:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>node -e \"console.log(process.platform); console.log(process.arch); console.log(process.version)\"\nSet-Location C:\\node-demo\nnpm init --yes\nGet-Content .\\package.json<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The first three lines should be <code>win32<\/code>, <code>x64<\/code>, and a <code>v<\/code>-prefixed version. The last command should display JSON containing a project <code>name<\/code> and a <code>version<\/code> field. For API and runtime behavior, use the <a href=\"https:\/\/nodejs.org\/docs\/latest\/api\/\" target=\"_blank\" rel=\"noopener\">official Node.js documentation<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><code>node is not recognized as the name of a cmdlet<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The terminal was probably open before the MSI updated PATH, or the installation did not finish. Close every terminal, open a new PowerShell window, and run <code>Get-Command node<\/code>; if it still fails, check whether <code>C:\\Program Files\\nodejs\\node.exe<\/code> exists and repair Node.js from <strong>Settings \u2192 Apps \u2192 Apps &amp; features \u2192 Node.js \u2192 Modify<\/strong>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><code>npm.ps1 cannot be loaded because running scripts is disabled<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">PowerShell&#8217;s execution policy is blocking the npm PowerShell shim, not Node.js itself. Use <code>npm.cmd --version<\/code> for a one-time check, or allow signed local scripts for your user account with <code>Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned<\/code>, then open a new terminal and retry <code>npm --version<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><code>npm ERR! code EACCES<\/code> or <code>EPERM<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The project or its dependency directory is protected or locked. Put application code in a dedicated writable folder such as <code>C:\\Apps\\YOUR_APP<\/code>, install dependencies locally with <code>npm install<\/code>, close editors that may hold files open, and avoid making a global package directory writable by every user.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The app works on the server but not from another computer<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The sample deliberately binds to <code>127.0.0.1<\/code>, which accepts local requests only. For a real deployment, bind the application to the interface your design requires, terminate TLS at a reverse proxy, and create the narrowest inbound rule in <strong>Server Manager \u2192 Tools \u2192 Windows Defender Firewall with Advanced Security<\/strong>; also check any firewall in the VPS control panel.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Hardening<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>Keep the server patched and use an actively supported Node.js LTS line; review the release notes before changing major versions.<\/li>\n\n\n<li>Run the application with a dedicated, least-privileged Windows account instead of Administrator, and keep secrets in protected environment variables or a secret manager.<\/li>\n\n\n<li>Leave port 3000 closed when the application is local. If it must be public, expose only the TLS reverse-proxy port and restrict backend access to the proxy host.<\/li>\n\n\n<li>Keep npm dependencies local to the application and review the lockfile before upgrades.<\/li>\n\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">FAQ<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Should I install the LTS or Current Node.js release on Server 2019?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Choose LTS for most production applications because it is the maintenance-oriented release line. Use Current only when the application explicitly needs a newer feature and its dependencies support that release.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Is the x64 installer compatible with Windows Server 2019?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Yes, provided the operating system is 64-bit and patched. Confirm the architecture in Step 1 before downloading; an x86 or ARM64 MSI is not the correct choice for a normal x64 VPS.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Does installing Node.js start a server or open a firewall port?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No. Node.js is a runtime, and the MSI does not publish an application or add an inbound rule. A port is used only when one of your scripts starts a network service, and you should then configure its binding and firewall policy deliberately.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Do I need the native build tools option?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Only when an npm dependency must compile a native addon and does not provide a compatible prebuilt binary. Start with the runtime and npm components; add the toolchain later according to that package&#8217;s documented requirements.<\/p>\n\n\n\n<aside class=\"vl-element vl-cta-banner\" aria-label=\"Run Node.js on Windows\">\n\t<div class=\"vl-cta-banner__content\">\n\t\t<p class=\"vl-cta-banner__eyebrow\">Windows Server hosting<\/p>\n\t\t<h3 class=\"vl-cta-banner__title\">Run Node.js on Windows<\/h3>\n\t\t<p class=\"vl-cta-banner__text\">Deploy Node.js applications on a Windows VPS with administrator access and full server control.<\/p>\n\t<\/div>\n\t<a class=\"vl-cta-banner__button\" href=\"\/buy-windows-rdp\" aria-label=\"View Windows VPS\">View Windows VPS<\/a>\n<\/aside>\n\n\n\n<script type=\"application\/ld+json\">{\"@context\": \"https:\/\/schema.org\", \"@type\": \"FAQPage\", \"mainEntity\": [{\"@type\": \"Question\", \"name\": \"Should I install the LTS or Current Node.js release on Server 2019?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Choose LTS for most production applications because it is the maintenance-oriented release line. Use Current only when the application explicitly needs a newer feature and its dependencies support that release.\"}}, {\"@type\": \"Question\", \"name\": \"Is the x64 installer compatible with Windows Server 2019?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Yes, provided the operating system is 64-bit and patched. Confirm the architecture in Step 1 before downloading; an x86 or ARM64 MSI is not the correct choice for a normal x64 VPS.\"}}, {\"@type\": \"Question\", \"name\": \"Does installing Node.js start a server or open a firewall port?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"No. Node.js is a runtime, and the MSI does not publish an application or add an inbound rule. A port is used only when one of your scripts starts a network service, and you should then configure its binding and firewall policy deliberately.\"}}, {\"@type\": \"Question\", \"name\": \"Do I need the native build tools option?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Only when an npm dependency must compile a native addon and does not provide a compatible prebuilt binary. Start with the runtime and npm components; add the toolchain later according to that package's documented requirements.\"}}]}<\/script>\n\n","protected":false},"excerpt":{"rendered":"Install nodejs on Windows Server 2019 with the official x64 LTS MSI, verify npm, run a local app, and fix PATH, PowerShell, and firewall issues.","protected":false},"author":1,"featured_media":836,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_singular_sidebar":"","csco_page_header_type":"","csco_page_load_nextpost":"","footnotes":""},"categories":[5,11],"tags":[64,65,38,40],"class_list":["post-835","post","type-post","status-publish","format-standard","has-post-thumbnail","category-guides","category-windows-server","tag-nodejs","tag-npm","tag-powershell","tag-windows-server-2019","cs-entry"],"_links":{"self":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/835","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/comments?post=835"}],"version-history":[{"count":1,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/835\/revisions"}],"predecessor-version":[{"id":3331,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/835\/revisions\/3331"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/media\/836"}],"wp:attachment":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/media?parent=835"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/categories?post=835"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/tags?post=835"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}