Remember when writing code was just you and a CRT screen with green text on a black background? I'll be honest, I don't. My earliest "retro computing" experience was on Windows 98 and it was more than a decade later when I started programming for the first time. So take my historical knowledge with a grain of salt, it's mostly based on Wikipedia and nostalgic Reddit threads. But from what I gathered, code editors used to be monochrome. That's it. One color, chosen not by designers but by the manufacturer of your display.
These days, modern editors like Zed have 200+ color tokens. We have colors for backgrounds, colors for borders, colors for slightly different borders and colors for when the compiler is disappointed in the code you wrote. When it comes to text, it gets even crazier: colors for different states, but more importantly, colors for every syntax token your heart desires.
We went from "the screen is green" to "actually, I want my functions to be #0751CF but only when it's a call expression.
And can we make punctuation.delimiter harmonize with my syntax.operator, while maintaining enough contrast against my editor.active_line.background?"
Progress? Absolutely. Themes are personal, themes are art. But editing 200 values in a JSON file to achieve your vision? Not exactly a vibe.
So we built Theme Builder: a visual editor where you can craft your perfect theme with a live preview, instantly see which token controls what, and export the result when you're done. No JSON wrangling required.
Why Theming is Hard
Here's the thing about theming a modern code editor: it's not just picking a few pretty colors.
Zed's theme system includes:
- 16 categories of UI colors covering everything from surfaces and borders to scrollbars and terminals
- 10 categories of syntax colors for all your highlighting needs
- Player colors for multiplayer collaboration (cursor, background and selection for each participant)
- Semantic relationships between colors that should stay consistent
These colors also don't exist in isolation.
Your editor.background needs to work with your editor.foreground.
Your syntax.keyword needs to contrast with your syntax.type.
Your error indicators need to stand out against your gutter.
Change one color, and you're suddenly playing whack-a-mole with readability issues across your entire interface.
Maybe even a bigger challenge is figuring out which color controls what.
You're looking at a JSON file with properties like editor.background, panel.background, surface.background, toolbar.background: four different backgrounds for four different contexts.
Which one affects that element you're staring at?
Your guess is as good as mine.
Change text and suddenly all kinds of elements change.
But icon is separate, even though icons often live right next to that text and need to maintain the same relationships.
Some theme properties are intuitive, but others require more trial and error.
The theme system is powerful and granular, but that granularity means you're constantly asking "Wait, which property controls this thing?"
There has to be a better way!
Introducing Theme Builder
Theme Builder is a visual editor for creating Zed themes. No more JSON tweaking. No more save-switch-check cycles. Just pick colors and watch your theme come to life instantly.

The interface is split into two parts:
- A live preview that shows an interactive replica of Zed's UI
- A sidebar with all theme tokens organized by category
Every change you make is reflected instantly in the preview. Pick a new background color, and see it immediately. Tweak your syntax highlighting, and watch your code transform in real-time.
The Inspector
Here's where it gets really cool.
Ever looked at an element in your theme and thought "what token controls this color?" Instead of hunting through 200+ options, just right-click on anything in the preview.

The inspector highlights the element and shows you exactly which theme tokens are used. Click on a token, and it will bring you directly to the right color input. It's like having browser DevTools, but for your theme.
Color Linking
Here's another common scenario: you want your panel backgrounds, tab backgrounds, and surface backgrounds to all share the same base color. In raw JSON, you'd have to update three different values every time you change your mind.
Theme Builder introduces color linking. Instead of setting a fixed color, you can link one token to another. Change the source, and all linked tokens update automatically.
We have pre-configured recommended links between related elements. Things like keeping focus borders consistent, ensuring icons match their accompanying text, or maintaining the same base color across different types of surfaces. These suggestions help you avoid visual inconsistencies without limiting your creative freedom.
These are suggestions, not requirements. You can replace any link with a custom color, or create your own linking patterns. The goal is to help you avoid accidentally creating visual inconsistencies while still giving you full control.
Syntax Highlighting
The code in the preview isn't just colored text, it's actually syntax-highlighted using the same approach Zed uses: Tree-sitter.
There are two common ways to do syntax highlighting: either with TextMate grammar (used by VS Code) or with Tree-sitter (used by Zed). Most web syntax highlighters use TextMate, but for Theme Builder we needed the exact same highlighting as Zed itself.
So on the server, we parse the code into an AST with Tree-sitter grammars running in WebAssembly. We then map those AST nodes to Zed's syntax token names, using the same query patterns that Zed uses internally. The result is pixel-perfect syntax highlighting that matches exactly what you'll see in the editor, while keeping the heavy lifting out of your browser.
Keywords, functions, types, operators, they're all highlighted exactly as Zed would highlight them.
Import/Export
Already have a theme you love? Import it directly into Theme Builder to use as a starting point. We'll parse the JSON and set up all the colors and links for you. When you're done creating, you can easily export it as theme overrides or even generate an extension file for when you created something truly unique!
We've included a few built-in themes to get you started: One, Ayu, and Gruvbox are all available out of the box.
Technical Tidbits
For the curious, here's how the magic happens:
Pixel-perfect preview is powered by HTML recreations of Zed's UI components. Every panel, tab bar, and editor element is built to match the real thing as closely as possible, so you can see exactly how your theme will look in the actual editor.
Instant updates are powered by CSS custom properties.
Your entire theme is injected as CSS variables like --editor-background and --syntax-keyword-color.
When you change a color, we update the variable and the browser handles the rest.
No re-renders, no virtual DOM diffing, just pure CSS doing what it does best.
State management uses Zustand with a history system. Every color change is tracked, so you get full undo/redo support. Accidentally nuke your carefully crafted palette? Just hit undo.
Persistence lives in local storage, so your work survives accidental page refreshes. Create multiple theme families, each with their own light and dark variants, and they'll all be waiting for you when you come back.
Try It Now
Theme Builder is live at zed.dev/theme-builder.
Whether you're creating your own fully customized theme, or just want to tweak an existing theme, we hope this makes the process more enjoyable. And if you create something beautiful, we'd love to see it!
Happy theming! 🎨
Related Posts
Check out similar blogs from the Zed team.
Looking for a better editor?
You can try Zed today on macOS, Windows, or Linux. Download now!
We are hiring!
If you're passionate about the topics we cover on our blog, please consider joining our team to help us ship the future of software development.