Table of Contents
If you code on Windows without WSL, you are fighting your tools. Paths with backslashes, file watchers that miss changes, build scripts written for Linux that fail in strange ways, and permission errors that no tutorial mentions because the tutorial’s author was on a Mac.
WSL gives you a real Linux environment inside Windows. This guide installs Node.js and npm there properly, using Node Version Manager, which is what most professional teams use. Every command is printed in full, along with the one mistake that quietly makes everything slow.
What you will have in about ten minutes:
✓ WSL 2 with Ubuntu, checked and updated
✓ nvm installed, so you can switch Node versions per project
✓ The latest LTS Node.js and npm
✓ VS Code opening your Linux project from Windows
✓ A first project that actually runs
Why Bother With WSL at All
Because almost every tutorial, Docker image, deployment server and open-source build script in the world assumes Linux. Running Node directly on Windows means translating all of that, and the translation leaks.
0Check WSL Is Actually Installed
Open PowerShell on Windows, not the WSL terminal, and run:
wsl --version wsl -l -v
PS C:\Users\you> wsl -l -v NAME STATE VERSION * Ubuntu Running 2
You want VERSION 2. If nothing is installed, this one command sets it up, then restart your computer:
wsl --install -d Ubuntu
Still on WSL 1? Upgrade it with wsl --set-version Ubuntu 2. WSL 2 uses a real Linux kernel and is far faster for exactly the kind of work Node does.
1Open Ubuntu and Update It
Search for Ubuntu in the Start menu, or open Windows Terminal and pick Ubuntu from the dropdown. Then bring the system up to date:
sudo apt update && sudo apt upgrade -y
# Things nvm and many npm packages need
sudo apt install -y curl build-essential
It will ask for your Linux password, which is the one you chose when Ubuntu first started, not your Windows password. Nothing appears as you type it; that is normal.
2Install nvm (With the Actual Command)
Do not install Node with sudo apt install nodejs. The version in Ubuntu’s repository is usually old, and installing globally with sudo causes permission problems later. Use nvm instead, which installs Node in your home folder and lets you switch versions per project.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.7/install.sh | bash
Then close and reopen the terminal, or reload your shell config so the nvm command becomes available:
source ~/.bashrc
# Check it is there
command -v nvm
$ command -v nvm nvm # If this prints nothing, see the troubleshooting section below.
About that version number. v0.40.7 was the current nvm release when this was written. Check the nvm repository for the latest and change the number in the URL if it has moved on. Pasting an install script from the internet is worth doing with your eyes open: open that URL in a browser first if you want to read what it does.
3Install Node.js
# LTS = Long Term Support. The stable choice for real work. nvm install --lts # Make it the default in every new terminal nvm alias default lts/*
$ nvm install --lts
Installing latest LTS version.
Downloading and installing node v22.20.0...
Now using node v22.20.0 (npm v10.9.3)
Creating default alias: default -> lts/* (-> v22.20.0)
Example output. Your version numbers will be higher; LTS moves forward every year.
4Verify
node -v npm -v which node
$ node -v v22.20.0 $ npm -v 10.9.3 $ which node /home/you/.nvm/versions/node/v22.20.0/bin/node
Check that third line carefully. If which node prints something starting with /mnt/c/, you are running the Windows copy of Node from inside Linux, because Windows shares its PATH with WSL. That causes genuinely baffling errors. The fix is in the troubleshooting section.
npm comes bundled with Node, so there is nothing separate to install. Upgrade it on its own whenever you like with npm install -g npm@latest.
Where You Put Your Project Decides Its Speed
This is the single most valuable thing in this guide, and almost no tutorial mentions it. WSL can see your Windows drives at /mnt/c/, which feels convenient. Working there is drastically slower, because every file read crosses between the two operating systems.
# Do this cd ~ mkdir -p projects && cd projects # Not this # cd /mnt/c/Users/you/Desktop
5Build and Run Something
cd ~/projects mkdir my-app && cd my-app npm init -y # Create a file and run it echo 'console.log("Node.js is working on WSL!");' > index.js node index.js
$ node index.js
Node.js is working on WSL!
Now something with a real server, so you can see it in your Windows browser:
import { createServer } from 'node:http'; createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/html' }); res.end('<h1>Hello from WSL</h1>'); }).listen(3000, () => { console.log('Running at http://localhost:3000'); });
# "type": "module" lets you use import
npm pkg set type=module
node server.js
Open http://localhost:3000 in your normal Windows browser and it works. WSL forwards localhost automatically, so a server running in Linux is reachable from Windows with no configuration at all.
Why nvm Is Worth It: Switch Versions Live
The real payoff is this. One project needs Node 18, another needs 22, and switching takes one second instead of an afternoon. Click the commands below to see it work.
Make it automatic per project. Put a file called .nvmrc in a project folder containing just the version, for example 22. Then nvm use with nothing after it reads that file and switches for you. Commit it, and your teammates get the right version too.
The nvm commands worth remembering
| Command | What it does |
|---|---|
nvm install --lts | Install the latest long-term-support version. |
nvm install 22 | Install a specific major version. |
nvm use 18 | Switch this terminal to version 18. |
nvm ls | List what you have installed, with the active one marked. |
nvm ls-remote --lts | List every LTS version available to install. |
nvm alias default 22 | Choose what every new terminal starts with. |
nvm use | Read .nvmrc in the current folder and switch to it. |
nvm uninstall 18 | Remove a version you no longer need. |
6Connect VS Code
You keep the Windows interface and get the Linux environment underneath. Install the WSL extension in VS Code on Windows, then from your Ubuntu terminal:
cd ~/projects/my-app code .
VS Code opens on Windows with the folder loaded from Linux. The bottom-left corner shows a green WSL: Ubuntu badge, and the built-in terminal is your Ubuntu shell.
Extensions install in two places now. Some run on Windows (themes, keymaps) and some must run inside WSL (ESLint, Prettier, language servers). If a linter has stopped working after switching, open the Extensions panel and look for the Install in WSL: Ubuntu button next to it.
When Something Goes Wrong
nvm: command not found
The installer added some lines to ~/.bashrc, but your terminal has not read them yet. Run source ~/.bashrc, or simply close and reopen the terminal. If it still fails, check the lines are actually there with tail -5 ~/.bashrc; if they are missing, run the install command again. If you use zsh rather than bash, add them to ~/.zshrc instead.
node -v shows a version I never installed, or which node says /mnt/c/
You are running the Windows copy of Node from inside Linux, because WSL inherits the Windows PATH. Uninstall Node from Windows if you do not need it there, or stop WSL inheriting that PATH by creating /etc/wsl.conf:
[interop] appendWindowsPath = false
Then run wsl --shutdown in PowerShell and reopen Ubuntu. Note that afterwards you can no longer call Windows programs such as explorer.exe from WSL.
EACCES: permission denied when installing a global package
If you installed Node with nvm, this should never happen, which is one of the main reasons to use it. If you see it, you probably have a second Node installed via apt. The fix is never to run sudo npm install -g, because that creates root-owned files that break later installs. Remove the apt version with sudo apt remove nodejs npm and use nvm alone.
npm install is extremely slow
Almost always because the project is on /mnt/c/. Move it into the Linux filesystem: cp -r /mnt/c/Users/you/projects/my-app ~/projects/ and work from there. The difference is usually not subtle.
Hot reload does not pick up my changes
Same cause. File-change events do not cross reliably between Windows and Linux. Move the project to ~/. If it is already there and you have very many files, raise the watcher limit: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p.
I cannot reach localhost:3000 from my Windows browser
Check the server is listening on all interfaces rather than only a specific one, and that no Windows firewall rule is blocking the port. If it still fails, wsl --shutdown in PowerShell and reopen Ubuntu; the localhost forwarding occasionally needs a restart.
WSL is using a lot of memory
WSL 2 claims memory as it needs it. Cap it by creating C:\Users\YourName\.wslconfig with [wsl2] and memory=4GB on the next line, then run wsl --shutdown.
Common Questions
Do I need to install Node on Windows as well?
No, and it is better not to. Two installations create PATH confusion and the mysterious version mismatches described above. Pick WSL and keep everything there.
Why not just install Node with apt?
Ubuntu’s repository version is often behind, and you cannot switch versions per project. With nvm you can run Node 18 for a client’s old project and Node 22 for your own, in two terminals at the same time.
LTS or Current?
LTS for anything real. “Current” has the newest features but a shorter support window and more surprises. LTS is what hosting providers and most libraries target.
Can I use WSL with Docker?
Yes, and they work together very well. Docker Desktop on Windows uses WSL 2 as its engine, so containers run on the same Linux kernel as your projects. See our Laravel in Docker guide for a practical example.
Where are my WSL files on Windows?
Type \\wsl$ into File Explorer’s address bar, or run explorer.exe . from inside a WSL folder. You can browse and edit them normally, but do your actual work from the Linux side for speed.
Is yarn or pnpm better than npm?
pnpm is noticeably faster and uses less disk space; yarn is common in older projects. npm is built in and perfectly good. Learn npm first, since every tutorial assumes it, and try pnpm once you are comfortable.
The Full Video Tutorial
Here is the whole setup on video if you would rather follow along:
New Linux, Node, Docker and Laravel tutorials every week.
Read next: How to Install Ubuntu on Windows 11 Using WSL if you have not set WSL up yet, and How to Upload Your Project to GitHub once your first project runs.
Final Thoughts
Two rules make this setup behave for years. Install Node with nvm, never with apt or sudo, so you can switch versions and never meet a permission error. And keep your projects in ~/, never in /mnt/c/, which is the difference between an install taking seconds and taking minutes.
Run node -v and which node right now. If the path starts with /home/, you are set up properly. Tell me in the comments which Node version you landed on. I read every one.
If this saved you an afternoon, share it with someone still fighting Node on plain Windows.



