/ build-guides / How to Build a VS Code Extension as a Solo Developer
build-guides 11 min read

How to Build a VS Code Extension as a Solo Developer

Step-by-step guide to building a VS Code extension by yourself. Tech stack, timeline, costs, and practical advice.

Hero image for How to Build a VS Code Extension as a Solo Developer

What You're Building

A VS Code extension that enhances the development experience for millions of developers. This could be a new language support, a theme, a snippet pack, a code formatter, an AI assistant, or a productivity tool that integrates with external services. VS Code is the most popular code editor in the world, and its extension marketplace is one of the best distribution channels available to solo developers.

I built a small VS Code extension that auto-generated boilerplate for a specific framework I used daily. Took me about two weekends. It never got massive downloads, but it taught me how the extension API works. And honestly, using an extension you built yourself every day is a pretty satisfying feeling.

Difficulty & Timeline

Aspect Detail
Difficulty Medium
Time to MVP 2-4 weeks
Ongoing Maintenance Low to Medium
Monetization Freemium, sponsorware, donations

VS Code extensions are written in TypeScript (or JavaScript, but TypeScript is strongly recommended). The extension host runs in Node.js, so you have access to the full Node ecosystem. For the UI, VS Code provides a Webview API that lets you render custom HTML/CSS/JS panels inside the editor.

Use the official Yeoman generator (yo code) to scaffold your project. It sets up the build pipeline, test infrastructure, and package.json with the right fields for the marketplace. The current versions, checked on the npm registry on 2026-05-30, are yo 7.0.1 and generator-code 1.11.18. You can skip the global install entirely with the one-shot command npx --package yo --package generator-code -- yo code, which is what the official "Your First Extension" docs now recommend. Your package.json will pin a @types/vscode version (currently 1.120.0); that number is your engines.vscode floor, so set it to the oldest VS Code release you want to support rather than blindly using the latest.

For testing, VS Code's built-in extension test runner (@vscode/test-cli, currently 0.0.12) works well enough. For complex extensions, add unit tests with Vitest (currently 4.1.7) alongside the integration tests.

There's no separate backend needed for most extensions. If your extension calls external APIs (like an AI service), you can do that directly from the extension code. If you need user accounts and premium features, you'll need a small API server, but start without one.

Step-by-Step Plan

Phase 1: Foundation (Week 1)

Run the Yeoman generator and explore the generated project. Open it in VS Code, press F5 to launch the Extension Development Host, and you'll see a second VS Code window where your extension is active. This development loop is excellent. Change code, reload the window, see the results.

Start with the simplest possible version of your idea. If you're building a code formatter, get it working on a single file type first. If you're building a productivity tool, implement one command. Register it in package.json under contributes.commands, wire it up in your extension.ts activate function, and make sure it works.

Read the VS Code Extension API docs. They're genuinely good, better than most platform docs I've worked with. Focus on the sections relevant to your extension type: Language Extensions, Webview, Tree Views, or Custom Editors.

Phase 2: Core Features (Week 2-3)

Build out your main functionality. The VS Code API is rich but has some quirks. Here are things I wish I'd known earlier.

The TextDocument and TextEditor APIs are your bread and butter. Learn the difference between editing through WorkspaceEdit (good for bulk operations) and TextEditorEdit (good for single-editor changes). I spent hours debugging why my edits weren't applying before realizing I was using the wrong approach.

If your extension needs a sidebar or panel, use the TreeView API for tree-structured data or the Webview API for custom UIs. Webviews are essentially iframes that can render any HTML, which is powerful but comes with security restrictions. You need to use a Content Security Policy and communicate between the webview and extension via message passing.

Add configuration options through VS Code's Settings UI. Users expect to customize extensions. Use contributes.configuration in your package.json and access settings via vscode.workspace.getConfiguration(). This is free UX that the editor provides for you.

Phase 3: Polish & Launch (Week 3-4)

Write a good README. Seriously. The README is your marketplace listing, and it's the primary thing users see before installing. Include screenshots or GIFs showing the extension in action, a clear feature list, and installation instructions. I've installed extensions solely because their README had a great demo GIF.

Create an icon (128x128 PNG). Add it to your package.json. Extensions without icons look untrustworthy in the marketplace.

Publish using vsce (Visual Studio Code Extensions CLI). Install it with npm install -g @vscode/vsce (the current published version is 3.9.1 as of 2026-05-30, and the package pulls over 1.26 million downloads a week, so this is the well-worn path). You'll need a Personal Access Token from Azure DevOps, which is free to set up. The token detail that trips everyone up is the scope. Create the token with Organization set to "All accessible organizations" and Scope set to "Marketplace (Manage)". Then run vsce login <publisher-id>, paste the token, and vsce publish. Your extension appears in the marketplace within minutes. Update it by bumping the version with vsce publish minor (or patch, or a specific number like vsce publish 1.1.0) and publishing again.

Monetization Strategy

VS Code extension monetization is tricky because the culture around extensions is very "free and open source." That said, several approaches work.

Sponsorware. Build the extension open source, then add premium features that sponsors get early access to. Once sponsors fund development, release features publicly. This model has worked well for extensions like GitHub Copilot alternatives and specialized language tools.

Freemium with a backend. The free extension connects to your API. Basic features are free. Premium features require a subscription. This works best for extensions that provide AI features, code analysis, or cloud-based services where you have actual hosting costs to cover.

Donations and GitHub Sponsors. If your extension is popular and open source, add a sponsor link. Some developers earn $500-2000/month from popular extensions through sponsorships alone. It's not guaranteed, but the ceiling is higher than most people expect.

The harsh truth is that most solo VS Code extensions won't make significant direct revenue. But they're incredible for reputation, job opportunities, and building an audience in the developer community.

Common Mistakes to Avoid

Activating on every file open. Use activation events properly. If your extension only works with Python files, set "activationEvents": ["onLanguage:python"]. An extension that loads for every file type slows down the editor and annoys users. I've seen one-star reviews that just say "made my editor slow." Don't earn those. The official docs are blunt about the catch-all "*" event, telling you to use it "only when no other activation events combination works in your use-case." One nuance worth knowing: since VS Code 1.74.0, commands, languages, views, and custom editors you contribute activate automatically, so you no longer need to hand-write a matching onCommand or onView entry. The generated activationEvents array is often emptier than older tutorials suggest.

Not handling extension host restarts. The extension host can restart at any time (updates, crashes, reloads). Make sure your extension handles deactivation cleanly and doesn't leak resources. Dispose of event listeners, file watchers, and timers in your deactivate function.

Shipping an unbundled extension. Use esbuild or webpack to bundle your extension. The official bundling guide puts the reason plainly. "Loading 100 small files is much slower than loading one large file." The default project setup works for development but ships every loose file, which drags activation time. esbuild is the lighter option (it is one of the most downloaded packages on npm, with hundreds of millions of weekly installs, currently version 0.28.0) and webpack (currently 5.107.2) is the heavier, more configurable one. Bundling is also what lets your extension run in the web builds at vscode.dev and github.dev, where only a single file can be loaded.

Ignoring the marketplace listing. Include detailed categories, tags, and a proper description. The marketplace search is basic, and proper metadata is how users find your extension. I've seen great extensions with terrible discoverability because the author didn't bother with tags.

Common Errors and Fixes

These are the failures that actually stop a solo developer on launch day, with fixes grounded in the current official docs and tooling.

vsce publish fails with 401 or "access denied." This is almost always the token scope. The Azure DevOps Personal Access Token must be created with Organization set to "All accessible organizations" and Scope set to "Marketplace (Manage)." A token scoped to a single organization, or one missing the Manage scope, authenticates but cannot publish. Regenerate the token with the right settings and run vsce login <publisher-id> again.

"Missing publisher name" on publish. Your package.json needs a top-level publisher field that matches the publisher identity you created in the Marketplace management portal. The Yeoman generator leaves this blank, so it is easy to forget. Add it before your first publish.

Webview renders blank or the console shows a Content Security Policy violation. Webviews are sandboxed iframes. Inline scripts and remote resources are blocked unless you declare them. Add a <meta http-equiv="Content-Security-Policy"> tag and use a per-load nonce on your script tags, then load assets through webview.asWebviewUri() rather than plain file paths. The Webview API guide walks through the exact CSP and nonce pattern.

Extension never activates. If your command does nothing, check that the command id in package.json exactly matches the string you pass to registerCommand. Since VS Code 1.74.0 contributed commands activate automatically, so you usually do not need a matching onCommand entry, but a typo in the id is silent and produces no error.

engines.vscode mismatch warning at install. The generator pins a @types/vscode version (1.120.0 at the time of writing) and a matching engines.vscode. If you set engines.vscode higher than the version a user is running, the Marketplace refuses to install. Set it to the oldest VS Code release you intend to support, not the newest one on your own machine.

Slow activation flag in the Running Extensions view. If VS Code flags your extension as slow, you are almost certainly shipping unbundled. Add esbuild or webpack per the bundling guide and confirm your .vscodeignore excludes source and node_modules so the packaged .vsix ships the single bundled file instead of hundreds of loose ones.

Sources

Is This Worth Building?

Yes, with caveats. If you use VS Code daily and have a specific pain point that no existing extension solves, building one is satisfying and useful. The skills you learn (TypeScript, API design, publishing) are broadly applicable.

If you're building a VS Code extension purely for revenue, manage your expectations. The money is indirect. A popular extension with 100k+ installs puts your name in front of a massive developer audience. That audience can convert to newsletter subscribers, course buyers, consulting leads, or job offers.

The best VS Code extensions come from developers scratching their own itch. If you've ever thought "I wish VS Code could do X," that's your extension idea. Build it for yourself first. If it's useful to you, it's probably useful to thousands of other developers with the same workflow.

Built by Kevin

Like this? You'll like what I'm building too.

Two ways to support and get more of this work.

Desktop App

HEARTH

A privacy-first Life OS for your desktop. Journal, tasks, and notes that stay on your machine. Coming soon, direct download from this site.

Read more
Digital Products

MY TOOLKITS

Receipts-first toolkits for shipping after hours, building Claude agents, publishing on Amazon, and more. The exact methods I used, not theory.

Browse on Whop

Need This Built?

Kevin builds products solo, from first version to live. If you want something like this made, work with him.