VS Code out of the box is fine. Good, even. But with the right extensions, it becomes extraordinary – a development environment perfectly tailored to your workflow. I've tried hundreds of extensions over the years, installing them eagerly, then uninstalling most within a week. These are the ones that actually stuck – the ones that genuinely changed my daily workflow and earned their place.
The key word is "workflow." Extensions shouldn't just add features – they should solve real problems you encounter repeatedly. If an extension doesn't change how you work, it's just bloat that slows down your editor.
The Non-Negotiables
Some extensions are so fundamental they feel like they should be built into VS Code. I install these immediately on any machine.
GitLens: Git Supercharged
GitLens transforms Git from a command-line tool you occasionally check into a first-class citizen of your editor. It shows you who wrote every line of code, when, and why – right there in the editor.
Hover over any line, and you see:
- The commit message that introduced it
- Author and date
- Full commit diff
- Ability to jump to that commit
But it goes far beyond blame. GitLens provides:
- Visual file history: See how a file evolved over time
- Branch comparison: Compare any two branches without command-line git
- Commit search: Find commits by message, author, or changes
- Repository insights: Contributors, commit patterns, hotspots
- Inline change indicators: See your current changes inline
I used to switch to Git GUI tools for this. Now I never leave VS Code. When debugging, seeing who wrote problematic code and reading their commit message often reveals the intent behind confusing logic.
ESLint and Prettier: End Formatting Debates Forever
These aren't optional if you write JavaScript or TypeScript. ESLint catches bugs and enforces code standards. Prettier formats code consistently. Together, they eliminate entire categories of code review comments and team debates.
My settings format on save and auto-fix ESLint issues:
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
Write messy code, hit save, it cleans up automatically. No more discussions about tabs vs spaces (spaces, 2 of them), semicolons or not (not needed but use them), quote styles (single quotes), trailing commas (always) – Prettier handles it according to your config.
ESLint catches:
- Unused variables
- Missing dependencies in useEffect
- Console.logs left in code
- Implicit any types in TypeScript
- Missing return statements
Errors show immediately as you type. Fix them before they become problems.
Language-Specific Superpowers
Different languages benefit from different tooling. Install what you actually use.
Python: Pylance
Pylance brings TypeScript-level intelligence to Python. Fast type checking, better autocomplete, comprehensive error detection, auto-imports, and semantic highlighting. It understands Python semantics beyond simple syntax highlighting.
Features that matter:
- Type inference that actually works
- Docstring hover information
- Auto-imports from installed packages
- Instant error detection
- Signature help for functions
Python suddenly feels as well-supported as TypeScript. Coupled with a Python formatter like Black, your Python development experience rivals any dedicated Python IDE.
Error Lens: Inline Error Display
Error Lens displays diagnostic messages inline, right where the error occurs. Sounds simple, but it fundamentally changes how you code.
Without Error Lens: Write code → notice red squiggly → hover to see error → read it → fix it.
With Error Lens: Write code → error message appears inline immediately → fix it instantly.
No more checking the problems panel. No more hovering. Errors are visible in your peripheral vision as you type. You see and fix them immediately instead of accumulating 20 errors and fixing them all later.
API Development: REST Client
Stop using Postman or Insomnia for API testing. REST Client lets you make HTTP requests from .http files in your project:
### Get all users
GET https://api.example.com/users
Authorization: Bearer {{token}}
### Get specific user
GET https://api.example.com/users/123
### Create user
POST https://api.example.com/users
Content-Type: application/json
{
"name": "Test User",
"email": "[email protected]",
"role": "admin"
}
### Update user
PUT https://api.example.com/users/123
Content-Type: application/json
{
"name": "Updated Name"
}
### Delete user
DELETE https://api.example.com/users/123
Benefits:
- Version control: API requests live alongside your code in Git
- Shareable: Entire team uses the same requests
- Documentation: Requests document your API through working examples
- Variables: Use variables for tokens, URLs, common values
- Environments: Switch between dev, staging, production
- Fast: Click and run, no separate application
Create an api.http file in your project. Whenever you need to test an endpoint, add it to the file. Over time, you build a comprehensive API documentation that's always up to date because it's actual working requests.
Productivity Multipliers
These extensions don't add language features – they multiply your productivity across all work.
Todo Tree: Never Lose Track
Todo Tree scans your workspace for TODO, FIXME, HACK, BUG, and other comment tags. Shows them in a tree view. Highlights them in your code. Suddenly those "I'll fix this later" comments can't hide.
I use it to leave breadcrumbs for myself:
// TODO: Add error handling
// FIXME: This breaks with negative numbers
// HACK: Temporary workaround, rewrite before v2.0
// BUG: Race condition when multiple users update
// NOTE: Keep this logic synced with mobile app
Different tags get different colors and icons. The tree view lets you:
- See all TODOs across the entire project
- Filter by tag type
- Jump to any TODO location instantly
- Track progress as you fix them
Working on a feature, notice something unrelated that needs fixing? Drop a FIXME comment, keep working on your feature, come back to it later when you have context switched.
Live Share: Collaborative Coding
Live Share is Google Docs for coding. Share your VS Code session with teammates. They can edit files, share terminals, debug together – all in real-time, all while staying in their own editor with their own settings.
Use cases:
- Pair programming: Remote pairing without screen sharing lag or control fighting
- Code review: Review and edit together, discuss changes interactively
- Debugging: Share debugging session, multiple people see the same state
- Onboarding: Guide new team members through the codebase interactively
- Learning: Teach and demonstrate in real code, not slides
Start a session, share the link, teammates join. Each person has their own cursor (color-coded). You can follow someone else's cursor or work independently in the same files. Changes sync in real-time.
For remote teams, this is invaluable. Better than screen sharing because everyone maintains their own environment, settings, and keyboard shortcuts. More interactive than Zoom coding because everyone can contribute simultaneously.
Path Intellisense: Stop Typing Paths
Path Intellisense autocompletes filenames when you write import statements or file paths. Seems minor until you realize how often you type file paths. This eliminates typos and the "was it user.js or users.js?" uncertainty.
import { something } from './components/ <- autocomplete suggests all files
import image from '@/assets/images/ <- works with aliases
const path = require('path');
const file = path.join(__dirname, ' <- autocomplete for filesystem
Works with:
- JavaScript/TypeScript imports
- CSS @import statements
- HTML src/href attributes
- Path aliases (@, ~, etc.)
- Absolute and relative paths
Quality of Life Improvements
Small touches that make daily coding more pleasant.
Auto Rename Tag: HTML Made Easier
Change an opening HTML tag, and the closing tag updates automatically. Change <div> to <section>, and the closing </div> becomes </section>.
Such a simple feature, but it saves countless tiny edits. When refactoring JSX/TSX, this is even more valuable because components often have long names:
content
Change the opening tag to DifferentComponent, closing tag updates automatically. No more mismatched tags, no more hunting for the closing tag in deeply nested JSX.
Better Comments: Semantic Comment Highlighting
Better Comments highlights different comment types with different colors:
// TODO:- Orange (needs action)// FIXME:- Red (broken, needs urgent fix)// NOTE:- Blue (important information)// HACK:- Yellow (temporary solution)// *:- Green (important comment)// ?:- Purple (question or uncertainty)// !:- Bold (critical information)
Makes comments easier to scan and gives them semantic meaning at a glance. Your eyes immediately pick up on red FIXME comments as you scroll. TODOs stand out from regular comments.
Indent Rainbow: Visual Structure
Indent Rainbow colors each indentation level differently. Makes it easier to see code structure, especially in deeply nested code.
Level 1 indentation is one color, level 2 another, level 3 another, etc. When you see six different colors, you know your function is deeply nested and probably needs refactoring.
Helps catch indentation errors instantly. If a line suddenly has the wrong color, the indentation is wrong.
The Controversial Ones
Extensions that generate strong opinions. Decide for yourself.
GitHub Copilot: AI Pair Programmer
Copilot suggests entire functions, writes boilerplate, completes patterns, generates tests. Some developers love it, some hate it, most fall somewhere in between.
My take after a year of use:
Great for:
- Boilerplate code (another React component, another API endpoint)
- Common patterns (error handling, input validation)
- Tests (suggest test cases based on function)
- Comments to code (write comment describing logic, get code suggestion)
- Getting unstuck (start typing, see possible approaches)
Not great for:
- Learning (you don't learn patterns if AI writes them)
- Complex business logic (often wrong or nonsensical)
- Security-sensitive code (blindly accepting suggestions is dangerous)
- Novel problems (training data doesn't cover your specific domain)
Use it as a tool, not a crutch. Read and understand what it suggests. Accept good suggestions, reject bad ones, modify almost-good ones. Don't let it atrophy your coding skills.
If you're learning programming, disable it. You need to struggle with syntax and patterns to learn them. If you're experienced, it can speed up grunt work.
Vim Extension: Modal Editing in VS Code
Brings Vim keybindings to VS Code. If you know Vim, this makes VS Code feel like home. If you don't know Vim, skip it – the learning curve isn't worth it unless you're committed to modal editing philosophy.
I use this. But I spent years learning Vim first. Starting from zero in VS Code? Not worth the productivity hit unless you're passionate about Vim.
Extensions to Avoid
Not all extensions are good. Some slow down your editor. Some conflict with each other. Some solve problems you don't have.
What to Avoid
- Duplicate functionality: VS Code has great built-in Git, debugging, terminal. Don't install extensions that replicate these.
- Theme proliferation: Pick one theme you like and stick with it. Don't install 20 themes "just in case."
- "Just in case" extensions: If you haven't used it in a month, uninstall it. You can always reinstall if you need it.
- Abandoned extensions: Check last update date. Extensions not updated in 2+ years often break with new VS Code versions.
- Slow extensions: Some extensions are poorly optimized. If VS Code becomes sluggish, disable extensions one by one to find the culprit.
Performance Matters
Every extension adds overhead – startup time, memory usage, CPU cycles. Be selective. Quality over quantity.
Check extension performance:
- Open Command Palette (
Cmd/Ctrl+Shift+P) - Run "Developer: Show Running Extensions"
- Sort by activation time or CPU time
- Disable slow extensions you don't use frequently
I have 15 extensions installed. I've tried hundreds. The goal isn't to have the most extensions – it's to have the right ones for your workflow.
Finding Your Perfect Setup
My extension list won't be your extension list. Your perfect setup depends on:
- Languages you use
- Frameworks you work with
- Team conventions
- Personal workflow preferences
- Type of projects (web, mobile, backend, data science)
My Process for Evaluating Extensions
- Identify a real problem: "I keep forgetting to fix TODOs" or "Checking Git blame is too slow"
- Search for solutions: Read descriptions, check ratings, read reviews
- Try for a week: Install and actually use it on real work
- Evaluate impact: Did it solve the problem? Do I use it daily? Would I miss it if gone?
- Keep or remove: If yes to above, keep. Otherwise, uninstall.
Your extension list should evolve with your needs. What you needed as a junior developer differs from what you need as a senior developer. What you need for frontend work differs from backend work.
Regularly audit your extensions. Every few months:
- Uninstall extensions you haven't used
- Check for updates to extensions you rely on
- Look for new extensions that solve current pain points
- Remove extensions whose features were added to VS Code itself
The Bottom Line
Extensions are tools. The right tools solve problems. The wrong tools create them. Don't install extensions because they're popular or because someone recommended them. Install extensions that solve problems you actually have.
Start with the essentials for your language (ESLint/Prettier for JavaScript, Pylance for Python, etc.). Add productivity multipliers that fit your workflow (GitLens, Path Intellisense, etc.). Add quality-of-life improvements that make you happier (Better Comments, Auto Rename Tag, etc.). Stop there unless you have a specific problem to solve.
The perfect VS Code setup is personal. What works for me might not work for you. These extensions solved real problems in my daily work. Maybe some will solve yours too. But don't install them all – install what you need, when you need it.