What I learned creating my first Figma plugin

I got into the Figma beta program about six weeks earlier before it was publicly announced. It felt like a huge opportunity. I saw how Sketch plugins did, and I knew this would be even bigger for Figma. I wanted something of my own that I could build, iterate upon, and take care of. But there was one problem.

I had absolutely no idea what to build.

The four weeks out of the six passed like nothing, I wrote exactly zero lines. I did go through the Plugin docs and build my bare-bones react app with it, but that was about it. I was sure that I'm not going to build anything.

Then as we were discussing with my colleagues at Kiwi.com what should be our standard mobile device to design for, we agreed that we should design for the most popular one (🤯), but it was hard to keep track of which devices are popular and where. And this is when the idea to have a list of different display sizes with their market share occurred. So I started coding.

I didn't really think it through. I started coding right away and decided to figure stuff out as I go. I managed to release the plugin, and in the first weeks, it gathered over ten thousand installs. But right after the release, the fall and winter of 2019 challenged me both personally and professionally. And I didn't progress at all because of that.

Fortunately, right at the beginning of the new year, I achieved my long dream of going over to Japan, and ride their pow covered hills. I had it on my list for the past eight years. While it was exhausting, and my body was at the edge of its limits, my mind was finally able to rest. It was truly an amazing experience.

When I was flying back, I had nine hours to spend on the plane. I knew that I need to release a new version soon. I was working on it here and there, but it was far from finished.

I also didn't update the analytics data for a while, and I felt really bad about it. And the design of the plugin itself wasn't holding up either. But I didn't want to make the same mistakes, so I decided to reflect on what I've learned, so it won't happen next time.

What Viewports do on the high level

In a nutshell: Viewports lets you to effectively preview your designs in the context of different markets. You launch the plugin, you select a frame or your desired element, you click on the display size, and the frame changes to your selection. That's it. The functionality is not that different from the native one, but seeing all the options and their market share is giving it the much-needed context.

What is the technological stack

This is the GitHub repo. The main sections here are:

  1. Client - Client is the actual plugin that you see in Figma. The framework of choice is React. Currently, it can only run in Figma. But together with the last huge version bump, I made some preparations that will enable me to make client platform agnostic. Meaning: I will be able to port it as a standalone website or as a browser plugin.
  2. Server - The server isn't really a server. It is a collection of serverless now functions. They are very simple, and all they do is that they make a request to Firestore DB, format the data, and return it to the client.
  3. Tasks - Collection of scripts that I run locally. They are there to generate, process, and upload data.
  4. WWW - Next.js website running on now.sh. Although I didn't publish it yet.

Everything was originally written in JavaScript but was later updated to Typescript. And for now, it requires just a small amount of resources to keep up and running.

So ... now that you know what Viewports is and what it does technically, we can jump straight to the first lesson learned. Which, by my guess, you already know what is it about.

Over-engineering the problem

Initially, I had great ambitions. Ambitions like I'll have a server that will keep display AND device information, with a market share, and that it will have its API that will be available for other developers to use. And that it would be a good experience to create a micro design system from react components and share it with the multitude of other plugins that I will eventually create. And that everything will be in a mono repo with everything covered by typescript and tests.

Now, these all sound quite good on paper. You can see the value, but if you are like me (totally unexperienced with any serious programming), you don't see the investment needed to make these happen. If you can visualize the path needed to make all of the above happen, imagine that there will be not be one but multiple problems at every step.

Although, I did manage to pull some of them off. And I did learn how to write API, how caching works, how basic API security works. And how it all relates to UX. I also learned how typescript could help you avoid bugs in your code, and make sure that you don't break things.

But what you need to know that all the tutorials on the internet are edited in a way where there are no problems. Everything is smooth sailing.

So, if you are an inexperienced developer as I am. You will encounter problems at every possible step. You will make a typo that you won't be able to find for what feels like forever. Or the libraries you desperately need are optimized for slightly different usage, and you will have to come up with a way how to make it work for you (because you overengineered the whole thing). Or some packages won't be supporting typescript yet, so you will have to learn how to generate your own types. Or for some reason, your OS will be using a different version of node than what is set, and you will have no idea why. It is a constant trial and error and error and error process.

