How to Create a Custom VS Code Theme: Developer's Guide

Published March 9, 2026 · 11 min read · By SPUNK LLC

Every popular VS Code theme started as a single JSON file and a developer who thought the existing options could be better. Creating your own theme is surprisingly approachable — you do not need to be a designer, and you do not need deep extension development experience. If you can edit JSON and have opinions about colors, you can build and publish a theme that thousands of developers might use.

This guide takes you from zero to a published theme on the VS Code Marketplace, covering the color token system, TextMate grammar scopes, testing workflow, and the publishing process.

Understanding the VS Code Theming System

VS Code themes control two distinct layers of color:

A complete theme defines both layers. You can technically create a theme that only defines one (inheriting defaults for the other), but the best themes carefully design both to create a cohesive visual experience.

Prerequisites

Before you start, install these tools:

  1. Node.js (v18 or later) — needed to run the extension scaffolding tool and package your theme.
  2. Yeoman and the VS Code Extension Generator:
npm install -g yo generator-code

That is all you need. No TypeScript, no Webpack, no bundler configuration. Theme extensions are pure JSON.

Step 1: Scaffold the Extension

Run the generator and select "New Color Theme":

yo code

When prompted, choose these options:

This creates a project with this structure:

midnight-ember/
  package.json
  themes/
    Midnight Ember-color-theme.json
  README.md
  CHANGELOG.md
  .vscodeignore

The entire theme lives in that single JSON file inside themes/.

Step 2: Define Your Color Palette

Before editing any JSON, decide on your palette. A well-designed dark theme needs these core colors:

Here is an example palette for a warm dark theme:

{
  "bg":      "#1a1410",
  "surface": "#221c16",
  "border":  "#3a3028",
  "fg":      "#e8dcc8",
  "comment": "#7a6e5e",
  "red":     "#e06c60",
  "orange":  "#e8965a",
  "yellow":  "#e8c86a",
  "green":   "#8cba6a",
  "blue":    "#6aa8c8",
  "purple":  "#b88ae8",
  "pink":    "#e08aaa"
}

Step 3: Configure Workbench Colors

Open your theme JSON file and populate the colors object. Here are the most important workbench color keys:

{
  "name": "Midnight Ember",
  "type": "dark",
  "colors": {
    "editor.background": "#1a1410",
    "editor.foreground": "#e8dcc8",
    "editorCursor.foreground": "#e8965a",
    "editor.selectionBackground": "#3a302866",
    "editor.lineHighlightBackground": "#221c1680",

    "sideBar.background": "#151010",
    "sideBar.foreground": "#b0a898",
    "sideBarTitle.foreground": "#e8dcc8",

    "activityBar.background": "#121010",
    "activityBar.foreground": "#e8dcc8",

    "statusBar.background": "#121010",
    "statusBar.foreground": "#b0a898",

    "tab.activeBackground": "#1a1410",
    "tab.inactiveBackground": "#151010",
    "tab.activeForeground": "#e8dcc8",

    "titleBar.activeBackground": "#121010",
    "panel.background": "#151010",
    "panel.border": "#3a3028",
    "terminal.foreground": "#e8dcc8",
    "terminal.ansiBlack": "#3a3028",
    "terminal.ansiRed": "#e06c60",
    "terminal.ansiGreen": "#8cba6a",
    "terminal.ansiYellow": "#e8c86a",
    "terminal.ansiBlue": "#6aa8c8",
    "terminal.ansiMagenta": "#b88ae8",
    "terminal.ansiCyan": "#6ac8b8",
    "terminal.ansiWhite": "#e8dcc8"
  }
}

VS Code supports over 700 workbench color keys. You do not need to define all of them — undefined keys inherit sensible defaults based on your theme type (dark/light). Focus on the 30-40 most visible elements first, then refine edge cases during testing.

Step 4: Define Token Colors with TextMate Scopes

Token colors use TextMate grammar scopes to target syntax elements. Each rule has a scope (what to target) and settings (how to color it). Add a tokenColors array to your theme JSON:

