VS Code Extensions That Changed My Development Workflow

6 min read1011 words

As a frontend developer working primarily with React, Next.js, and TypeScript, I've spent countless hours fine-tuning my development environment. After trying dozens of VS Code extensions over the years, I've settled on a core set that genuinely transformed how I write code.

In this post, I'll share the extensions that made the biggest impact on my productivity, along with real examples of how I use them daily and specific configuration tips that took me months to discover.

The Problem with Extension Overload

Before diving into my recommendations, let me address the elephant in the room: extension fatigue. I've seen developers with 50+ extensions installed, creating a sluggish, confusing environment that hurts more than it helps.

My approach is different. I focus on extensions that solve specific, recurring problems in my workflow. Each extension in my list has earned its place by consistently saving me time and reducing friction.

Essential Extensions for Modern Frontend Development

1. GitHub Copilot - AI Pair Programming

Why it's essential: GitHub Copilot has fundamentally changed how I write code. It's not just about autocomplete—it's like having an experienced developer pair programming with you.

Real-world impact: I estimate Copilot saves me 2-3 hours per day by:

  • Generating boilerplate code instantly
  • Suggesting complex regex patterns
  • Writing comprehensive test cases
  • Creating documentation comments

Configuration tip:

{
  "github.copilot.enable": {
    "*": true,
    "yaml": false,
    "plaintext": false
  },
  "github.copilot.advanced": {
    "debug.overrideEngine": "codex"
  }
}

I disable Copilot for YAML and plaintext files where suggestions can be more distracting than helpful.

Example workflow: When building a React component, I start with a comment describing what I want:

// Create a responsive card component with image, title, description, and CTA button
// Props: image, title, description, buttonText, buttonHref
// Use Tailwind CSS for styling
 
// Copilot generates:
interface CardProps {
  image: string;
  title: string;
  description: string;
  buttonText: string;
  buttonHref: string;
}
 
export const Card: React.FC<CardProps> = ({
  image,
  title,
  description,
  buttonText,
  buttonHref
}) => {
  return (
    <div className="max-w-sm rounded-lg border border-gray-200 bg-white shadow-md">
      <img className="rounded-t-lg" src={image} alt={title} />
      <div className="p-5">
        <h5 className="mb-2 text-2xl font-bold tracking-tight text-gray-900">
          {title}
        </h5>
        <p className="mb-3 font-normal text-gray-700">
          {description}
        </p>
        <a
          href={buttonHref}
          className="inline-flex items-center px-3 py-2 text-sm font-medium text-center text-white bg-blue-700 rounded-lg hover:bg-blue-800"
        >
          {buttonText}
        </a>
      </div>
    </div>
  );
};

2. Error Lens - Inline Error Display

Why it's essential: Error Lens displays TypeScript errors and warnings directly in your code, eliminating the need to hover or check the problems panel constantly.

Before Error Lens:

  • Write code → see red squiggles → hover to read error → fix → repeat
  • Context switching between code and problems panel

After Error Lens:

  • Errors appear inline with clear descriptions
  • Immediate feedback without breaking flow
  • Color-coded severity levels

Configuration:

{
  "errorLens.enabledDiagnosticLevels": ["error", "warning"],
  "errorLens.excludeBySource": ["cSpell"],
  "errorLens.followCursor": "closestProblem",
  "errorLens.gutterIconsEnabled": true
}

3. Auto Rename Tag - Synchronized HTML/JSX Tags

Why it's essential: Automatically renames paired HTML/JSX tags when you edit one. This seems minor until you're refactoring large components.

Before:

// Change <div> to <section>
<div className="container">
  <div className="header">
    <h1>Title</h1>
  </div>
  <div className="content">
    Content here
  </div>
</div>
// Manually change closing </div> tags - error-prone!

After:

// Change <div> to <section> and closing tag updates automatically
<section className="container">
  <div className="header">
    <h1>Title</h1>
  </div>
  <div className="content">
    Content here
  </div>
</section>

4. GitLens - Supercharged Git Integration

Why it's essential: GitLens provides Git blame information, file history, and repository insights directly in your editor.

Key features I use daily:

  • Inline blame annotations: See who changed each line and when
  • File history: Track how files evolved over time
  • Commit details: Rich commit information on hover

Configuration for minimal distraction:

{
  "gitlens.currentLine.enabled": false,
  "gitlens.hovers.currentLine.over": "line",
  "gitlens.blame.format": "${author|10} ${agoOrDate|14-}",
  "gitlens.blame.heatmap.enabled": false
}

I disable the current line blame to reduce visual clutter while keeping hover information available.

5. Tailwind CSS IntelliSense - Smart Utility Classes

Why it's essential: If you're using Tailwind CSS (and you should be), this extension provides intelligent autocomplete, syntax highlighting, and linting.

Features that save time:

  • Autocomplete for all Tailwind classes
  • CSS property previews on hover
  • Syntax highlighting for class names
  • Linting for invalid or deprecated classes

Configuration:

{
  "tailwindCSS.includeLanguages": {
    "typescript": "javascript",
    "typescriptreact": "javascript"
  },
  "tailwindCSS.experimental.classRegex": [
    ["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"],
    ["cx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
  ]
}

The experimental regex patterns help with class variance authority (cva) and conditional class utilities.

6. Thunder Client - API Testing in VS Code

Why it's essential: Thunder Client provides a Postman-like interface directly in VS Code, eliminating the need to switch between applications for API testing.

Workflow integration:

  1. Build API endpoint in Next.js
  2. Test immediately with Thunder Client
  3. Save requests in collections
  4. Generate code snippets for frontend

Example use case: When building a blog API, I create a collection with all endpoints:

  • GET /api/posts - List all posts
  • GET /api/posts/[slug] - Get single post
  • POST /api/posts - Create new post
  • PUT /api/posts/[id] - Update post

This keeps all API testing within my coding environment.

7. Import Cost - Bundle Size Awareness

Why it's essential: Shows the size impact of imported packages inline, helping you make informed decisions about dependencies.

Real example:

import moment from 'moment'; // 67.8KB (gzipped: 19.6KB) ⚠️
import { format } from 'date-fns'; // 13.4KB (gzipped: 4.6KB) ✅

This visual feedback has helped me:

  • Choose date-fns over moment.js
  • Import specific lodash functions instead of the entire library
  • Avoid accidentally importing entire icon libraries

Configuration Best Practices

Workspace vs User Settings

I keep extension configurations in workspace settings (.vscode/settings.json) for project-specific needs:

{
  "typescript.preferences.filename": "index.ts",
  "emmet.includeLanguages": {
    "typescript": "html",
    "typescriptreact": "html"
  },
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true,
    "source.organizeImports": true
  }
}

Performance Optimization

Extensions can slow down VS Code. Here's how I keep things fast:

  1. Disable unused language servers:
{
  "extensions.ignoreRecommendations": true,
  "telemetry.enableTelemetry": false
}
  1. Limit file watching:
{
  "files.watcherExclude": {
    "**/node_modules/**": true,
    "**/.git/**": true,
    "**/dist/**": true
  }
}