It was hard to maintain and gather information (and keep the plugin updated)

The original premise of the project was that I would gather a broader spectrum of information on a limited number of devices. Devices like iPhones, Google Pixels, the most common list you would find in every other design tool. I wanted to keep information like what OS they are running, which OS version they support, display ratio, scale, dimensions in pixels.

I wanted to include just the basic models like iPhones and some Google pixels. But then users asked why I don't have more devices like Samsungs. So I added the most popular Samsung devices, but people requested more. So I added these as well. But since the database was growing, I created scripts that helped me to maintain the data and keep it valid. I also automated some parts of content generation like aspect ratio and orientation.

Then tablets and desktops were a pretty common request. And the initial premise ended up being unachievable. There was no way I'm going to collect such a huge amount of information for so many devices. I needed to make the switch to something more tangible that would help me react to new devices on the market and push out the update as fast and with at as least effort as possible.

So I ended up ditching the whole device dataset. All the work disappeared. All I kept around was just the width and the height. It was a huge simplification of the whole process. Now I can react much faster because of automation! Which again ...

The biggest takeaway should be that if you plan to create a side project, its viability shouldn't be determined whether it will make money. But whether it will be possible to have the time necessary to keep it running before you will even have a chance to make some money (if ever any). Lots of side projects die because they require a lot of time to keep running, and their creators run out of time.

I invested too much time into DB tooling which I had to completely redo

Even though I didn't validate whether the original device approach would work, I invested a lot of my time writing utilities that helped me to keep all the data valid and upload it periodically to Firestore. But because I made the switch to displays, and since I added support for different continents as well, I had to completely rewrite EVERY script.

But I managed to upgrade the logic, and now the script informs me of any missing resolution from my database, and when such a display is detected, it updates the original database automatically. It also removes no longer used devices/displays, so only data with some market share are kept around. The manual maintenance is now minimal, but the effort was quite huge from my side.

It might be a no brainer, but you should really think through your product before you start making it. Or rather, if you are about to invest a huge amount of time or money, make sure everything is laid out. So you won't end up backtracking back to the drawing board as I did. It isn't always possible, but gathering feedback from your fellow engineers or ppl who have at least some experience with building products will help you avoid these mistakes.

And now you can almost see the pattern ...

Changing technology and things too frequently

Designers often tend to be perfectionists, which can be sometimes daunting when designing a landing page, but it can surface on a completely different level when you code. I always wanted to use the best technology. I had to have the best performance, the most though through the system.

I switched from having a server on Heroku to serverless functions, it saved some money, but I wasted so much time learning and reimplementing the same stuff. The same goes for going from JavaScript to Typescript. It is now more bug-free, but I had to rewrite everything. It still costs me quite a lot of money to keep it up and running but at least not as much as before.

If I would manually write the database as a JSON and then bundled it in the plugin, it would help me to iterate far faster. Because of all the technology and tools that I set up, even small changes took me too long to deliver, and I wasn't able to react to the huge amount to feedback. And while there was a ton of stuff happening in the background, it seemed like the plugin is dead or no being updated.

This mindset is called "Premature Optimization". You spend too much time on things which you might not need. Thus, my biggest mistake was that I wanted to have it all, right of the bat. And if I moved a little bit more thoughtfully and reacted to the needs of the product, rather to my megalomanic vision. I could ship the last update at least three months earlier.

The plugin has too many dependencies

The success of this project entirely depends on my ability to gather data from third-party providers, and so far I have only one. It is a pain in the ass. This makes my plugin only a small client with an uncertain future, although this is quite common for Figma plugins.

Some plugins make it easy to use third-party content (material icons, google maps, icon libraries), which is fine, but they will be around as long as the original authors won't enter the game. Which they may or may not. You never know. And once they do, you can't really "fight" the official support.

That is why my next step is to detach my plugin from the data provider or find alternatives that I could offer. Or start offering my own. Unfortunately, I don't have any analytics services that I could collect my data from.

So, instead, I will work with the data that my users will provide. You will be able to see data for your product, instead of high-level continental analytics. Which will bring even more value to you and Viewports will be able to live on its own.

This is the end, my awesome friend... but it doesn't have to be! You can reach out at Twitter, inspect what I design at Figma, and checkout what I code at GitHub.