Master WSL
The Fun Way
Windows Subsystem for Linux lets you run a full Linux environment right inside Windows — no dual boot, no VM headaches. This guide turns complex concepts into bite-sized, interactive lessons.
Get WSL 2 running on your machine in under 5 minutes.
4 lessons • ~10 minSet up VS Code, Docker, Git and SSH for serious development.
4 lessons • ~20 minGPU passthrough, mirrored networking, custom distros and more.
6 lessons • ~30 minDiagnose and fix the most common WSL issues quickly.
3 lessons • ~15 minWhat is WSL?
Understand what Windows Subsystem for Linux actually is, why it exists and how it changed the Windows developer experience forever.
🤔 The Problem WSL Solves
Before WSL, Windows developers who needed Linux tools had a rough time. You either dual-booted (restart every time you need Linux), ran a heavy VM (slow, resource-hungry) or used Cygwin/MSYS (incomplete compatibility). None of these were great.
WSL changes everything by letting you run real Linux binaries directly on Windows — no full VM overhead, no rebooting, no compromises.
WSL 2 runs a real, Microsoft-maintained Linux kernel inside a lightweight VM. It's not emulation — it's the actual thing.
File I/O on the Linux filesystem (ext4 VHD) is blazing fast. No more waiting around for npm install.
Call Windows executables from Linux and vice versa. Share files, environment variables and network ports.
WSLg lets you run Linux GUI apps (Firefox, GIMP, VS Code) with no extra setup. They just... appear.
🏗️ How WSL 2 Works
WSL 2 is architecturally very different from WSL 1. Instead of translating Linux system calls to Windows (like WSL 1 did), WSL 2 runs a full Linux kernel inside a lightweight Hyper-V VM. The VM is so tightly integrated that it feels like a local process, not a virtual machine.
Related Topics
Requirements
Make sure your system can run WSL 2. This is quick — most modern Windows machines are already good to go.
✅ Minimum Requirements
| Feature | Requirement | Your Build Needs |
|---|---|---|
| WSL 2 (basic) | Windows 10 or 11 | Build 19041+ (May 2020) |
| WSLg (GUI apps) | Windows 11 | Build 22000+ or Windows 10 Insider |
| GPU / CUDA | Windows 11 or Win 10 21H2+ | Build 19044+ |
| Mirrored Networking | Windows 11 | WSL 0.67.6+ |
| Sparse VHD | Windows 11 | WSL 2.0.0+ |
🖥️ Check Your Windows Build
Run this in PowerShell to see your Windows version and build number:
Get-ComputerInfo | Select-Object WindowsVersion, OsBuildNumber
🔲 Enable Required Features
WSL 2 needs two Windows features enabled. Run these in PowerShell as Administrator:
# Enable WSL feature dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart # Enable Virtual Machine Platform dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
Related Topics
Installation
Install WSL 2 with a single command. Seriously, it's that easy now.
🚀 One-Command Install
Open PowerShell as Administrator and run:
wsl --install
This installs WSL 2 with Ubuntu as the default distro. Restart your PC when prompted, then Ubuntu will finish setup.
Open PowerShell as Admin. Run wsl --install. Wait for it to finish.
WSL needs a reboot to finish setting up the kernel. Don't skip this.
After reboot, Ubuntu opens automatically. Set your Linux username and password.
Run wsl --version and wsl -l -v to confirm everything is running.
wsl --version wsl -l -v
🐧 Install a Different Distro
# See available distros wsl --list --online # Install a specific one wsl --install -d Debian wsl --install -d kali-linux wsl --install -d Ubuntu-24.04
Related Topics
First Run Setup
WSL is installed. Now let's get your Linux environment production-ready.
On first launch, Ubuntu asks for a username and password. This is your Linux user — separate from your Windows account. Pick anything you like (lowercase recommended).
Always do this first. Keeps your system secure and current.
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl wget git build-essential unzip
uname -r # Should show Linux kernel version whoami # Your Linux username pwd # /home/yourusername
Many devs prefer Zsh with Oh My Zsh for a better shell experience.
sudo apt install -y zsh sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
Related Topics
WSL 1 vs WSL 2
Understanding the difference helps you make the right choice for your workflow.
📊 Feature Comparison
| Feature | WSL 1 | WSL 2 |
|---|---|---|
| Architecture | Syscall translation | Real Linux kernel (Hyper-V) |
| Linux filesystem performance | Slower | ⚡ Much faster |
| Windows filesystem speed | Fast | Slower (cross-OS) |
| Docker support | ❌ No | ✅ Yes |
| GPU / CUDA | ❌ No | ✅ Yes |
| systemd | ❌ No | ✅ Yes (opt-in) |
| Full kernel compatibility | Partial | ✅ Yes |
| WSLg (GUI apps) | ❌ No | ✅ Yes |
| Boot time | Instant | ~1-2 seconds |
🔄 Switch Between Versions
# Set default WSL version for new installs wsl --set-default-version 2 # Switch a specific distro to WSL 2 wsl --set-version Ubuntu 2 # Check current versions wsl -l -v
Related Topics
Distro Management
Install multiple distros, switch between them, back them up and move them around.
🗂️ Lifecycle Commands
# List all installed distros with version and status wsl -l -v # Launch a specific distro wsl -d Debian # Set the default distro wsl --set-default Ubuntu # Stop a specific distro wsl -t Ubuntu # Stop ALL distros (full shutdown) wsl --shutdown # Remove a distro (DELETES ALL DATA) wsl --unregister OldDistro
💾 Backup & Restore
# Export distro to a .tar.gz file wsl --export Ubuntu C:\Backups\ubuntu-backup.tar.gz # Import it back (or to a new machine) wsl --import Ubuntu C:\WSL\Ubuntu C:\Backups\ubuntu-backup.tar.gz --version 2
[user] + default=yourusername to /etc/wsl.conf inside the distro, then run wsl --shutdown.Related Topics
Filesystem
The #1 performance gotcha in WSL — and how to avoid it.
🗺️ Path Mapping
| From | You See | Windows Equivalent |
|---|---|---|
| Linux home | ~/ or /home/user/ | \\wsl$\Ubuntu\home\user\ |
| Windows C drive | /mnt/c/ | C:\ |
| Windows desktop | /mnt/c/Users/Name/Desktop/ | C:\Users\Name\Desktop\ |
| WSL from Explorer | Open Explorer → type \\wsl$ | Directly browse Linux files |
🔄 Path Conversion
# Convert Linux path to Windows path wslpath -w ~/myproject # → \\wsl.localhost\Ubuntu\home\user\myproject # Convert Windows path to Linux path wslpath -u 'C:\Users\Name\Downloads' # → /mnt/c/Users/Name/Downloads # Open current Linux folder in Windows Explorer explorer.exe .
Related Topics
Interoperability
Call Linux commands from PowerShell. Call Windows executables from bash. Share environment variables across worlds.
🪟 → 🐧 Call Linux from Windows
# Run any Linux command from PowerShell wsl ls -la wsl grep -r "TODO" ./src # Pipe between PowerShell and Linux Get-Content file.txt | wsl grep "pattern" wsl cat /etc/hosts | Select-String "localhost"
🐧 → 🪟 Call Windows from Linux
# Open Windows Explorer in current dir explorer.exe . # Open a file in Windows Notepad notepad.exe myfile.txt # Copy text to Windows clipboard echo "hello!" | clip.exe # Run PowerShell from bash powershell.exe -Command "Get-Date"
Related Topics
.wslconfig
Global VM settings that apply to all your WSL distros — tune memory, CPU, networking and more.
📁 Location
Create this file at: C:\Users\YourName\.wslconfig
This file configures the WSL 2 virtual machine globally. Changes take effect after running wsl --shutdown.
⚙️ Full Reference Config
[wsl2] # Max memory for the WSL VM (default: 50% of host RAM) memory=8GB # Swap space swap=4GB # Number of virtual processors (default: same as host) processors=4 # Max VHD disk size diskSizeGB=256 # Networking mode: 'nat' (default) or 'mirrored' (Win11 only) networkingMode=nat # DNS tunneling (useful with VPNs) dnsTunneling=true # Allow Windows Firewall rules to apply in WSL firewall=true # Return unused memory pages to Windows (helps with RAM usage) pageReporting=true # Enable GUI apps (WSLg) guiApplications=true # Enable nested virtualization (for running Docker-in-Docker) nestedVirtualization=false
Related Topics
/etc/wsl.conf
Per-distro configuration. Each distro can have its own settings.
📁 Location
Create/edit inside your distro at: /etc/wsl.conf
Run wsl --shutdown then relaunch your distro to apply changes.
⚙️ Full Reference Config
[boot] # Enable systemd (recommended!) systemd=true # Run a command on WSL start command="" [automount] # Auto-mount Windows drives (/mnt/c etc) enabled=true # Mount options options="metadata,uid=1000,gid=1000,umask=022,fmask=11" [network] # Auto-generate /etc/hosts from Windows hosts file generateHosts=true # Auto-generate /etc/resolv.conf for DNS generateResolvConf=true [interop] # Allow calling Windows executables from Linux enabled=true # Append Windows PATH to Linux PATH appendWindowsPath=true [user] # Default user (important after wsl --import) default=yourusername
Related Topics
Networking
How WSL connects to the network and how to fix common issues.
🔌 NAT Mode (Default)
In NAT mode, WSL gets its own private IP address and shares Windows' internet connection. Ports you open in WSL are accessible from Windows via localhost.
# Find WSL's IP address ip addr show eth0 | grep "inet " # Find Windows host IP from inside WSL ip route show default | awk '{print $3}'
🔧 Fix DNS Issues
# Manual DNS fix sudo tee /etc/resolv.conf <<'EOF' nameserver 1.1.1.1 nameserver 8.8.8.8 EOF # Prevent WSL from overwriting it sudo chattr +i /etc/resolv.conf
Related Topics
systemd
Enable systemd to use service management, timers and native Linux init.
🔧 Enable systemd
# Edit /etc/wsl.conf sudo tee /etc/wsl.conf <<'EOF' [boot] systemd=true EOF # Then in PowerShell: # wsl --shutdown # Then relaunch your distro
✅ Verify & Use
# Verify systemd is PID 1 ps -p 1 -o comm= # Common systemctl commands sudo systemctl start nginx sudo systemctl enable nginx # Auto-start on WSL launch sudo systemctl status nginx journalctl -u nginx -f # Follow logs
Related Topics
VS Code + WSL
The best IDE experience for WSL development. Open WSL projects directly in VS Code from Windows.
Download from code.visualstudio.com. Install normally on Windows, not inside WSL.
In VS Code, press Ctrl+Shift+X, search for "WSL" and install the official Microsoft extension.
# From inside WSL, open current folder in VS Code code . # Or open a specific project code ~/myproject
Related Topics
Docker in WSL 2
Run Docker natively inside WSL 2 without Docker Desktop — lighter, faster, free.
🐋 Install Docker Engine (No Desktop Required)
# Install dependencies sudo apt update sudo apt install -y ca-certificates curl gnupg # Add Docker's GPG key sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg \ | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg # Add the repository echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \ https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \ | sudo tee /etc/apt/sources.list.d/docker.list # Install Docker sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # Run Docker without sudo sudo usermod -aG docker $USER newgrp docker # Start on boot (requires systemd) sudo systemctl enable --now docker
Related Topics
SSH Keys
Generate and manage SSH keys in WSL for GitHub, remote servers and more.
🗝️ Generate a Key
# Generate ed25519 key (recommended) ssh-keygen -t ed25519 -C "[email protected]" # Or RSA (for older systems) ssh-keygen -t rsa -b 4096 -C "[email protected]" # Start ssh-agent and add your key eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519 # Copy public key for GitHub cat ~/.ssh/id_ed25519.pub
🔄 Persistent ssh-agent (auto-start)
# Install keychain, then add to ~/.bashrc or ~/.zshrc
sudo apt install -y keychain
echo 'eval $(keychain --eval --quiet ~/.ssh/id_ed25519)' >> ~/.bashrc
Related Topics
Git Setup
Configure Git properly in WSL — the right user, editor, line endings and Windows Credential Manager.
⚙️ Essential Config
git config --global user.name "Your Name" git config --global user.email "[email protected]" git config --global init.defaultBranch main git config --global core.autocrlf input # Critical for cross-platform git config --global core.editor "code --wait" git config --global pull.rebase false
🪟 Use Windows Credential Manager
# Use Windows Credential Manager for HTTPS auth
git config --global credential.helper "/mnt/c/Program\\ Files/Git/mingw64/bin/git-credential-manager.exe"
Related Topics
GPU & CUDA
Run machine learning workloads inside WSL with full GPU acceleration.
Download and install the latest Game Ready or Studio driver from nvidia.com. Do this on Windows, not inside WSL.
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/x86_64/cuda-keyring_1.1-1_all.deb sudo dpkg -i cuda-keyring_1.1-1_all.deb sudo apt update sudo apt install -y cuda-toolkit
nvidia-smi # Should show your GPU nvcc --version # CUDA compiler version # Test with PyTorch python3 -c "import torch; print(torch.cuda.is_available())"
Related Topics
Performance Tuning
Squeeze every bit of speed out of your WSL setup.
🏎️ Key Tuning Areas
Work in ~/projects, not /mnt/c/. This alone can give 5–10x faster I/O.
Node.js and Vite need lots of file watchers. Increase the kernel limit.
Set memory= in .wslconfig to prevent WSL from using too much RAM.
Tune vm.swappiness and net buffers for server workloads.
🔧 Quick Wins
# Increase inotify watchers (for Vite, Webpack, etc.) echo fs.inotify.max_user_watches=524288 | sudo tee /etc/sysctl.d/99-wsl.conf sudo sysctl --system # Reduce swap pressure echo vm.swappiness=10 | sudo tee -a /etc/sysctl.d/99-wsl.conf # Release cached memory sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches' # Benchmark disk speed dd if=/dev/zero of=/tmp/test bs=1M count=1024 oflag=direct 2>&1 | tail -1
Related Topics
Custom Distros
Import any Linux distro into WSL — Alpine, Arch or your own custom Docker image.
🏔️ Import Alpine Linux
# Download Alpine minirootfs wget https://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/x86_64/alpine-minirootfs-3.21.0-x86_64.tar.gz # In PowerShell: import it # wsl --import Alpine C:\WSL\Alpine .\alpine-minirootfs-3.21.0-x86_64.tar.gz --version 2 # wsl -d Alpine
🐳 Build from Docker Image
# Build and export a Docker image as a WSL distro docker build -t my-distro . docker run --name tmp-distro my-distro true docker export tmp-distro | gzip > my-distro.tar.gz docker rm tmp-distro # In PowerShell # wsl --import MyDistro C:\WSL\MyDistro .\my-distro.tar.gz --version 2
Related Topics
GUI Apps with WSLg
Run Linux graphical apps seamlessly on Windows. No X server needed.
🎨 Enable & Install GUI Apps
First enable in .wslconfig: guiApplications=true (enabled by default on Windows 11).
# Install some Linux GUI apps sudo apt install -y gedit gimp vlc x11-apps # Launch them — they appear as Windows windows! gimp & xclock & # Classic X11 test # Test audio sudo apt install -y pulseaudio-utils paplay /usr/share/sounds/alsa/Front_Left.wav
Related Topics
Mirrored Networking
WSL gets the same IP as Windows. Ports are instantly accessible. VPN-aware. IPv6 native.
🚀 Enable Mirrored Mode
Add to C:\Users\YourName\.wslconfig:
[wsl2] networkingMode=mirrored dnsTunneling=true
Then run wsl --shutdown and relaunch. Verify with:
hostname -I # Should match Windows IP python3 -m http.server 8080 & # Access localhost:8080 from Windows browser instantly
Related Topics
VHD Storage Management
Manage the virtual disk that stores your WSL filesystem — resize, compact and monitor it.
📊 Check Disk Usage
# Total disk usage df -h / # What's using the most space? du -sh /* 2>/dev/null | sort -rh | head -20 # Find large files find / -size +500M -not -path "/proc/*" 2>/dev/null # Clean apt cache sudo apt clean && sudo apt autoremove -y
💨 Enable Sparse VHD (Windows 11)
# Sparse VHD automatically returns freed space to Windows
wsl --manage Ubuntu --set-sparse true
Related Topics
Common Issues
Fast solutions to the most frequent WSL problems.
❌ WSL Won't Start
wsl --shutdown wsl --update wsl
❌ Error 0x80370102 (Virtualization Disabled)
wsl --update.❌ No Internet in WSL
# Test connectivity ping -c 3 8.8.8.8 # If ping works but DNS fails, fix resolv.conf echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf sudo chattr +i /etc/resolv.conf # Or try switching to mirrored networking in .wslconfig
❌ Docker iptables Error
# Switch to legacy iptables
sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
sudo service docker restart
Related Topics
Logs & Debugging
Find and read the right logs when things go wrong.
📋 Linux Logs
# Kernel messages (including WSL-specific) dmesg | tail -50 # systemd journal (if systemd enabled) journalctl -xe journalctl -u docker --since "10 minutes ago" # WSL status overview wsl --version wsl --status wsl -l -v
🪟 Windows Event Logs
Get-WinEvent -LogName Microsoft-Windows-Lxss-Manager/Operational -MaxEvents 20 | Select-Object TimeCreated, Message | Format-List
Related Topics
Reset & Repair
Nuclear options — when nothing else works. Use only as last resort.
wsl --export Ubuntu C:\backup.tar.gz🔄 Reset a Distro
# Back up first! wsl --export Ubuntu C:\backup-$(Get-Date -Format yyyyMMdd).tar.gz # Delete and reinstall wsl --unregister Ubuntu wsl --install -d Ubuntu
💣 Full WSL Reset
# Disable WSL features dism.exe /online /disable-feature /featurename:Microsoft-Windows-Subsystem-Linux dism.exe /online /disable-feature /featurename:VirtualMachinePlatform # Restart, then re-enable dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart # Restart again, then wsl --update wsl --install
Related Topics
Command Cheatsheet
Every important WSL command, organized and copyable.