Skip to content

I built a Chrome extension that gives Azure DevOps the Visual Studio dark theme

Posted on:July 17, 2026

Share

Table of contents

TLDR

I built a Chrome extension that makes code in Azure DevOps look like it does in Visual Studio: same dark theme colors, same font. It works in the file viewer, commit diffs and pull requests.

Supported file types:

You can install it from the Chrome Web Store here: VS Dark Theme for Azure DevOps

C# in Azure DevOps with Visual Studio dark theme colors

Why I built it

I spend a lot of my day in Visual Studio, and with the coming of AI, a bigger and bigger chunk of my day becomes reviewing code in Azure DevOps. Over the years I have become very used to the Visual Studio dark mode theme.

After years in the same editor I read these colors subconsciously, I see that something is a struct before I read its name. Losing that during code review, which is exactly when you’re reading unfamiliar code, annoyed me.

So I built the thing I wanted: Azure DevOps, but the code looks like it does in Visual Studio default dark mode.

What it does

A Blazor component in Azure DevOps with full Razor highlighting

How it works

Written with the help of AI, because writing technical documentation is a little boring.

Azure DevOps renders code with the Monaco editor - the same editor that powers VS Code. That was the opening: Monaco has a public API for themes and tokenizers, so a content script running on the page can register its own.

The extension does three things:

  1. Forces a custom Monaco theme with the exact Visual Studio dark hex values, and wraps setTheme so Azure DevOps can’t switch it back.
  2. Replaces the built-in tokenizers for C#, Razor, CSS, SCSS, JavaScript and TypeScript with grammars I wrote from scratch. Monaco’s stock C# grammar lumps methods, properties and class names together as “identifier” — to get the Visual Studio look you need much more granular tokens, so most of the work went into heuristics: an identifier before ( is a method, PascalCase after . without a call is a property, IFoo is an interface, and so on.
  3. Discovers symbols from context. A tokenizer can’t know that Money is a struct — that’s semantic information. So the extension scans the open document for declarations (struct Money, enum Permission, method signatures) and feeds those names back into the grammar, then re-tokenizes. Close enough to semantic highlighting that you rarely notice the difference.

What about Blazor code-behind?

Blazor components often keep their logic in a separate .razor.cs code-behind file. When you view Dashboard.razor, the markup references fields and methods that are declared in a file the browser has never seen, so how do you color @onclick="LoadAsync" as a method?

The extension runs inside an authenticated Azure DevOps page, so it can simply ask Azure DevOps: when you open a .razor file, it fetches the sibling .razor.cs through the same REST API the site itself uses, scans it for method and type declarations, and re-colors the markup. No extra permissions, no data leaves the page — it’s the same request your browser could make anyway.

Razor file with code behind in PR

The hard parts

Two things fought back more than expected:

TypeScript in Azure DevOps with Visual Studio dark theme colors

It works in pull requests too

The per-file diff view in pull requests is Monaco-based, so reviews get the full treatment — which was the point of the whole exercise.

A pull request diff with full syntax highlighting

The trickiest surface was the all-files summary view (and the compare view when creating a PR) — Azure DevOps renders those as plain text rows without Monaco, without tokens, without any structure to restyle. Even worse, on those pages Monaco isn’t loaded at all. So the extension ships its own copy of Monaco (the editor’s own MIT-licensed engine, bundled right into the extension) and runs my grammars over the raw diff text with monaco.editor.tokenize() — so the summary view gets the exact same colors as the full file view, including things that need state across lines, like @code blocks and block comments. Because Monaco is bundled rather than fetched, the extension ships all of its own code and needs no remote scripts.

Install it

Grab it from the Chrome Web Store: VS Dark Theme for Azure DevOps

It runs only on dev.azure.com and *.visualstudio.com, collects no data, and needs no configuration. Tip: set your Azure DevOps profile theme to Dark (⚙ → Theme) so the UI around the code matches.

If a color looks off for your favorite language construct, let me know — half of this extension was built by comparing screenshots against Visual Studio one token type at a time.


This extension is not affiliated with or endorsed by Microsoft. “Visual Studio” and “Azure DevOps” are trademarks of Microsoft Corporation, referenced only to describe compatibility.

Related Posts