Browser Extensions should Work Together

Most browser extensions do a thing. And they do that thing in their isolated little world. Many of them do their thing pretty well. Many of them are built to do many things. Many of them are built to do just one little thing. But only few of them talk to other extensions to do things.

And I’d like to see more extensions talk to each other to do things.

A Couple of Examples

Running a Task

One of my extensions lets you know when creators are streaming. Some people like using external tools to watch those streams (for many reasons). While I do not want to support a native application that interacts with Firefox to launch the tool, I have instead found an extension that already provides integration with the tool and Firefox and asked nicely to add an API for other extensions to be able to launch the tool. And now I can offer an option to open streams with the tool when that extension is installed. Since this is a feature only few users would be using it is a much more efficient approach for me and it makes it simpler for users of that other extension, since they don’t have to install two native applications to interact with the tool.

There are many other things that other extensions may already be doing and you don’t necessarily want to repeat in your own extension. I can think of interacting with some APIs to share content on a service or applying certain modifications to a page as generic examples.

An API for a Custom Feature

Another one of my extensions plays a sound when a notification is shown. That sound can be customized. It’s something Firefox doesn’t do out of the box. If other extensions also want to have that sound played when they show notifications, and thus make it way simpler for users to get a unified notification experience from Firefox, they can just tell that extension that they are showing a notification.

I initially opted to build a separate extension to play a sound for new notifications because I did not want to add my own solution in every notifier extension I maintain. And because some operating systems already play a sound, so why should I always just have that feature built into my extension, when it’s easily modularizable and users can opt into it by installing an extension.

There are many other extensions, especially in the tab management category that do very custom stuff with how they handle native Firefox features. Giving other extensions a way to directly interact with those additional features opens new and exciting opportunities.

Adding more Functionality

The popular Twitch modification extension FrankerFaceZ has an add-on pack for more emotes and additional customizations. The add-on pack fully integrates into the UI of the base extension.

Other classic examples for this include Firebug extensions (which are now just normal developer tools extensions) and extensions adding features to ad blockers.

How can Extensions Integrate with Each Other?

There is a well hidden feature in the very basic messaging API for WebExtensions: you can send a message to another extension. And of course that extension can then reply to your message, or send you more messages, since it gets your extension’s ID as part of the sender info.

The API in question is the sendMessage API in the runtime namespace. You just specify the ID of the extension to send your message to as the first parameter. Extensions can also open ports between them to exchange more than just single messages in a context. To listen for incoming messages from other extensions a separate event listener onMessageExternal is required. The same goes for incoming port connections with onConnectExternal.

When listening you do not only get the message from the other extension, but also which extension is interacting with you. This allows you to allow extension-based filtering to reduce the threat of abuse or for users to further customize their experience.

The actual messaging protocol has to be defined by the individual extensions. The protocols I’ve used so far are both documented in the README of the extension.

Some extensions expose an API in the page they modify with a global object. This lets users customize extension behavior via user scripts or other extensions. I don’t have an example of any extension that does this and has a documented API.

I’ve created awesome-extension-apis as a curated resource for extensions that have a messaging API for other extensions to use. Please add your extensions with messaging APIs to that list!

Why Should they Integrate with Each Other?

Primarily to reduce configuration repetition for users. At least that’s what I think integrations are primarily useful for. Instead of every extension providing its own solution for a problem they can reduce it to a single point of configuration for the user by all requiring the same extension.

This is not really fitting for core features, since users have to install a second extension. But to expand the abilities of your extension I think it is fine to ask users to install a different extension. Especially for less extension related things like a notification sound. It may be a harder sell for integrations with services, like Streamlink, however I feel the problem is similar to requiring a native application. It may even be a little less severe, as installing an extension requires a lower trust level from the user and is easier.