WSL — Windows Subsystem for Linux Essentials
WSL (Windows Subsystem for Linux) lets you run a real Linux environment directly on Windows — no VM, no dual boot. WSL2 runs a full Linux kernel in a lightweight Hyper-V VM and is the current default.
Install and Update
Install WSL
From PowerShell as Administrator:
This installs WSL2 and Ubuntu by default. To list available distros and install a specific one:
Update WSL itself
WSL is distributed via the Microsoft Store and updated independently from Windows:
Check the currently installed version:
Update the Linux distro inside WSL
WSL itself and the Linux distribution inside it are two separate things. Update the distro as you would on any Ubuntu system:
File Paths
Windows drives in WSL
All Windows drives are mounted under /mnt/ with lowercase drive letters:
| Windows | WSL |
|---|---|
C:\ |
/mnt/c/ |
D:\ |
/mnt/d/ |
C:\Users\Sebastian\Desktop |
/mnt/c/Users/Sebastian/Desktop |
Backslashes become forward slashes, drive letters are lowercase.
Convert paths with wslpath
wslpath converts between Windows and WSL paths:
Convert a WSL path back to a Windows path:
Use Windows environment variables
Windows environment variables like $USERPROFILE are available in WSL by default:
Find other useful paths:
Permanent shortcut via symlink
Create a symlink to your Desktop once, then use it forever:
Alias in ~/.bashrc
Access WSL Files from Windows
Your Linux home directory is accessible from Windows Explorer at:
Or navigate there directly from WSL:
This opens Windows Explorer in the current WSL directory.
Run Windows Apps from WSL
Any Windows .exe is callable directly from a WSL shell:
code . opens the current WSL directory in VS Code with the Remote WSL extension automatically.
WSL Management Commands
Shows all installed distros, their WSL version, and state (Running/Stopped).
Immediately stops all running WSL instances and the VM. Required after changing .wslconfig.
Stops a specific distro without affecting others.
Sets the default distro launched when typing wsl in PowerShell.
Configuration: Two Files
WSL has two separate config files with different scopes:
| File | Location | Scope |
|---|---|---|
wsl.conf |
/etc/wsl.conf inside the distro |
Per-distro settings |
.wslconfig |
%UserProfile%\.wslconfig on Windows |
Global settings for all WSL2 distros |
Changes to either file only take effect after a full WSL restart — run wsl --shutdown from PowerShell, then reopen WSL.
wsl.conf — Per-distro settings
Located at /etc/wsl.conf inside the Linux distro. Edit with:
Enable systemd (needed for systemctl, Docker, and many services):
Run a command on WSL start (e.g. start Docker daemon):
Set default login user:
Set a custom hostname:
Disable Windows PATH being appended to Linux $PATH (cleaner environment, but Windows tools like code won't work from WSL anymore):
.wslconfig — Global WSL2 settings
Located at C:\Users\<WindowsUsername>\.wslconfig. Create it if it doesn't exist. Edit from WSL:
Limit memory and CPU (WSL2 defaults to 50% of RAM and all CPU cores, which can starve Windows under load):
Enable automatic memory reclaim (frees cached Linux memory back to Windows):
gradual slowly releases cached memory. dropCache releases it immediately. disabled turns it off.
Enable sparse VHD (the virtual disk only takes up as much space as actually used):
Performance Tips
Keep project files inside WSL, not on /mnt/
This is the most impactful performance change. Linux filesystem operations on /mnt/c/ go through a translation layer and are significantly slower than operations on the native Linux filesystem.
| Location | Speed |
|---|---|
~/projects/ (Linux filesystem) |
Fast |
/mnt/c/Users/.../projects/ (Windows filesystem) |
Slow |
For regular use: keep scripts and project files in ~/. Copy them from Windows once, then work inside WSL.
VS Code Remote WSL
Install the Remote - WSL extension in VS Code. Then from WSL:
This opens VS Code connected directly to the WSL filesystem — full speed, no translation layer.
CRLF Line Endings
Scripts written or edited in Windows tools (Notepad, VS Code on Windows side) often have Windows line endings (\r\n). Bash treats the \r as part of the command and fails with cryptic errors like bad interpreter or ^M characters.
Detect CRLF:
Fix it:
Or install and use dos2unix:
Useful One-Liners
Open current WSL directory in Windows Explorer:
Find your Windows username from WSL:
Open .wslconfig from inside WSL:
Restart WSL (from PowerShell):
Check if a distro is still running after closing the terminal: