VS Code
Status: 🟩 COMPLETE (🟦 LIVING — VS Code ships changes monthly) Last updated: 2026-06-19 Plain-English tagline: Microsoft’s free code editor — the dominant tool for modern web development, with built-in TypeScript, terminal, debugger, and Git, plus a massive extension ecosystem that handles almost any specific need.
In plain English
Visual Studio Code (universally called VS Code, sometimes abbreviated to vscode) is a code editor: a program for reading, writing, and navigating code. It’s NOT an IDE in the heaviest sense (no built-in compilers, no opinionated project structure), but it’s much more than a plain text editor. It comes with:
- Syntax highlighting for ~100 languages out of the box
- IntelliSense (autocomplete) that’s exceptional for TypeScript/JavaScript
- Built-in terminal
- Built-in Git client
- Built-in debugger
- An extension marketplace with ~50,000 published extensions
It’s free, cross-platform (Windows, macOS, Linux), and Microsoft updates it monthly. Since ~2018, it has been the dominant code editor in JavaScript/TypeScript-land. The 2025 Stack Overflow Developer Survey shows ~75% of web developers using it daily.
The closest competitors in 2026:
- Cursor — a fork of VS Code with deeper AI integration (chat, multi-file edits, agentic flows). Free tier; paid Pro tier. Increasingly common among AI-heavy developers.
- Zed — a newer, faster, Rust-based editor with collaborative features. Smaller ecosystem.
- JetBrains WebStorm / IntelliJ — paid; better refactoring; heavier; favored in enterprise.
- Neovim — terminal-based; for terminal natives.
For a non-programmer building modern webapps with AI assistance (George’s profile), Cursor or VS Code are the right defaults — both ship with great AI workflows; Cursor is more polished, VS Code is more universal.
This entry focuses on VS Code. Most of what’s here applies to Cursor too (since it’s a VS Code fork).
Why it matters
Three concrete reasons VS Code is foundational:
-
It’s the editor every tutorial assumes. If you’re following a Next.js / React / TypeScript tutorial in 2026, the screenshots and shortcuts are VS Code. Familiarity saves friction.
-
TypeScript support is unrivalled. Microsoft makes both VS Code and TypeScript — IntelliSense, “Go to Definition,” refactoring, and inline diagnostics are deeply integrated. The same code in a plain editor would lose much of its safety.
-
The extension ecosystem covers everything. Specific frameworks, tools, languages, linters, formatters, debuggers, AI assistants — each has an extension. Most are free and well-maintained.
The trade-off: VS Code is heavier than a plain text editor and lighter than a full IDE. For very large codebases (~1M+ lines), it can feel sluggish. For typical webapp projects (10k-100k lines), it’s responsive and rich.
The mental model
Think of VS Code as four overlapping layers:
- The editor — where you read and write code
- The activity bar — left side, with Explorer (files), Search, Source Control, Run/Debug, Extensions
- The panel — bottom, with Terminal, Problems (errors/warnings), Output, Debug Console
- The status bar — bottom edge, with Git branch, errors count, language, line/column
Most daily work happens in the editor + terminal + Git panel. Everything else is one click away.
The two killer shortcuts:
- Cmd/Ctrl+P — quick open by filename. Type any part of a filename; pick from the list. Faster than navigating the Explorer tree.
- Cmd/Ctrl+Shift+P — command palette. Every command in VS Code (and every extension’s commands) is searchable here. “Toggle dark mode,” “Format document,” “Git: Commit,” “Reload window,” etc.
Master those two shortcuts and you replace 80% of mouse usage.
A solid baseline settings.json
VS Code is configurable. Settings live in Code → Preferences → Settings (macOS) or File → Preferences → Settings (Windows/Linux). The JSON view (Preferences: Open User Settings (JSON) from the command palette) is where power users live.
A practical baseline for modern Next.js / TypeScript work:
{
// Editor
"editor.fontSize": 14,
"editor.fontFamily": "'JetBrains Mono', 'Geist Mono', Menlo, Consolas, monospace",
"editor.fontLigatures": true,
"editor.lineHeight": 1.6,
"editor.tabSize": 2,
"editor.insertSpaces": true,
"editor.minimap.enabled": false,
"editor.bracketPairColorization.enabled": true,
"editor.guides.bracketPairs": "active",
"editor.cursorBlinking": "smooth",
// Formatting on save
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.organizeImports": "explicit"
},
// Files
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true,
"files.eol": "\n",
"files.autoSave": "onFocusChange",
"files.exclude": {
"**/.next": true,
"**/node_modules": true
},
// Terminal
"terminal.integrated.fontSize": 13,
"terminal.integrated.fontFamily": "'JetBrains Mono', monospace",
"terminal.integrated.defaultProfile.windows": "PowerShell",
"terminal.integrated.defaultProfile.osx": "zsh",
// TypeScript
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true,
"typescript.preferences.importModuleSpecifier": "non-relative",
"typescript.updateImportsOnFileMove.enabled": "always",
"typescript.inlayHints.parameterNames.enabled": "literals",
// Search
"search.exclude": {
"**/.next": true,
"**/node_modules": true,
"**/dist": true,
"**/build": true,
"**/.git": true,
"**/coverage": true
},
// Git
"git.autofetch": true,
"git.confirmSync": false,
"git.enableSmartCommit": true,
// Theme
"workbench.colorTheme": "Default Dark Modern",
"workbench.iconTheme": "vscode-icons"
}A few highlights:
editor.formatOnSave: true— every save runs Prettier. Code is always formatted.source.fixAll.eslint— auto-fixes ESLint issues on save (unused imports, etc.).source.organizeImports— sorts imports automatically.typescript.tsdk: node_modules/typescript/lib— uses the project’s TypeScript version, not VS Code’s bundled one. Critical: ensures the editor’s diagnostics matchtscin CI.files.eol: "\n"— Unix line endings (LF). On Windows, default is CRLF — this normalizes.search.exclude— speeds up project-wide search by ignoring build artifacts.
This setup is roughly equivalent to a Bible Quest-style project default.
The extensions that actually pay off
VS Code has ~50,000 extensions. You need ~10. The high-value list:
| Extension | What it does |
|---|---|
| Prettier - Code formatter | The dominant formatter; works with editor.formatOnSave |
| ESLint | In-editor lint warnings/errors |
| Tailwind CSS IntelliSense | Autocomplete + hover docs for Tailwind classes |
| GitLens | Git integration on steroids (blame inline, commit history per line) |
| Error Lens | Shows error/warning messages inline on the offending line |
| Code Spell Checker | Spell-check in code (catches typos in variable names, comments) |
| Pretty TypeScript Errors | Reformats verbose TS errors into something readable |
| Auto Rename Tag | Rename one side of an HTML/JSX tag, the other follows |
| vscode-icons | Distinct file-type icons in the Explorer |
| GitHub Pull Requests and Issues | View / review / create PRs in VS Code |
For AI assistance:
- GitHub Copilot — Microsoft’s AI assistant; inline suggestions + chat
- Claude Dev / Continue / Cline — Claude / OpenAI / open-model alternatives
- Cursor — separate editor, but worth knowing about as an alternative
For specific stacks, add:
- Supabase VS Code extension — schema browsing, SQL execution
- Prisma — if using Prisma
- MDX — if writing MDX content
- YAML — for
.github/workflows/*.ymlfiles
Avoid extension bloat. Every extension is a startup cost. Pick the ones you actually use; uninstall the rest periodically.
The shortcuts worth memorizing
Cmd/Ctrl + P Quick open file by name
Cmd/Ctrl + Shift + P Command palette
Cmd/Ctrl + Shift + F Search across the project
Cmd/Ctrl + , Settings
Cmd/Ctrl + B Toggle file explorer
Cmd/Ctrl + ` Toggle integrated terminal
Cmd/Ctrl + J Toggle bottom panel
Cmd/Ctrl + / Toggle line comment
Cmd/Ctrl + D Add cursor at next occurrence (multi-cursor)
Cmd/Ctrl + Shift + L Add cursor at ALL occurrences
Cmd/Ctrl + L Select current line
Alt + ↑/↓ Move line up/down
Shift + Alt + ↑/↓ Copy line up/down
Alt + Click Add cursor at click position
Cmd/Ctrl + F Find in file
Cmd/Ctrl + H Find + Replace in file
F2 Rename symbol (rename everywhere it's used)
F12 Go to definition
Cmd/Ctrl + Click Same as F12
Alt + F12 Peek definition (popup, no navigation)
Shift + F12 Find all references
Cmd/Ctrl + K, Z Zen mode (focus mode)
Cmd/Ctrl + K, S Open keyboard shortcuts
The 4-5 you’ll use constantly: Cmd+P, Cmd+Shift+P, Cmd+F, Cmd+/, F2 (rename).
Workspaces & multi-root projects
A workspace in VS Code is just “the folder you opened.” code /path/to/project opens that folder as the workspace.
For more advanced setups, a .code-workspace file can include multiple folders:
{
"folders": [
{ "path": "./apps/web" },
{ "path": "./apps/admin" },
{ "path": "./packages/shared" }
],
"settings": {
"editor.tabSize": 2
}
}Opening this .code-workspace shows all three folders in one window. Useful for monorepos.
For typical solo projects, just open the project folder; you don’t need a workspace file.
Project-level settings
Settings can live in .vscode/settings.json inside your project. These OVERRIDE user-level settings for that project specifically.
A typical .vscode/settings.json for a Next.js project:
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"typescript.tsdk": "node_modules/typescript/lib",
"tailwindCSS.experimental.classRegex": [
["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"],
["cx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
]
}Commit .vscode/settings.json to git. Every contributor (and Claude Code) gets the same baseline.
You can also commit .vscode/extensions.json recommending specific extensions:
{
"recommendations": [
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"bradlc.vscode-tailwindcss",
"eamodio.gitlens"
]
}When someone opens the project, VS Code prompts them to install missing recommended extensions. A small UX win for team projects.
Integrated terminal
VS Code’s terminal is a full shell embedded in the window. Open with Ctrl+` (backtick).
What you can do:
- Run
npm run devand see output without leaving the editor - Split terminals (multiple shells side by side)
- Pin one terminal for the dev server, another for git commands
- Set the default shell per OS in settings
- Switch between PowerShell, Bash, zsh, etc. via the dropdown
The terminal respects your project’s .envrc (if you use direnv) and PATH overrides. It’s the same as opening a separate Terminal app and cd-ing to your project — just integrated.
For Windows specifically: the default profile is PowerShell. Git Bash, WSL bash, and cmd are all available via the profile dropdown. See Windows dev environment.
Source control (Git) in VS Code
The Source Control panel (Cmd/Ctrl+Shift+G) is a graphical Git client:
- See changed files
- Stage / unstage hunks (chunks of changes) inline
- View diffs side-by-side
- Commit with a message
- Push, pull, fetch
- View branch history
- Resolve merge conflicts with built-in 3-way merge view
For most operations, the panel is faster than the terminal. For complex git surgery (rebases, cherry-picks, reflog), use the terminal.
GitLens (extension) supercharges this: inline blame (“this line by George, 3 weeks ago, commit abc123”), file history navigation, comparison views.
Debugging
VS Code has a built-in JavaScript/TypeScript debugger. Set breakpoints by clicking the gutter (left of line numbers). Hit F5 to start debugging.
For Next.js specifically, the debug configuration in .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Next.js: debug full stack",
"type": "node-terminal",
"request": "launch",
"command": "npm run dev",
"serverReadyAction": {
"pattern": "started server on .+, url: (https?://.+)",
"uriFormat": "%s",
"action": "debugWithChrome"
}
}
]
}Hit F5. Next.js starts, Chrome opens to localhost:3000, breakpoints work in both server and client code. The integration is best-in-class.
In practice, many AI-era developers don’t use the debugger as heavily as they used to — console.log + reading the output is enough for most cases. But for tricky bugs, the debugger is still the right tool.
A concrete example: opening Bible Quest in VS Code
cd C:\Users\georg\st-marks-bible-quest
code .code . opens the current directory in VS Code. (Requires the code CLI to be installed — on macOS, run “Shell Command: Install ‘code’ command in PATH” from the command palette.)
VS Code opens. Activity bar shows file explorer. Bottom shows terminal (run npm run dev). Right shows the file currently open. Status bar at the bottom shows the Git branch.
Type Cmd+P, type home, hit Enter — opens app/page.tsx. Cmd+/, the line comments out. F2 on a function name, type a new name, hit Enter — renames everywhere it’s referenced. Cmd+Click on a <Button> component — jumps to its definition. Cmd+Shift+F, type “supabase”, see every place “supabase” appears across the project.
That’s an hour into using VS Code. The rest is muscle memory and gradual extension adoption.
Cursor — the AI-native fork
Cursor is a fork of VS Code optimized for AI workflows. Settings, extensions, and shortcuts are nearly identical. The differences:
- Built-in Composer (multi-file AI edits)
- Built-in Chat (Cmd+L) for asking questions about code
- Tab-complete-aware AI that uses Claude / GPT models for inline suggestions
- Agent mode — let AI run multi-step tasks
- Free tier + Pro tier ($20/mo)
Cursor’s value prop: “VS Code but with AI baked deeper.” For developers using AI heavily (which describes George’s workflow), Cursor is often more frictionless than VS Code + Copilot extension.
The catch: Cursor is closed-source (only the VS Code fork base is open). Privacy / telemetry trade-offs differ from VS Code. Settings sync separately.
Either tool works. Pick based on workflow preference; switching between them is easy.
Common gotchas
-
Don’t forget
typescript.tsdk: node_modules/typescript/lib. Without it, VS Code uses ITS bundled TypeScript version, not your project’s. Diagnostics will diverge from CI. -
Extensions slow down startup. A laptop with 50 extensions installed takes noticeably longer to open files. Audit periodically; uninstall the unused.
-
Workspace settings override user settings. A
.vscode/settings.jsonin a project wins. Be aware when settings feel “wrong” — check the workspace file first. -
Format on save can fight with itself. If TWO formatters compete (Prettier vs Beautify, say), your file may be reformatted twice on each save. Set
editor.defaultFormatterexplicitly. -
The “Save Without Formatting” command exists. Cmd+K Cmd+S — useful when you genuinely don’t want Prettier to touch a file.
-
codecommand not in PATH. On macOS, install via command palette. On Windows, the installer asks; if you skipped it, reinstall or set PATH manually. -
Git Bash and PowerShell are different shells. A
npm installworks in both, but bash-specific commands (export, heredocs) don’t work in PowerShell, and vice versa. See PowerShell vs Bash. -
VS Code’s “Open Recent” can leak repos. If you open multiple projects, the recent list grows. Manually prune for privacy.
-
The Explorer file watcher can hammer disks. Large
node_modulescause excessive file-watcher events. Thefiles.watcherExcludesetting prevents this; modern defaults handle it, but old configs may not. -
GitLens is amazing AND noisy. Default settings show inline blame on every line. Many users disable inline blame and keep only the “blame this line” hover. Tune to taste.
-
Multiple TypeScript versions in one workspace = drama. If two packages in a monorepo declare different TypeScript versions, VS Code picks one. Use a workspace-level TypeScript version.
-
Auto-saving + format-on-save is opinionated. Saves trigger format which can shift cursor position mid-edit.
files.autoSave: "onFocusChange"(only save when leaving the file) is a popular compromise. -
The integrated terminal is NOT exactly the same as your system terminal. PATH, env vars, profile scripts may differ. Set
terminal.integrated.env.*explicitly for known differences. -
Long files slow down IntelliSense. A 5,000-line component slows everything. Refactor into smaller files.
-
Crash recovery is good, not perfect. VS Code recovers most unsaved work; not always. Save frequently; commit often.
-
Live Share (Microsoft’s pair-programming feature) is excellent for collaborative debugging. Underused.
-
The “Welcome” tab can be turned off.
workbench.startupEditor: "none"removes it. -
Theme matters for long hours. Dark themes reduce eye strain in low light. Default Dark Modern (2023+) is a good neutral choice. Avoid “fun” themes for production work — color choices should be informative, not decorative.
-
Font choice matters for code reading. Monospace fonts with ligatures (JetBrains Mono, Fira Code, Geist Mono) make
=>,!=,&&, etc. render as nicer glyphs. Highly recommended. -
The minimap (right side) is divisive. Useful for some, distracting for others. Disable with
editor.minimap.enabled: falseif it bothers you. -
The “breadcrumbs” bar (top of editor) is useful for jumping around large files. Show with
breadcrumbs.enabled: true. -
Settings sync is built in. Sign in with GitHub/Microsoft — your settings, extensions, keybindings sync across machines.
-
The “Restricted Mode” prompt appears when you open a folder you’ve never opened. It limits some extension behavior for security. Trust the folder if it’s your own code.
-
AI-generated code may not match your formatting. Prettier on save fixes most; some AI generations include intentional formatting (e.g. multi-line function signatures) that fight Prettier. Adjust Prettier config rather than the AI output.
-
Settings JSON has comments. VS Code’s JSON parser accepts
//and/* */comments. Standard JSON doesn’t. This sometimes confuses outside tools that read VS Code settings. -
Extension marketplace has malicious entries. Rare but happens. Stick to popular, verified extensions; check publisher and download counts.
-
code-serverandvscode.devlet you run VS Code in a browser. Useful for remote development; same UI, fewer extensions. -
Tabs vs spaces battles are settled by Prettier in modern projects. Spaces (2) is the JS/TS default. Pick once; don’t relitigate.
-
AI tools sometimes leak project-specific paths into edits. Watch for hardcoded
C:\Users\...paths in generated code. Use environment-relative paths.
See also
- npm & package managers 🟩 — what VS Code runs in its terminal
- Node.js (runtime — practical view) 🟥
- Windows dev environment 🟩 — VS Code on Windows specifics
- Terminals & emulators 🟩 — VS Code’s integrated terminal vs standalone
- PowerShell vs Bash 🟥 — shells inside VS Code
- Dotfiles & config 🟩 — settings.json + .vscode/ folder
- TypeScript 🟩 — VS Code’s biggest strength
- JavaScript 🟩
- Linting 🟩 — ESLint integration
- Git 🟩 — VS Code’s Git panel
- Claude Code overview 🟥 — runs in the terminal, separate from VS Code’s AI
- Claude Code deep dive 🟩 🟦
- Glossary: VS Code, IDE, IntelliSense
Sources
- VS Code docs — official reference
- VS Code Marketplace — extension catalog
- VS Code tips & tricks — Microsoft’s curated practical guide
- Cursor docs — the AI-native fork
- Awesome VS Code — community-curated extensions list
- Stack Overflow Developer Survey — annual stats on editor usage