Search Tech Journey

Find topics, journeys and posts

6-month learning plan1 / 130
back to blog
systemsbeginner 15m read

S001 · Dev Environment — Linux/WSL, Terminal, VS Code

Baseline setup so you never hit an environment wall.

Module M00: Setup & Tools · Session 1 of 130 · Track: Setup 🧰

What you'll be able to do after this session

  • Explain Dev Environment to a friend in one minute, out loud, no notes.
  • Recognise it when you see it in real code / systems / papers.
  • Complete the hands-on exercise at the end without looking up help.

Prerequisites

If you can't answer these in 30 seconds each, redo the linked session first:

None.


Pre-read (skim before the session)


(a) Intuition · 5 min

The one-paragraph mental model. Why this concept exists, what problem it solves, and the analogy that makes it stick.

In one sentence: Baseline setup so you never hit an environment wall.

Imagine you're a chef who just moved into a new kitchen. Before you cook anything, you sharpen the knives, arrange the spices where your hand can find them without looking, and make sure the stove actually turns on. That's a dev environment. It's the boring 90 minutes that saves you 90 hours of "why doesn't this work on my machine" over the next 6 months.

Historically, "real" software was built on Unix (Linux/macOS) and hobby software on Windows — so almost every tutorial, error message, and Stack Overflow answer assumes a Unix-style terminal. WSL (Windows Subsystem for Linux) is Microsoft's admission of that: it gives you a genuine Ubuntu inside Windows, sharing the same filesystem. Combined with VS Code — a free editor from Microsoft that speaks to that Linux transparently — you get the best of both worlds without dual-booting.

Gotcha to carry forever: always keep your code inside the Linux filesystem (~/projects/…), never on the Windows drive (/mnt/c/…). Cross-filesystem file I/O is 10–100× slower and will silently ruin your first "why is this so slow?" debugging session.


(b) Visual walkthrough · 15 min

Diagrams, worked examples, step-by-step visuals.

Here's how the pieces stack up on a Windows box. On macOS/Linux, delete the WSL layer — everything else is identical.

Worked example — install path on Windows (once, ever):

StepCommand / actionWhat it does
1wsl --install in PowerShell (admin)Installs Ubuntu + WSL 2 kernel, reboots.
2Set a Linux username + password when promptedThis is your Linux identity, separate from Windows.
3sudo apt update && sudo apt upgrade -yPulls the latest package index and upgrades.
4Install VS Code on Windows side, then add the WSL extensionThe editor stays on Windows; the code lives in Linux.
5From Ubuntu shell: code . inside a project folderLaunches VS Code connected to WSL — status bar shows "WSL: Ubuntu".

Worked example — first project directory:

~/projects/                     ← always here, never /mnt/c
├── learning/                   ← your 130-session repo lives here
│   └── s001/
│       └── hello.py
└── .config/                    ← dotfiles go here later

The mental picture to hold: VS Code is a windowpane on Windows; your code, tools, and terminal all live behind that pane in Linux. When something feels weird — usually file permissions, line endings (CRLF vs LF), or slow file watchers — 90 % of the time it's because a file accidentally crossed the pane.


(c) Hands-on · 20 min

Code you type and run. Not pseudo-code — real, runnable, copy-pasteable.

Run this end-to-end on a fresh Ubuntu/WSL/macOS terminal. It creates your first project, installs Python via uv (the modern, fast package manager), and prints a smoke test.

#!/usr/bin/env bash
set -euo pipefail
 
# 1. Create the workspace root you'll use for the whole 6 months.
mkdir -p ~/projects/learning/s001
cd ~/projects/learning/s001
 
# 2. Install uv (fast Python installer / venv manager) if missing.
if ! command -v uv >/dev/null 2>&1; then
  curl -LsSf https://astral.sh/uv/install.sh | sh
  export PATH="$HOME/.local/bin:$PATH"
fi
 
# 3. Pin a Python version + create an isolated venv.
uv python install 3.12
uv venv .venv --python 3.12
source .venv/bin/activate
 