"tokenColors": [
  {
    "name": "Comments",
    "scope": ["comment", "punctuation.definition.comment"],
    "settings": {
      "foreground": "#7a6e5e",
      "fontStyle": "italic"
    }
  },
  {
    "name": "Keywords",
    "scope": ["keyword", "storage.type", "storage.modifier"],
    "settings": {
      "foreground": "#e06c60"
    }
  },
  {
    "name": "Strings",
    "scope": ["string", "string.quoted"],
    "settings": {
      "foreground": "#8cba6a"
    }
  },
  {
    "name": "Functions",
    "scope": [
      "entity.name.function",
      "support.function",
      "meta.function-call"
    ],
    "settings": {
      "foreground": "#6aa8c8"
    }
  },
  {
    "name": "Variables",
    "scope": ["variable", "variable.other"],
    "settings": {
      "foreground": "#e8dcc8"
    }
  },
  {
    "name": "Types and Classes",
    "scope": [
      "entity.name.type",
      "support.type",
      "support.class"
    ],
    "settings": {
      "foreground": "#e8c86a"
    }
  },
  {
    "name": "Constants and Numbers",
    "scope": [
      "constant",
      "constant.numeric",
      "constant.language"
    ],
    "settings": {
      "foreground": "#e8965a"
    }
  },
  {
    "name": "Operators",
    "scope": ["keyword.operator"],
    "settings": {
      "foreground": "#b88ae8"
    }
  },
  {
    "name": "Tags (HTML/JSX)",
    "scope": ["entity.name.tag"],
    "settings": {
      "foreground": "#e06c60"
    }
  },
  {
    "name": "Attributes",
    "scope": ["entity.other.attribute-name"],
    "settings": {
      "foreground": "#e8965a",
      "fontStyle": "italic"
    }
  }
]

How to Find the Right Scope

The fastest way to discover which scope applies to any token in your code is the built-in scope inspector:

  1. Open any source file in VS Code.
  2. Press Cmd+Shift+P and run "Developer: Inspect Editor Tokens and Scopes".
  3. Click on any token. A panel appears showing the TextMate scope, semantic token type, and current foreground color.

Use this tool constantly while building your theme. It removes all guesswork from scope targeting.

Step 5: Test Your Theme Live

VS Code makes testing effortless with its extension development host:

  1. Open your theme project folder in VS Code.
  2. Press F5 to launch a new VS Code window with your theme loaded.
  3. Open various source files (JavaScript, Python, HTML, CSS, Rust, Go) to see how your colors look across languages.
  4. Edit the theme JSON in your original window — changes apply immediately in the test window after saving.
Tip: Create a test file that contains examples from 5-6 languages. Include edge cases like deeply nested objects, template literals, JSX, decorators, and multi-line strings. This single file becomes your visual regression test.

Step 6: Publish to the VS Code Marketplace

Once your theme looks great across multiple languages, publish it:

Create a publisher account

  1. Go to Visual Studio Marketplace Management.
  2. Sign in with a Microsoft account or create one.
  3. Create a publisher (choose a unique publisher ID).

Create a Personal Access Token

  1. Go to dev.azure.com and sign in.
  2. Click your profile icon > Personal Access Tokens > New Token.
  3. Set the scope to Marketplace > Manage and set a reasonable expiration.
  4. Copy the generated token — you will need it once.

Package and publish

# Install the publishing tool
npm install -g @vscode/vsce

# Login with your publisher name and token
vsce login your-publisher-name

# Package your extension
vsce package

# Publish to the marketplace
vsce publish

Before publishing, update your package.json with these fields:

{
  "publisher": "your-publisher-name",
  "repository": {
    "type": "git",
    "url": "https://github.com/you/midnight-ember"
  },
  "icon": "icon.png",
  "galleryBanner": {
    "color": "#1a1410",
    "theme": "dark"
  }
}

Include a 128x128 pixel PNG icon and a detailed README with screenshots. Themes with good screenshots get significantly more installs — developers decide visually, and a single compelling screenshot can be the difference between someone clicking Install or scrolling past.

Tips for a Great Theme

Going Further

Once your theme is published, consider these enhancements:

Building a VS Code theme is one of the most rewarding small projects a developer can take on. You get to use your own creation every day, and if it resonates with others, you might find yourself maintaining a tool used by thousands. Start with a palette that makes you happy, test it thoroughly, and ship it.