Skip to content
Chapter 3Lesson 7

VS Code as a team artifact

Set up VS Code as the course's editor and commit its configuration to the repo so every teammate shares the same formatter, extensions, and TypeScript version.

A teammate joins the repo on Monday and opens it in their editor, which already has their personal “format on save with Prettier defaults” turned on. They hit save on one file, and the diff comes back as two hundred lines of whitespace changes. Their formatter, their indentation rule, and their auto-organize-imports behaviour all disagree with the project’s, so nobody can review the actual change. The fix isn’t a code-of-conduct doc asking everyone to disable their personal settings. It’s three files the repo commits so the editor reads the project’s rules instead of the developer’s.

Every lesson so far in this chapter ran in the TS Playground in your browser. From the next lesson on, you’ll write .ts files on disk and run them locally. This lesson sets up the editor, VS Code, along with the team-shared config that comes with it, so the next lesson opens against a known setup. Node 24 LTS, the .mise.toml that pins it, and the tsconfig.json that drives the compiler all arrive in the lessons right after this one. Here, the only concern is the editor and the files the repo owns.

VS Code is the 2026 default for SaaS work. It has the broadest extension ecosystem, and the stack’s official LSP s target it first: Biome, Tailwind, and TypeScript. It’s free and cross-platform, and it’s the editor every junior teammate either already has or can install in five minutes. Three alternatives are worth naming, each with the one thing that would change the decision:

  • Cursor is built around AI-first workflows, and this course deliberately spends its time elsewhere. Advice on how to direct AI goes stale faster than the course can ship, while the durable engineering the course covers does not, so that’s where the pages go.
  • Zed is faster to type in than most people would ever notice, but its LSP support for this stack still lags behind VS Code’s.
  • Neovim pays off if you have deep keyboard fluency, and building that fluency takes more time than a working dev usually has to spare for the gain it returns.

The course commits to VS Code. Install it from the official download page; the installer is a single click on every platform.

Download VS Code
code.visualstudio.com

Official installers for macOS, Windows, and Linux.

Themes, icon packs, vim modes, and productivity bundles are out of scope here. Install whatever you like on the side; what follows is the set the repo needs the whole team to share. There are six of them, and each one earns its place for a specific reason.

Biome

biomejs.biome is the lint-and-format LSP for JS, TS, and JSON. It installs the project’s formatter, so the next time you hit save it’s that formatter that runs, not the editor’s default.

Tailwind CSS IntelliSense

bradlc.vscode-tailwindcss gives you class-name autocomplete, a hover preview of the generated CSS, and design-system linting. It pays off from the React unit onward, and installing it now means you never have to come back for it.

EditorConfig for VS Code

EditorConfig.EditorConfig reads .editorconfig so that teammates on other editors, such as IntelliJ or Neovim, honour the same indent, line-ending, and final-newline rules.

GitLens

eamodio.gitlens shows inline blame on the line under the cursor, plus file history and side-by-side compare. Code review starts with “who wrote this and why,” and GitLens puts that question one click away.

Error Lens

usernamehw.errorlens pulls TypeScript and Biome diagnostics inline, right next to the line that triggered them. That tightens the feedback loop on every save, since you no longer have to hover to see what’s wrong.

Pretty TypeScript Errors

yoavbls.pretty-ts-errors reshapes long structural type errors into something you can read in one pass. It earns its weight the first time a Drizzle or Zod inferred type expands into a wall of brackets.

Install each one by clicking through the marketplace link in VS Code, or by running code --install-extension <id> in a terminal; either way works. The extensions.json file in the next section turns this into a one-click prompt the next time anyone clones the repo, so this is the last time you have to install these by hand.

GitLens is the one extension whose payoff isn’t obvious from a single setting. Its inline blame, CodeLens, and file-history views are the kind of tooling code review leans on heavily, so the short tour below is worth watching.

Three files live in the repo so that every editor on the team behaves the same way. .editorconfig sits at the root for any editor that honours the spec. .vscode/extensions.json makes VS Code prompt to install what the project needs. .vscode/settings.json holds the workspace-only overrides that pin the formatter, the on-save actions, and the TypeScript SDK choice. Personal preferences such as theme, font, and keybindings never live in these files.

Create the three files in the order below. Each one settles a specific layer of the editor’s behaviour.

  1. .editorconfig at the repo root. This is a six-rule file that every modern editor honours, so the most basic things, like indent, line endings, and file encoding, never come down to whose machine you happen to be on.

    .editorconfig
    root = true
    [*]
    indent_style = space
    indent_size = 2
    end_of_line = lf
    charset = utf-8
    insert_final_newline = true
    trim_trailing_whitespace = true

    The rules cover a 2-space indent, LF line endings (so a Windows teammate doesn’t introduce CRLF), UTF-8 encoding, a final newline at the end of every file, and trimmed trailing whitespace. The IntelliJ family and Neovim honour these natively, and VS Code does so through the EditorConfig extension above. Biome reads .editorconfig for its indent and line-ending settings too. That gives you one source of truth and no duplicate config to keep in sync once biome.json arrives later in the course.

  2. .vscode/extensions.json with the recommendation list. This is the marketplace IDs of the six extensions from the previous section, in the same order.

    .vscode/extensions.json
    {
    "recommendations": [
    "biomejs.biome",
    "bradlc.vscode-tailwindcss",
    "EditorConfig.EditorConfig",
    "eamodio.gitlens",
    "usernamehw.errorlens",
    "yoavbls.pretty-ts-errors"
    ]
    }

    When a teammate clones the repo and opens the folder in VS Code, the editor prompts them to install any of these six they don’t already have. That turns the rule into something the tooling enforces: “I forgot to install Biome” is hard to leave unfixed when the editor asks every time.

  3. .vscode/settings.json with the workspace overrides. These are the settings the project needs, scoped to this workspace only. Nothing personal goes in here.

    .vscode/settings.json
    {
    "editor.formatOnSave": true,
    "editor.defaultFormatter": "biomejs.biome",
    "[css]": {
    "editor.defaultFormatter": "biomejs.biome"
    },
    "editor.codeActionsOnSave": {
    "source.fixAll.biome": "explicit",
    "source.organizeImports.biome": "explicit"
    },
    "typescript.tsdk": "node_modules/typescript/lib"
    }

    The first pair, editor.formatOnSave and editor.defaultFormatter, sends every save through Biome instead of whatever each teammate happens to have set as their personal default. The per-language [css] override is here for the day Tailwind v4 code arrives later in the course. It isn’t doing anything yet, but pinning it now means you don’t have to come back to this file.

    editor.codeActionsOnSave lists the two Biome actions that run on save. source.fixAll.biome applies safe auto-fixes, and source.organizeImports.biome sorts and dedupes imports. Both use the "explicit" string form, which has been mandatory since VS Code 1.83. The older true and false values stopped working a couple of years ago, so any tutorial that still shows them is out of date.

    typescript.tsdk points the editor at the workspace TypeScript, meaning the tsc installed inside the project’s node_modules. This matters because every fresh open of a TS project shows a “Use Workspace Version” toast, asking whether the editor should switch from its bundled TypeScript to the one the project pins. Setting this here answers that prompt in advance, so the editor uses the same compiler your build does. The node_modules/typescript path doesn’t exist yet, since installing the dependency is a later lesson’s job. Pinning it now is harmless, and the editor picks it up the moment the dependency lands.

Below are six settings, each with two possible homes. Drop each one into the place it belongs: the repo’s .vscode/settings.json, which every teammate gets, or your own User settings, which only you see. The rule is the one the callout above states. If the project needs the setting, it’s workspace; if you prefer the setting, it’s user.

Decide where each setting belongs — the repo's `.vscode/settings.json` or the developer's User settings. Drag each item into the bucket it belongs to, then press Check.

Workspace (.vscode/settings.json) Lives in the repo, everyone gets it.
User (machine-local) Lives in your profile, nobody else sees it.
editor.formatOnSave enabled
workbench.colorTheme: "GitHub Dark"
editor.fontFamily: "JetBrains Mono"
editor.codeActionsOnSave with Biome actions
editor.lineHeight: 1.6
editor.defaultFormatter set to biomejs.biome for the workspace

These three references are worth bookmarking. Each is the canonical source on one of the topics this lesson touched.