Making a VSCode theme the smart way

zevro

Zev

Posted on January 17, 2024

Making a VSCode theme the smart way

Making a VSCode theme is relatively simple - all you really need is a single .json file.

However, this comes with a whole bunch of problems, the biggest one being the fact that you can't use variables in a .json file. What if you want to change a color that was used in multiple places? You'd have to manually replace every single instance of that color.

Now you might think, well, with find & replace, that doesn't sound so bad. But what if you want to make multiple themes? You'd have to copy the entire .json file, and then change every hex value manually!

When I made my own theme for VSCode, I already knew that I wanted to make many variants, so I wanted to find a way to use variables to make themes instead of writing every hex value literally.

So now that I've figured out how to do it, I'd like to share that method so that anyone else who wants to make their own theme knows how.

Setting up the project

The first thing you'll need to do is to create the project itself. Detailed instructions can be found on the VSCode documentation, but basically all you have to do is type the following in your terminal and VSCode's yeoman cli will help you generate the rest.

npm install -g yo generator-code
yo code
Enter fullscreen mode Exit fullscreen mode

However, instead of creating a .json file, create a new TypeScript (or Javascript) file in your src/ folder, and name it whatever you want.

Making the theme

In this file, you can define all your color variables. Then, make a function called getTheme() which returns a JSON object. This JSON object should be in the format of a theme JSON, meaning it should specify the name, whether it's a dark, light, or high contrast, and the colors that the theme consists of. Then, export the function you just made, like so:

// src/mytheme.js

const blue = "#2D3079"
const blue2 = "#2C2E58"
const white = "#FFFFFF"
const black = "#000000"
// define as many colors as you want...

function getTheme() {
  return {
    "name": "My theme",
    "type": "dark",
    "colors": {
      "editor.background": blue,
      "editor.foreground": white,
      "editorIndentGuide.background": blue2,
      "editorRuler.foreground": white,
      "activityBarBadge.background": black,
      "sideBarTitle.foreground": white,
      // ... add as many changes as you want
  },       
}

module.exports = getTheme
Enter fullscreen mode Exit fullscreen mode

If you want to use translucent colors, you can either hardcode the alpha value at the end of the existing hex values, or you can use a helper function. For mine, I used the colors-convert package.

npm install colors-convert
Enter fullscreen mode Exit fullscreen mode
// src/mytheme.js
const { hexToHexWithAlpha } = require("colors-convert");

function hex(color, alpha = 1) {
  return hexToHexWithAlpha(color, alpha);
}

// example usage:
    "list.dropBackground": hex(blue2, 0.3), 
Enter fullscreen mode Exit fullscreen mode

Once you've customized all the color values (a detailed description of which can be found here), there's still more work to be done. First, we need to go into index.js to actually create the .json file from the function we just made.

// src/index.js
const getTheme = require("./mytheme")
// ... import any other themes you made
const fs = requre("fs").promises
// generate the json and store it in a const
const myTheme = getTheme()
// ... do the same for any other themes you've made

// write the .json file
fs.mkdir("./themes", { recursive: true })
  .then(() =>
    Promise.all([
      fs.writeFile(
        "./themes/my-theme.json",
        JSON.stringify(myTheme, null)
      ),
      // call fs.writeFile() again on all your themes
    ])
  )
  .catch(() => process.exit(1))
Enter fullscreen mode Exit fullscreen mode

Now, if you run the extension in debug mode by pressing F5, you should see a new themes/ directory with a brand new .json file in it!

All you have to do now is register your theme in your package.json file:

// package.json
{
  // ...
  "contributes": {
    "themes": [
      {
        "label": "My theme",
        "uiTheme": "vs-dark", // or "vs" if it's a light theme
        "path": "./themes/my-theme.json" 
      } 
      // ...repeat for the rest of your themes
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

And congratulations! You've just created a whole bunch of themes. Just remember that if you make any changes, you must run F5 again to write the changes to the actual .json files or none of the changes you made will actually change the theme.

To see a full example, check out my theme, lightning, on github. Or, you know, just install it and give me a rating if you like how it looks!

Happy coding!
Zev

💖 💪 🙅 🚩
zevro
Zev

Posted on January 17, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Making a VSCode theme the smart way
vscode Making a VSCode theme the smart way

January 17, 2024