Is it possible to build plugins for multiple design tools with a single code base?
Tags: plugins, cli, sketch, figma
Published: 2020-02-23 13:42:12

---
title: Is it possible to build plugins for multiple design tools with a single code base?
published: true
description: A breakdown of DTPM, a command line utility that helps you develop plugins for Sketch, Figma, and Adobe XD using a single API.
tags: plugins, cli, sketch, figma
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/dnzothg0wva96vd4k3l6.png
---

_tl;dr DTPM is a proof of concept command line utility that would allow you to develop plugins for Sketch, Figma, and Adobe XD using a single API. [Check it out here.](https://github.com/jodyheavener/dtpm)_

---

If you work in the design space you probably use tools like Sketch, Affinity Designer, Figma, Adobe XD, Photoshop, Illustrator, InVision Studio, Procreate… the list goes on and on. You're also more than likely familiar with the massive landscape of plugins that come with certain platforms. Photoshop has had them for nearly two decades, Sketch has had a pretty vibrant community for the last few years, and a few other tools have also started supporting them over the last couple of years, with more on the horizon. Plugins can be novel, they can handy at times, and in some cases they can be critical to ones design process. If you're not familiar with plugins, do check them out ([Sketch](https://www.sketch.com/extensions/plugins/), [Figma](https://www.figma.com/community/plugin/all), [Adobe XD](https://helpx.adobe.com/xd/help/plugins.html)).

These days they’re also pretty fun to make, and the possibilities are endless. The development environments tend to be based in JavaScript with a handful of a host properties and methods, so it’s usually not too difficult to start working on your own plugin. 

I’ve built a handful of plugins myself, and while the barrier to entry isn’t necessarily huge if you’re familiar with some basic JavaScript, I’ve noticed that as more design tools adopt the ability to expand their platforms with plugins they tend to implement the setup, manifests, and APIs in vastly different ways. I suppose it makes sense; they have no incentive to work with one another to create a consistent development environment, and in some cases they might want to expose unique functionality that their tool offers. It’s great that they’re supporting plugins, but the inconsistencies can sometimes suck as a developer if you’re trying to build the same plugin for multiple tools.

#### So what can be done about these inconsistencies?

I’ve been pondering this for the last few months, and today I want to demonstrate a proof of concept solution for a tool that would allow someone to be able to develop a plugin one time — that is, use a single API to interact with the platform’s components and capabilities — for multiple design tools.

#### What am I hoping will come from this?

I like to think of it this way: web browsers provide the same level of basic functionality. You can open a web page, interact with it, share it, and much more. Some browsers do things a little better than others and some provide bells and whistles to make the experience better, but at the end of the day, they’re all generally doing the same thing. The top browsers, even though they’re in competition with one another, for the most part all implement a similar structure of [Browser Extensions](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions). There’s even a [W3C Draft Spec](https://browserext.github.io/browserext/) for it.

Much like browsers, these tools generally provide the same set of functionality, each with their own unique presentation, and a handful of speciality areas. So why shouldn’t they also support a consistent structure for plugins?

My goal with this project is to normalize development across multiple tools, find overlaps in the structures and APIs, and perhaps plant a seed that could one day lead to something of a “plugin spec” that all design tools could adhere to. 

But at the very least, a neat little proof of concept is always fun.

## Introducing DTPM

The **Design Tool Plugin Manager**, or DTPM, at its core is two things: a bridging API that provides a common interface for interacting with plugin environments, and a CLI that allows you to generate templates, compile your plugin files, and load it into each respective tool. Both of these things come from the `dtpm` command line, available on [npm](https://www.npmjs.com/package/dtpm).

_I’m aware I use the words “tool” and “platform” interchangeably. I’m also aware “Plugin Manager” isn’t the best name for this utility. Do not email me._

If you build plugins and this utility looks at all familiar it might be because I got a lot of inspiration from [xdpm](https://github.com/AdobeXD/xdpm) and [skpm](https://github.com/skpm/skpm).

As of writing, DTPM supports generating plugins for [Sketch](https://developer.sketch.com/), [Figma](https://www.figma.com/developers/), and [Adobe XD](https://adobexdplatform.com/). I initially was trying to also support InVision Studio, but their plugin environment isn’t ready.

### Why these platforms?

As I mentioned previously most plugin environments are based in JavaScript, and these three are no exception. This makes it that much easier to provide a common development setup, without needing to wrap additional programming languages around each platform.

You may have also guessed from the JavaScript, but each platform also supports some degree of HTML and CSS when building out interfaces. This is a little more nuanced, though, so we’ll get to that later.

These platforms also all have bustling plugin development communities! This is one of my favourite parts, because it’s important to have others that you can bounce ideas off of, get help from, and in some cases even provide feedback to the platform creators.

Finally, all three design tools are rapidly evolving, and their plugin environments (for the most part) are keeping pace.

### If they’re all based in JavaScript, what’s the problem?

For me, the biggest hurdle when building plugins for multiple platforms is that each one has different expectations.

Here are just a few examples:

- Sketch and Figma both have document API environments separate from UI environment APIs, while XD exposes both APIs in a single environment.
- Figma expects you to signal when your plugin is finished running, but Sketch and XD don’t seem to care.
- XD and Sketch both support instantiating and manipulating layers before inserting them into the document, while Figma inserts on creation.
- Sketch expects you to attach your command function to the `window` instance, XD expects them to be exported in `module.exports`, and Figma expects you to invoke your function based on the value of `figma.command`.

It doesn’t take long before you get a sense of how different each platform can be. Just take a look at what’s necessary to create a simple Rectangle layer:

{% gist https://gist.github.com/jodyheavener/4cadd4d2cd7b1993e6dff18e462f6780 %}

### So what does this thing actually do?

#### [`dtpm new`](https://github.com/jodyheavener/dtpm#new-name-options)

For starters, it removes the hassle of getting set up for each platform. The `new` command will generate a set of template files that you can use to start building plugins with.

#### [`dtpm build`](https://github.com/jodyheavener/dtpm#build-options)

The `build` command (optionally with the `-w`atch flag) builds your plugin files into their respective plugin formats. Where possible the utility will also load them into the platform.

#### [The API](https://github.com/jodyheavener/dtpm#the-api)

This is the core of DTPM. It allows you to import various plugin, platform, and document related properties and methods, and will take care of executing them as each platform expects.

Let’s take a look at that Rectangle example again, but this time using DTPM to build for Sketch, Figma, and XD:

{% gist https://gist.github.com/jodyheavener/bfbb3b957a24603f152e3aeade8b90a2 %}

I’ll be the first to admit that right now this API is extremely slim. But hey, it’s a proof of concept. Don’t email me.

#### The small things

Lastly, DTPM is going to take care of generating a manifest for each plugin, with the properties that each platform expects, as well as generate your plugin icon into the required sizes.

You don’t have to give up full control to DTPM for manifests, though. For each platform you can specify override keys.

Here’s an example manifest:

{% gist https://gist.github.com/jodyheavener/00b198b1591e4b8c9d661690cce8ec86 %}

---

### Roadmap: plugin UI

One of the biggest inconsistencies across the three platforms, and therefor one of the biggest hurdles that this utility will need to overcome, is the ability to display plugin UI. It’s something I’m hoping to accomplish soon.

Why is it so challenging? You’ll need to dig into the code to really understand it, but the gist is that:

- Figma supports a single HTML file that has to be listed in your manifest and invoked in your plugin environment code. It cannot talk directly to the document API environment, and instead relies on post-messages to transfer information back and forth between document and UI.
- XD only supports using JavaScript to interact with an augmented DOM in order to create dialogue boxes. No external HTML files allowed. However, this also means that the document API environment and the UI API environment are one and the same.
- Sketch does not provide any native HTML UI support, but the third-party [sketch-module-web-view](https://github.com/skpm/sketch-module-web-view) provides an Electron-style interface that allows you to effectively invoke a browser window. As such, and similar to Figma, this means you need to communicate back and forth via post-message setup.

---

## Final thoughts

Thank you for coming to my TED talk. I’m not even sure if multi-platform-plugin-development-inconsistency is a problem that many developers face, but I certainly do, and this has been a fun experiment.

If you like DTPM, have any thoughts or suggestions about how to improve it, or just want to chat more about the wild world of design tool plugins, drop me a note.