One of the most frustrating things any Web Developer has to deal with is constantly having to refresh their browser any time they want to preview a tweak to their code. When building out UIs, this can be a significant drag on your development experience, as you keep having to refresh, losing the current state of your application every time. Thankfully there are tools such as hot-loading that solve this issue by automatically rebuilding your application and re-render the DOM every time you save a file.
Once you experience this massive life improvement it's hard to go back. Now enter the world of Figma plugin development; any time you want to view any changes to your plugin code, you have to wait to do the following:
Our plugin takes a few seconds to fully reload, as we make all the necessary API requests to load the user's data. This quickly adds up when you are debugging issues inside your plugin. As you have to relaunch the plugin, wait for it to load, and then manually navigate back to the desired state you wish to test. Debugging becomes even more complicated when you don't have access to your favorite chrome extensions such as 'React Developer Tools' to help you debug state issues inside your app.
There has to be a better way...
This all resulted in a pretty poor developer experience whenever we needed to add a new feature to the Ditto plugin. It would take significantly longer to build and test a new feature vs what it would take to perform the same task in our web app. But one of the great things about being an engineer is if you don't like the tools you're using, you can go out and create your own.
Figma Plugins are just web apps wrapped in an iFrame, that communicate with Figma via posting and receiving messages:
Due to this architecture, plugins need to be bundled and developed inside of the Figma sandbox to access the contents of a Figma design file.
By adding a middleman in the message passing stage, you could decouple your plugin and the Figma sandbox environment. This would allow you to run your plugin in a browser as a normal web app while still having a means of communicating with Figma. The big advantage of this is that you would be able to leverage all the tools web developers have at there fingers such as hot-reloading and Chrome Extensions to help debug your application.
We decided to utilize a websocket server that acts as a proxy between our plugin and Figma. Messages generated by the plugin or Figma are sent to the websocket server, and then forwarded to any other connected clients. Our plugin is a React app that we wrapped inside of a 'Preview' component to render the plugin in a browser and to handle the message proxying logic to our websocket server. In Figma we run the 'Preview' app as a 'dummy' plugin to give our plugin access to the Figma sandbox, and to send Figma generated events such a mouse selection back to our browser based plugin.
With this solution in place we are now able to develop and debug our Figma plugin in real-time, and we get to leverage all the tools we would have developing any other web app. New features take a fraction of the time to build out than before, resulting in much happier engineers and customers. Most importantly it's more fun to build out Figma plugins than ever before!
We have learned a lot from the Figma Plugin community over the past year, so we are excited to give back and share what we've built. You can find a sample template below that you can use to build your own Figma Plugins in the environment of your choice: