A Figma plugin that automatically generates dark themes

Hi. I am a Product Designer at Yandex.Maps. Today I would tell you how we generate a dark theme with the self-created plugin. Additionally, you will know why we are using semantic color styles and why you should too.
Why semantic color styles better
Right now, many apps already support a dark theme or have plans to will add it soon. Dark theme on the hype. Before, we used declarative styles set and rules for creating a dark theme variation. This approach has a lot of problems. Let’s look at one example with the text layer:

If you used declarative color styles, you could choose any color on the pallet. But it’s not true. You could use only selected color styles. It seems you need to keep in mind all these rules or constantly checked them. It creates a lot of mistakes.
We decided to use semantic color styles grouped by type of object. These are four groups: text, background, icons, buttons.

Now, when you select any object, you always choose the right color style. Additionally, semantic color styles could be doing more if you have a dark and light theme 🙂.
Generating dark or light theme with a plugin
Creating a dark theme from the light may take a long time. It is a boring thing. I was thinking about how to automate and improve this process. To prove my theory, I created a plugin with fixed color styles. I used external color style id’s. It works but had some flaws: all color styles are should be used in the file, any style changes in the external team library broke the plugin.
After that, I found plugins with similar functionality. But I could not use them for several reasons:
- Themer. It works only with the jsobin service. It needs to create rules for turning the dark into a light theme.
- Lights. It can not work with the external team library. Our team using only design library styles. You should use only two style groups (Dark and Light).

I decided to finish my plugin with external library support and flexible naming. The interface has three menu items:

- Dark mode. It turns the selected object to dark theme mode if the color style name has [day] and has [night] analog.
- Light mode. It works like dark mode, but the other way around.
- Save styles work with the external library styles. You need to do this in your team library file. The plugin gets color styles from the file and saves them. Then open any linked file, and all be work.
The styles should have [day] for the light theme and [night] for the dark theme. You can use it at any place of your style names. Below example our text color styles:

This flexible naming allows group color style as you want. It is one of the key features. Finally, the plugin generates a dark/light mode.

How it works
The plugin used three methods:
- getLocalPaintStyles — Get styles from the current file
- setAsync и getAsync — Write and read in the Figma local storage
- importStyleByKeyAsync — Import color style from the external team library
All Figma plugins may work only in the current local file. getLocalPaintStyles return only local styles. You may get access to the team library styles if you have keys, using importStyleByKeyAsync. It is a big problem for us because our team using the external library styles only. Firstly, I used Figma API to get style keys, but Figma did not recommend using this way. Then, I decided to use Figma local storage for store-style keys. I get them using getLocalPaintStyles in the library file when selected “Save styles” at the plugin menu.
The plugin used style.id at the object fillStyleId for fill any objects. But if color styles updated also changing style id. And that’s why the plugin using importStyleByKeyAsync.
Bellow, you can see importing style example. The plugin can work every time, even if you changed the name of the color style.

Code of the plugin you can see on my Github.
Also it available on the Figma Plugins page.

Conclusion
- Whenever you creating a dark mode theme you can see mistakes.
- Using a semantic palette you always choose the right style.
- The plugin saves time for designers, developers, and testing.