Skip to content
| Marketplace
Sign in
Visual Studio Code>Themes>Modern ThemesNew to Visual Studio Code? Get it now.
Modern Themes

Modern Themes

Hüsamettin Ulutaş

|
4 installs
| (0) | Free
24 handcrafted modern color themes plus a coding font picker that can install bundled open-source fonts for you. Every color is solved for WCAG contrast.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info
Modern Themes

Modern Themes

24 handcrafted color themes for VS Code, plus a coding font picker that installs fonts for you.

Both with live preview.

Every color is solved for contrast, not picked by eye.

Version Themes Contrast Checks License

Modern Midnight, Modern Ember, Modern Jade and Modern Paper

Why another theme pack

Most theme extensions Modern Themes
One theme per extension 24 themes in one package, 16 dark and 8 light
Switch through Settings, then restart your eyes Ctrl+K Ctrl+M, arrow keys, every theme applies instantly
No idea which theme you are on Active theme in the status bar, check mark in the picker
Colors picked by hand, contrast checked by hope Every color solved against the surface it sits on, verified by 9289 automated checks
Comments you cannot read Comments hold 4.6:1 in all 24 themes
Stuck once you install it One click back to the stock VS Code theme
Colors only, font is your problem A font picker too, showing what is actually installed on your machine

Install

Grab the .vsix from Releases:

code --install-extension modern-themes-1.0.0.vsix

Or build it yourself:

npm install
npm run build && npm run icon && npm run preview && npm run package
code --install-extension modern-themes-1.0.0.vsix

Usage

Press Ctrl+K Ctrl+M. That is the whole thing.

ShortcutWhat it does
Ctrl+K Ctrl+MOpen the picker. Arrow keys preview live, Enter keeps, Esc cancels
Ctrl+K Ctrl+→Next theme
Ctrl+K Ctrl+←Previous theme

Everything is also in the Command Palette under Modern Themes:

  • Browse Themes (Live Preview) — the picker
  • Surprise Me (Random Theme) — for when you cannot decide
  • Next Theme / Previous Theme — step through the set
  • Pick a Coding Font — the font picker
  • Back to the VS Code Default Theme / Back to the Default Font — clears the setting entirely

Knowing where you are

The status bar, bottom right, shows two things: the active theme and the active font. Click either to open its picker. Inside a picker the current entry carries a check mark and reads current, so previewing others never loses your place.

Changing your mind

Esc while previewing restores whatever you had before you opened the picker.

To leave the pack entirely, pick Back to the VS Code default at the bottom of the list. It clears workbench.colorTheme, so VS Code returns to the theme it shipped with. The themes stay installed, one keystroke away.


Fonts

A theme changes the colors. The font changes the shapes, and the two together are what the editor actually feels like. Three ways in, whichever you notice first:

  • Click the font name in the status bar, bottom right, next to the theme name
  • Command Palette (Ctrl+Shift+P) then Modern Themes: Pick a Coding Font
  • The Aa button in the top right of the theme picker

Same behaviour as the theme picker: arrow keys preview live, Enter keeps, Esc restores.

It can install the font for you

editor.fontFamily only resolves fonts registered with the operating system. A font sitting inside an extension is invisible to it, and no extension can inject @font-face into the workbench. The circulating workaround patches VS Code's own CSS, which marks the install corrupted and breaks on every update.

So instead of pretending, this puts the file where the OS looks. Four faces ship inside the extension and install to your user account on click:

Font Ligatures
JetBrains Mono yes Tall x-height, built for long reading sessions
Victor Mono yes Cursive italics, so the italic comments in these themes really sing
Fira Code yes The one that made programming ligatures popular
Source Code Pro no Conservative and very legible

No administrator prompt is needed. Windows has supported per-user font installs since Windows 10 1803 (%LOCALAPPDATA%\Microsoft\Windows\Fonts plus an HKCU registry value); macOS reads ~/Library/Fonts, fontconfig reads ~/.local/share/fonts. VS Code enumerates fonts when its renderer starts, so the picker offers a window reload once the file is in place.

The picker splits everything into three groups:

  • Installed — previews live, applies immediately
  • Bundled, ready to install — the four above, one click, nothing to download
  • Not installed on this machine — inert in the list, and picking one opens a download page rather than quietly applying a family that falls back

Ligatures are switched on or off to match the face you pick. Set modernThemes.manageFontLigatures to false to decide that yourself.

Also in the list

Not bundled, but detected if you already have them, with a download link if you do not: Geist Mono, Cascadia Code, Commit Mono, Iosevka, IBM Plex Mono, Hack, plus whichever system faces your platform has: SF Mono and Menlo on macOS, Consolas on Windows, DejaVu Sans Mono on Linux.

MonoLisa and Berkeley Mono are commercial, so they are listed but never bundled; picking one opens its purchase page.

Roboto Mono, Arial and Helvetica derivatives are deliberately absent. The design rules this project follows ban those families as default reaches.


The themes

Dark

All sixteen dark themes

Light

All eight light themes
Every theme, full size

Modern Midnight
Cool slate-blue

Modern Cobalt
Deep navy

Modern Ink
Near-black indigo

Modern Nebula
Violet-grey

Modern Orchid
Orchid magenta

Modern Rose
Plum and deep rose

Modern Olive
Olive and brick