# 4. Write your first script.
cat > hello.py <<'PY'
import sys, platform, os
print("python :", sys.version.split()[0])
print("os     :", platform.system(), platform.release())
print("cwd    :", os.getcwd())
print("shell  :", os.environ.get("SHELL", "unknown"))
print("hello, dev environment ✅")
PY
 
# 5. Run it.
python hello.py
 
# 6. Save what you installed so future-you can reproduce it.
uv pip freeze > requirements.txt
echo "--- requirements.txt ---"
cat requirements.txt

Checklist — what to observe:

  1. uv python install 3.12 downloads Python in seconds, not minutes.
  2. source .venv/bin/activate changes your prompt to show (.venv) — that's isolation working.
  3. python hello.py prints your OS, Python version, and current directory.
  4. which python inside the venv points to .venv/bin/python, NOT /usr/bin/python3.
  5. requirements.txt is empty (you haven't installed anything yet) — that's expected.

Try this modification: add a second line to hello.py that imports requests, run it, watch it fail with ModuleNotFoundError, then run uv pip install requests and re-run. You've just experienced the entire "why do we use virtual environments" argument in 30 seconds.


(d) Production reality · 10 min

How this shows up in real systems, gotchas, war stories, common bugs.

Every senior engineer has a horror story that starts with "it worked on my laptop." The usual culprits are all environment issues, and they're all preventable.

War story 1 — the CRLF bug. A team ships a bash script from Windows to a Linux server. It fails with bad interpreter: /bin/bash^M. That ^M is a carriage return Windows added to every line. Fix: git config --global core.autocrlf input on the Windows machine and .gitattributes with * text=auto eol=lf in the repo. Every real team does this on day one.

War story 2 — the "slow filesystem" mystery. A Next.js dev at Microsoft complained his hot-reload took 8 seconds. He'd cloned the repo to /mnt/c/work/ (Windows drive, accessed through WSL). Moving it to ~/work/ (native ext4) dropped reload to 200 ms. This is one of the top-3 WSL support tickets internally.

War story 3 — the venv you forgot to activate. You install pandas, run your script, get ModuleNotFoundError: pandas. You just installed pandas into your system Python because your venv wasn't active. Pro teams enforce this with tools like direnv (auto-activates on cd) or uv run script.py (runs inside the project's venv without you thinking about it).

How top teams handle it: Google, Microsoft, and Netflix ship devcontainers — a JSON file in the repo (.devcontainer/devcontainer.json) that describes the exact Ubuntu image, tool versions, and VS Code extensions. New engineer clones the repo, VS Code prompts "Reopen in container?", and 3 minutes later they have the exact environment everyone else has. Zero "works on my machine" tickets. As you grow, adopt devcontainers early — Session S056 will cover Docker, which is the foundation for this.

The one rule: if you can't reproduce your setup from a script in under 15 minutes on a fresh machine, your environment is a liability.


(e) Quiz + exercise · 10 min

  1. What is the difference between WSL 1 and WSL 2, in one sentence?
  2. Why should your code live in ~/projects/ and not /mnt/c/…?
  3. What problem does a virtual environment solve that installing packages globally does not?
  4. What does chmod +x script.sh do, and why do fresh scripts need it before you can run them?
  5. Given a coworker's project with a requirements.txt and no venv, what is the exact 3-command sequence to reproduce their environment?

Stretch problem (connects forward to S002): Take the ~/projects/learning/s001/ folder you created above, initialise a Git repository inside it, add a .gitignore that excludes .venv/ and __pycache__/, then commit hello.py and requirements.txt. Explain in one sentence why the .venv/ directory must never be committed.


Explain-out-loud test

If you can't teach these 3 things to a friend without notes, redo the session:

  1. What is Dev Environment? (one sentence, no jargon)
  2. When would you use it? (one concrete example)
  3. When would you NOT use it? (one anti-pattern)

What comes next


Part of a 130-session evergreen learning series. Session structure: (a) intuition · (b) visual walkthrough · (c) hands-on · (d) production reality · (e) quiz + exercise. Duration: 60 minutes.

More from M00 · Setup & Tools

all modules →
  1. 002Git & GitHub — Commits, Branches, PRs
  2. 003The Command Line — bash, pipes, grep, jq
  3. 004Reading Docs & Effective Googling — the Meta-Skill