Skip to content

Making Figma Variables Make Sense

Posted on:January 25, 2026 at 04:00 PM

I’ve really enjoyed using Figma ever since I started migrating from Adobe XD around 2018. I was delighted by the fact that the program didn’t crash every 15 minutes when more than one person was using it at the same time. It was the true real-time collaboration that XD promised, and Figma ended up delivering. It’s had room for improvement, and it’s been implementing a lot of features I had always hoped that design tools would add, such as robust variable sizing for divs in the form of auto-layout, aligning text to its actual size rather than including the spacing or by its baseline, robust composable design components in the form of Figma components, and so on.

Figma String Variables

I was thrilled when variables were introduced. With their introduction, the right panel got a lot less cluttered with many of the design variables actually moved to the new system instead of having an nCr number of combinatory options on one’s component properties. They could easily be changed later, and the changes would instantly propagate across pages and files.

One thing that stood out as odd to me was the fact that the text variables can only be applied to entire text fields.

Two text nodes: the above one having a variable applied and its value being the value of the keyword, whereas the bottom one shows that the variable cannot be applied to a substring of the text.
Two text nodes: the above one having a variable applied and its value being the value of the keyword, whereas the bottom one shows that the variable cannot be applied to a substring of the text.

As seen above, one cannot bind a substring of a larger text to the variable, which felt like a huge missed opportunity to me. One needs to use workarounds to make something like that happen.

A set of three split text nodes to apply a variable to some of it
A set of three split text nodes to apply a variable to some of it

And as it always is with workarounds, there are couple of limitations to this approach. You have to set the spacing between the text nodes to exactly match the width of the space character, which is also impossible to sync with the actual font size, so whenever the font size is changed, you must change the spacing manually. There are also a bunch of problems that arise with wrapping, but I won’t get into the details of the drawbacks of this method.

I looked through the Figma plugin documentation to see if I could achieve binding a part of the text to variables, but the only publicly available APIs for text content were about text styles.

Building the Extension

So, I got down to building an extension myself. The mechanism itself is pretty simple, given the limitations of the plugin system. I cannot hook into events such as when nodes are edited for the plugin to run in the background silently. One has to keep the plugin open for it to listen to events, which mostly makes sense but could be useful in cases of “run-in-background” type of extensions such as the one I was building. To minimize the impact of this limitation, I made a feature to minimize the plugin window as much as possible.

I digressed a little. Let me get back to how the extension actually works. It basically monitors when one focuses on a node and when one focuses away from it. Each text node has two versions of the text: display text and placeholder text. Placeholder text is what one would write directly into the text nodes, and display text is what would be displayed once one is done editing. Every time a text node starts to get edited, the text is changed to the placeholder text, and once it stops being edited, it changes to the display text.

Whenever the change is made from placeholder text to display text, it uses regex to look for @word. (Note to self: make the prefix configurable) Then it looks at a preconfigured collection - “Keywords” by default - and looks at any variable called word and replaces it with its value.

Above text node will turn into 'When focused... my-value' once it loses focus.
Above text node will turn into 'When focused... my-value' once it loses focus.

Of course, grouped variables are also supported if one just uses @groupname/word.

And voilà! Now we have a system where one just uses the keyword to type out in the text boxes and whenever one is done editing, it changes to its corresponding value. One just has to remember to turn it on whenever one is editing text and maintain the Keywords collection.

Of course, first-class support for such a feature would be more ergonomic and streamlined, but at the core, it seems like with the currently available set of APIs provided by the plugin system, the workflow is going to be variations of my implementation.

The source code is open on GitHub at https://github.com/noidwasavailable/figma-keyword-replacer. Feel free to open pull requests for bug fixes and feature implementations, as there must be bugs; I haven’t robustly tested it. I have already found a bug and a feature idea I’d like to implement soon—which I’ll ideally do before this blog post goes online!