Extensions providing APIs to other Extensions

I think extensions working together by providing APIs to each other is a really cool thing. APIs can either be a runtime.onMessageExternal (or onConnectExternal) protocol or a global injected into a website that other extensions and user scripts can interact with to augment functionality.

I’ve started a list with documented APIs (I know of a few more, but no documentation for them, at least yet): https://github.com/freaktechnik/awesome-extension-apis

Feel free to submit pull requests there of other APIs, or just post them here to share with other extension developers!

3 Likes

This is a really nice initiative. I was thinking at some time to create an addon that backs up and restores data from other extensions trough the API. I did not have time to work on it, but it would be really cool.

1 Like

I love this idea too !

However, an add-on A exporting an API to add-on B that could be implemented directly in B has a limited range (not saying it cannot be useful).

What i would like to see is a clean extension dealing with a clean native app and exporting to other extensions APIs that are missing from WebExtensions. File and Socket APIs come to mind.

Obviously, security is an issue there if any add-on is able to connect to the API-providing extension, and for instance get access to the file system. In the meantime, those APIs used to be available in the former add-on SDK (RIP) not causing any particular threat AFAIK, thanks to the Mozilla reviewing process filtering out intentionally evil extensions.

Obviously, security is an issue there if any add-on is able to connect to the API-providing extension, and for instance get access to the file system.

In theory such an extension can implement its own permissions/privilege management system. In Notification Sound users can either block specific extensions or only explicitly allow certain extensions.

However, an add-on A exporting an API to add-on B that could be implemented directly in B has a limited range (not saying it cannot be useful).

As I tried to outline in my blog post accompanying the list, there are cases where you’d rather centralize configuration etc. to a single point. Or where an extension already provides something and just also exposes that other extensions.

Legacy version of FoxyProxy supported a very rich API. It is documented here. It was exposed to both websites and other addons. I’d love to re-implement in WebExtensions, but I think exposing to websites is more important as a first priority. Do your 2 existing github examples do this? Is it as simple as injecting content into every website (not enabled by default; the user would have to enable in the addon first, in order to prevent abuse)

They do not do this. They only provide APIs to other extensions. The approach I’ve seen the most to provide an API to websites is to inject some global as API.

The onMessageExternal API has an option to also work with websites, however that is not implemented in Firefox. See also https://bugzilla.mozilla.org/show_bug.cgi?id=1319168

I am a bit confused:
In the end that means some extensions wont work if one doesn’t install ‘your’ extension. But if so ‘your’ extension is simply another library that always has to be shipped together with Firefox. Maybe it would be easier to integrate all APIs directly into Firefox.
Jm2c.

I have implemented that kind of service (allowing a web page to request some function from the addon) on the downloadhelper.net site. It was really straight forward.

Basically, the web page and the injected script communicate through the standard window.postMessage() function, and the injected script and add-on background communicate via the stantard browser.runtime connect/postMessage WebExtensions API.

Of course, for security reasons, you have to make sure you just don’t proxy blindly the web page requests to the add-on, even if you control on which sites you inject your content script.

I can share some code if anyone is interested.

Maybe it would be easier to integrate all APIs directly into Firefox.

Technically you are right, but i think it’s a problem of responsibility. If you implement a new API in a native application (controlled by an add-on that exports the service to other extensions), whatever security hazard this introduces (that the user accepts or not by choosing to install the native app) is no longer Mozilla fault.

This is the reason why using native applications are allowed by Firefox add-ons rules, as long as the application is installed explicitly by the user.

Either you extend a “bigger” extension via their API, or the extension you are using is an optional enhancement of functionality (like the two extensions currently listed in the GitHub repo). But yes, it adds a barrier compared to doing things yourself or it being a browser API. Though extensions can also do things that Firefox would never consider having as an API or are very use-case dependent.

I’ve put quite some work into something similar.
The aim is to make native APIs easily accessible for extensions, my approach has all extensions start their own native app, though.
The native program then locates the current extension on the disk and makes the files inside available to be requireed as node.js modules. That way it makes sure to only execute code that the developer intended, and doesn’t just eval something send to it. And the extension developers don’t have to worry about the native messaging protocol or most aspects of RPC at all.
A good portion of the project is already pretty well documented, others parts I didn’t have the time for yet. I am open to questions and suggestions.


More to the topic of this thread:

I am also working on a major update to my Wikipedia Peek extension. It currently only shows previews of Wikipedia articles on Wikipedia, I want to make it display previews for all kinds of links everywhere.
For the latter, I implemented an cross extension mechanism to allow other extensions to become providers of the previews. It works, but the entire thing is still very much beta, though.
I hope I remember to update this here once it is done!

1 Like