Modern Ember
Burnt orange

Modern Amber
Warm charcoal

Modern Citron
Cool charcoal, citron

Modern Graphite
Monochrome, one pop

Modern Moss
Forest floor

Modern Jade
Jade green-teal

Modern Forest
Deep green

Modern Abyss
Deep teal

Modern Aurora
Glacier cyan

Modern Paper
Cool grey and cobalt

Modern Linen
Slate and terracotta

Modern Bone
Bone and forest green

Modern Mist
Cool mist teal

Modern Meadow
Pale green

Modern Coral
Warm white and coral

Modern Blossom
Blossom pink

Modern Iris
Pale iris magenta

Every preview above is rendered directly from the theme's own color values, so what you see is the palette itself, not an artist's impression of it.

The extension icon works the same way. The outer ring is one swatch per theme at that theme's real accent color, ordered by hue, and the even spacing is the 15-degree minimum separation the audit enforces. The split disc in the middle is the thesis: a color, and the surface under it.


Every color is solved, not picked

This is the part that makes the pack worth installing.

A theme here is not a list of hex codes. It is a neutral hue, a single accent, a syntax hue ring, and a depth — and everything else is derived. For each color the generator walks lightness until it clears a contrast target against the surface that color actually sits on:

// Walk lightness until the color clears `target` contrast against `bg`.
function solve (h, s, bg, target) {
  const dark = luminance(bg) < 0.18
  let l = dark ? 40 : 60
  for (let i = 0; i < 400; i++) {
    const c = hsl(h, s, l)
    if (contrast(c, bg) >= target) return c
    l = clamp(l + (dark ? 0.5 : -0.5), 0, 100)
  }
}

That last part matters more than it sounds. An inactive tab label does not sit on the editor background, it sits on the tab strip. Solving it against the wrong surface is how themes end up with tab labels at 2.8:1. Here every ramp is solved against its own surface.

What that buys you, in all 24 themes:

Ratio
Default text ~10:1 past the AAA target of 7
Syntax tokens ≥5.5:1 comfortably past AA
Comments ≥4.6:1 the line most themes fail
Button and badge labels ≥4.6:1 accent lightness is fitted to guarantee it
Chrome text ≥4.5:1 against its own surface, not the editor's

The audit

build/audit.js runs 9289 checks and exits non-zero on any violation:

$ npm run audit
ran 9289 checks across 24 themes

PASS: contrast, forbidden colors, hue lock and accent lock all hold

It enforces:

  • Contrast for every token, status color, git decoration and chrome pair
  • No pure black, no pure white anywhere — pure values kill depth
  • One neutral hue per theme, so warm and cool greys never mix in one theme
  • One accent per theme, saturation under 80, identical everywhere it appears
  • 15 degrees minimum between any two same-type accents, so no two themes read as the same family
  • No banned palettes — the beige/brass/espresso premium-consumer family is rejected outright
  • Syntax role separation, flagging any two roles too close to tell apart

Design rules

The themes were built against a UI/UX rule set (kept outside this repo, under .agents/skills) treated as hard constraints rather than suggestions. The audit exists because a rule you only promise to follow is a rule you break.

Some things those rules changed:

  • Two planned themes used the banned beige/brass/espresso palette. Cut, and replaced with approved families (Forest, Cobalt + Cream, Terracotta + Slate).
  • A light theme used #ffffff. Now nothing does; the lightest surface is 99.2%.
  • Three themes shipped button labels between 4.08:1 and 4.44:1. Accent fill lightness is now fitted until a legible label exists.
  • Keyword and tag colors were 23 degrees apart and read identically in three themes. The syntax ring was widened to 45 degrees.
  • Shadows are tinted to each theme's neutral hue. None are black.
  • Violet is used three times in sixteen dark themes, on purpose, never as a default reach.

Development

npm run build     # palettes -> themes/*.json, and rewrites contributes.themes
npm run audit     # 9289 design checks, exit 1 on any violation
npm run preview   # re-renders every theme image in media/
npm run icon      # re-renders the extension icon from the live accent colors
npm run package   # builds the .vsix

To change a theme, edit the palette in build/palettes.js — never themes/*.json, which is generated output and gets overwritten.

A palette is five numbers and a name:

{
  id: 'midnight',
  label: 'Modern Midnight',
  type: 'dark',
  family: 'Cool slate-blue, electric blue accent',
  neutral: { h: 220, s: 20 },   // every grey in the theme comes from this hue
  accent:  { h: 212, s: 72 },   // the one accent, saturation under 80
  rot: 0,                       // rotates the syntax hue ring
  ssat: 62,                     // syntax saturation
  depth: 0                      // slides every surface lighter or darker
}

Add one to the array, run npm run build && npm run audit, and the theme is contributed, validated and rendered.


Settings

Setting Default Description
modernThemes.showStatusBarItem true Show the active theme in the status bar
modernThemes.manageFontLigatures true When you pick a font, match editor.fontLigatures to what it supports

License

The code and the themes are MIT.

The four bundled fonts are not. Each keeps its own SIL OFL 1.1 licence, included beside it in fonts/ along with the details. The OFL explicitly permits bundling a font with software when the copyright notice and licence travel with it and the font is not sold on its own, which is the case here. The files are unmodified variable builds.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft