Building a VS Code extension is well-documented. Publishing it to the Marketplace is less so — the official docs cover it, but the actual flow has several steps that aren't obvious until you try. Here's the complete process I followed for mkhCodeFormatter.

Step 1: Create a publisher account

Go to https://marketplace.visualstudio.com/manage. Sign in with a Microsoft account. Click "Create publisher." Choose a publisher ID — this is permanent and forms part of your extension's unique identifier (publisherId.extensionName). Mine is mustafa-Mlab, so mkhCodeFormatter's full ID is mustafa-Mlab.mkh-codeformatter.

Step 2: Create a Personal Access Token (PAT)

In the Azure DevOps portal (https://dev.azure.com), under User Settings → Personal Access Tokens, create a new token with "Marketplace (Publish)" scope. This token is what vsce (the VS Code Extension Manager CLI) uses to authenticate.

Step 3: Configure package.json

Before publishing, your package.json must include these fields:

{
  "name": "mkh-codeformatter",
  "displayName": "mkhCodeFormatter",
  "publisher": "mustafa-Mlab",
  "version": "0.0.2",
  "engines": { "vscode": "^1.96.0" },
  "icon": "icon.png",
  "repository": { "type": "git", "url": "https://github.com/mustafa-Mlab/mkh-codeformatter.git" },
  "categories": ["Other"]
}

Key requirements: publisher must match your Marketplace publisher ID exactly. icon must be a 128×128 PNG. engines.vscode must be a valid minimum version.

Step 4: Bundle with esbuild

The extension source (TypeScript) needs to be compiled and bundled into a single dist/extension.js file before packaging. I use esbuild for this — it's faster than webpack and produces smaller bundles:

// esbuild.js
require('esbuild').build({
  entryPoints: ['src/extension.ts'],
  bundle: true,
  outfile: 'dist/extension.js',
  external: ['vscode'],
  format: 'cjs',
  platform: 'node',
  minify: process.argv.includes('--production'),
});

The external: ['vscode'] is critical — the vscode module is provided by VS Code at runtime and must not be bundled.

Step 5: Install vsce and publish

npm install -g @vscode/vsce

# Login with your PAT
vsce login mustafa-Mlab

# Package the extension into a .vsix file (for testing)
vsce package

# Publish directly to the Marketplace
vsce publish

vsce package creates a .vsix file you can install locally by running code --install-extension mkh-codeformatter-0.0.2.vsix. This is good for final testing before publishing.

Step 6: .vscodeignore

The .vscodeignore file tells vsce which files to exclude from the package — source files, test files, node_modules (the bundled output in dist/ is enough), and development configs:

src/**
out/**
node_modules/**
.vscode-test/**
*.ts
esbuild.js

After publishing

The extension appears on the Marketplace within a few minutes. It takes up to 24 hours to be indexed in VS Code's built-in Extensions search. Subsequent versions are published with vsce publish patch (auto-increments the patch version) or vsce publish minor. Version history appears on the Marketplace listing automatically.

One thing I learned: the Marketplace listing's "Features" and screenshots come entirely from your README.md and any icon.png you provide — there's no separate UI to fill in. Write a clear, complete README with installation steps, feature list, and configuration guide before publishing.

Mustafa Kamal Hossain

Mustafa Kamal Hossain

Founder & Principal Engineer at Manfi. Passionate about Laravel, SaaS architecture, and high-performance engineering.