Skip to content

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:

wsl --install

This installs WSL2 and Ubuntu by default. To list available distros and install a specific one:

wsl --list --online
wsl --install -d Ubuntu-24.04

Update WSL itself

WSL is distributed via the Microsoft Store and updated independently from Windows:

wsl --update

Check the currently installed version:

wsl --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:

sudo apt update && sudo apt upgrade -y

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:

wslpath 'C:\Users\Sebastian\Desktop'

Convert a WSL path back to a Windows path:

wslpath -w ~/scripts/backup.sh

Use Windows environment variables

Windows environment variables like $USERPROFILE are available in WSL by default:

cd "$(wslpath "$USERPROFILE/Desktop")"

Find other useful paths:

wslpath "$APPDATA"
wslpath "$TEMP"

Create a symlink to your Desktop once, then use it forever:

ln -s "$(wslpath "$USERPROFILE/Desktop")" ~/desktop

Alias in ~/.bashrc

echo "alias desktop='cd \"\$(wslpath \"\$USERPROFILE/Desktop\")\"'" >> ~/.bashrc
source ~/.bashrc

Access WSL Files from Windows

Your Linux home directory is accessible from Windows Explorer at:

\\wsl$\Ubuntu\home\<username>\

Or navigate there directly from WSL:

explorer.exe .

This opens Windows Explorer in the current WSL directory.


Run Windows Apps from WSL

Any Windows .exe is callable directly from a WSL shell:

explorer.exe .
notepad.exe /mnt/c/Users/Sebastian/file.txt
code .

code . opens the current WSL directory in VS Code with the Remote WSL extension automatically.


WSL Management Commands

wsl --list --verbose

Shows all installed distros, their WSL version, and state (Running/Stopped).

wsl --shutdown

Immediately stops all running WSL instances and the VM. Required after changing .wslconfig.

wsl --terminate Ubuntu

Stops a specific distro without affecting others.

wsl --set-default Ubuntu-24.04

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:

sudo nano /etc/wsl.conf

Enable systemd (needed for systemctl, Docker, and many services):

[boot]
systemd=true

Run a command on WSL start (e.g. start Docker daemon):

[boot]
command=service docker start

Set default login user:

[user]
default=sebastian

Set a custom hostname:

[network]
hostname=my-wsl-box

Disable Windows PATH being appended to Linux $PATH (cleaner environment, but Windows tools like code won't work from WSL anymore):

[interop]
appendWindowsPath=false

.wslconfig — Global WSL2 settings

Located at C:\Users\<WindowsUsername>\.wslconfig. Create it if it doesn't exist. Edit from WSL:

nano "$(wslpath "$USERPROFILE/.wslconfig")"

Limit memory and CPU (WSL2 defaults to 50% of RAM and all CPU cores, which can starve Windows under load):

[wsl2]
memory=4GB
processors=2

Enable automatic memory reclaim (frees cached Linux memory back to Windows):

[wsl2]
memory=4GB

[experimental]
autoMemoryReclaim=gradual

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):

[experimental]
sparseVhd=true

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:

code .

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:

file script.sh

Fix it:

sed -i 's/\r//' script.sh

Or install and use dos2unix:

sudo apt install dos2unix
dos2unix script.sh

Useful One-Liners

Open current WSL directory in Windows Explorer:

explorer.exe .

Find your Windows username from WSL:

cmd.exe /c 'echo %USERNAME%' | tr -d '\r'

Open .wslconfig from inside WSL:

nano "$(wslpath "$USERPROFILE/.wslconfig")"

Restart WSL (from PowerShell):

wsl --shutdown

Check if a distro is still running after closing the terminal:

wsl --list --running

Sources