P.S. I did not do it alone.
It’s about time I talked about the unofficial plugins system for Figma (Figma Plus) and how it was born.
Personally, I’ve been benefiting from the tech community work all of my career. It’s about time I give something back.
Let’s face it.. Figma is freaking awesome!
However, I came from Sketch and one of the things that always put me away is the lack of plugins.
Until, I saw Figma Dark UI Plugin.
I froze for a little bit and though to myself…
I’ve been injecting CSS and JS to websites since I knew the internet existed.. and it never occurred to me that Figma is also a website!
I was intrigued thinking.. there must be a way…!
So, I challenged myself to build not just a plugin…. but a plugin system for Figma.
I started fiddling around.. it was my first time writing a plugins system, but I did…
and..
Figments was born!
This link is for an old commit in what’s now the repo for the advanced rename plugin.
But How?
Yeah, I get it. Let me explain something… Figma is a website. Adding your own CSS & Javascript to websites is pretty easy. whole startups were established by doing just that.
It started as a challenge, only to discover that there were others that tried to do it too. We eventually joined forces.
There was one important discovery that made all of this possible.
window.App
It’s is Figma’s frontend javascript app that communicates with their backend.. and it’s available on the window object… SWEET!
We did however had to reverse-engineer the hell out of app.js to find useful publicly accessible APIs.
The unofficial plugins system for Figma
The system was built using 2 main components, factory and figments.
Factory:
The factory injects a dropdown menu Figma’s UI, and iterate over the plugins (figments) inside /src/figments directory to add an option for each one.
Figments:
Each figment is an object with 3 required properties: name, setup(), main().
Example plugin
const counter = {
// Displayed in the injected menu
name: "Counter",
state: {
counter: 0
},
// Think of it as the constructor for your figment
setup() {
console.log(`Counter ${this.state.counter}`);
},
// Called when a user clicks on the injected menu option
main() {
this.state.counter++;
console.log(`Counter ${this.state.counter}`);
}
}
export default counter;
And boom, I have created my first plugin system ever. NOICE!
Simulation vs. Reverse Engineering
Now, my first try to create a plugin was Batch Renamer, before Figma did theirs 😝.
I had no idea where to start, so I started doing what I know, which is simulating user interactions to automate select then renaming layers.
The first problem was that I was selecting layers by using document.querySelectorAll, but since Figma is using a “Virtual List”, not all layers are actually in the DOM to be selected. Thus, the first release had a limitation of 50 layers (depends how tall your screen is).
After fighting with it for a few weeks, Jackie released his “Find and Replace Plugin”. I saw that he’s accessing something weird… window.App.
I took a look at what he’s doing, and voila, the plugin was done.
Batch layer renamer (it’s better than Figma’s)
Now, although making the renamer was tedious, it does not even come close to what content generator plugin was. I almost lost my s*** working on it.
I went to great lengths trying to simulate copy/paste, reading the clipboard, simulating drag-n-drop, encrypting and decrypting images. I learned so much about blobs, clipboard, reverse engineering, trial and error.
My initial implementation was a bit naive.. I did not consider how to load new plugins on the fly. This means that whenever a new plugin is created/updated, I have to rebuild my system. I could’ve done that eventually, but it would’ve taken me ages to do.
Still not ready
As I have said before, but to be precise… there were multiple issues that I needed to tackle:
- A streamlined way to develop plugins.
- An easy way for devs to publish plugins they created.
- A way for Figma users to browse and install those published plugins.
- Provide all of the above for “Figma for Desktop” users.
By creating a plugins system, I just solved 1/4 of the problem. And it’s too much to just do it alone.
—
Assemble
The day I wrote about my plugins system in Figma’s Community, the awesome Jackie Chui has just released his Find & Replace plugin, it’s brilliant.
After a small discussion, we decided to team up. Mirko, Jackie and I to create what I aspired to do, AND MORE!
Alas, the problems we have to solve
This was one of the biggest side-projects I’ve worked on. It has a lot of new things that I have never done. That’s what makes it awesome!
without further ado…
Problem #1: A system
It has already started, people were creating plugins for Figma as Chrome Extensions. While that might work just fine, it’s not the best solution. We wanted to standardize how we (and potentially others) create plugins for Figma.
We’ve set out to create a standard way of creating, installing and developing plugins.
- We will create a plugin manager that works for both browser and desktop.
- The manager should read a JSON file that has the directory of all available plugins and provide them to be installable on the user’s machine.
- Provide a set of useful API for Figma so that devs can create plugins more easily.
One thing to note is that instead of limiting you to factory-like lifecycle.. the new plugin system should allow you to create your own plugin lifecycle however you want. It’s just a Javascript app that runs inside Figma.
Problem #2: A manager
We wanted to create a full-blown user experience for discovering, installing and developing plugins.
Since we decided that the manager will be inside Figma, we wanted it to look native.
Jackie Chui blew us away with his work. In a couple of weeks, he managed to design and develop a plugin manager built with Vue.js. It’s remarkably amazing and does the job and more.
It provides a way for users to browser, filter, install and uninstall plugins. It also auto-updates your plugins every time you reopen Figma!
Problem #2: The developer
After using the manager, it was a PITA to try my plugin with Figma. I had to do this every time I change a single line of my code:
- Build my JS (I use es6).
- Copy code bundle.
- Reload Figma.
- Paste it in Chrome DevTool.
- Try my code.
- Repeat.
That’s a lot, just to test one small change. We had to had a developer mode. I managed to create a localList for the plugin manager to load, it was working fine with me. Until I shared my idea with Jackie, he created a better solution.
From the plugin manager, there’s a developer tab which provides you handy tools to include your localhost served JS/CSS files once, and then just do this:
- Build my JS (I use es6).
- Reload Figma.
Now that’s a better development experience.
Problem #3: Security
Since we will be running JS code in your browser, we wanted to make sure that the code you install is safe. That’s why in order to submit a plugin, you need to create a PR in the repo. We will test the plugin to see that it’s not doing something fishy, then approve it.
We also wanted to make sure that the code you installed stays the same and that if the developer changes the plugin code, the manager won’t run the plugin until the developer submits a pull request in the manager repo. We rely on Github Releases + JSDelivr to cache them. For now, it does the job as intended.
Problem #4: Figma
Let’s face it… Figma is proprietary software, and at any minute they can decide to take us down and we can’t say anything about it, because it’s theirs.
—
And we did it!
We wanted to create a full-blown user experience for discovering, installing and developing plugins.
It was a bumpy ride, but it’s finally done:
- A plugins manager for people to browse and install plugins.
- Devs can publish their plugins by opening a PR in the plugins-manager repo.
- Devs can write their plugins with their preferred way.
- All of this is available for “Figma for Desktop” by using Figma Plus Installer.
- A helpful documentation and guide to write your next cool plugin.
- A nifty landing page for our creation.
You can read the full introduction post on here.
A thank you note
The amazing Jackie, for doing all of the work with me just standing still being amazed with every commit he did. Thank you.
The inspiring Mirko, for creating the Dark UI Plugin that started it all, and for designing the website, and for donating the logo. Thank you.
Thank you Github, JsDelivr, Slack and Spectrum. Your awesome software made our lives easier while working together.
A quick demise
After releasing Figma Plus, we had 14 plugins bundled with it. In under 2 weeks:
- 3 plugins were added from the community (Figma RTL, Figma Iconify, and Figma to Marvel).
- We had almost 4000 users, with over 12K installed plugins.
There was a couple of tiny issues…
In order for a developer to test his plugin locally, we had to bypass certain security measures that Figma had in place. But this is only for developers. As for users that install plugins, the security measures were untouched.
This was a compromise that we knew about, and warned developers about in our documentation.
Moreover, all of the work we did was based on reverse engineering Figma’s JavaScript. This does not only mean that our plugins could break very often… it also means that our work might destabilize Figma or may be break it!
Unfortunately, this was obviously not a good thing for Figma, so we had to take it down. You can read more details from here and from here.
We totally understand and respect Figma and where they stand in regard to Figma Plus.
What’s next?
We have been invited by the Figma team to join an early access program for the upcoming official API. We’re going to build our plugins in an officially supported format that benefit the users and don’t compromise anything.
Stay tuned.
Enjoyed the story? Don’t forget to leave some 👏👏👏👏👏 down here and share this story with your Figma buddies. Also, follow me on Twitter here for updates about Figma and other design stuff (I tweet in both English and Arabic): https://twitter.com/cdes
Ahmad Al Haddad is the Head of Product Design & Prototyping at Tam Hub, a multi-disciplined designer/developer from Saudi Arabia.
Top comments (0)