It's time to port your extension to Firefox

February 12th, 2021 · 5 minute read

I’ve seen quite a few people complaining lately about the Kafkaesque Chrome extension review process, so when I started running into my own problems with the Chrome Web Store I wasn’t exactly surprised.

It wasn’t until I submitted the same extension to the Firefox Add-Ons Store that I saw just how good things could be. In a world of walled gardens watched over by heavy handed reviewers, Firefox’s review process was laughably good.


In January 2020 my buddy and I started working on an idea we had for an automation app. We called it Otto.

Otto consisted of two parts: a Mac app and a browser extension. After a few months worth of nights and weekends we had an alpha version we were ready to share with friends. I submitted the browser extension to Chrome under my own personal account, and after a review process of a couple days it was accepted. So far so good.

Chrome gives us hell

The trouble started a few months later. After some more development and discussion, we re-framed our idea as an app to make custom keyboard shortcuts and we decided to rename Otto to Keysmith. We also took the time at this point to create a company Google account. We renamed the extension and submitted it from our new company account.

To be clear: changing the name was the only change we made.

A few days later we received a rejection email. Here’s a timeline of our interaction:

  • 6/18 We submit Keysmith to the Chrome Web Store.

  • 6/19 @ 3:49am First rejection email. Quick summary:

    • Keysmith “violates the ‘Use of Permissions’ section”
    • We should “Request access to the narrowest permissions necessary"
    • "If more than one permission could be used to implement a feature, you must request those with the least access to data or functionality.”
    • We shouldn’t attempt to “future proof”
  • 6/19 @ 9:42am We double check the permissions we’ve requested and can’t find any problems. We respond asking for more detail.

    We also mention that we had previously submitted the same extension with the same requested permissions, just under a different name (Otto). We hoped they’d say “oh, in that case we’ll approve this right away!“. But instead:

  • 6/20 @ 3:11am Otto, our existing extension, is removed from the store and no additional detail on the rejection is provided. In fact, this email contains the same exact text as the previous one.

  • 6/20 @ 10:47am We respond, again asking for more detail. We ask if it would help if we expanded on how we’re using each permission in the permissions justification section.

  • 6/20 @ 9:27pm They respond with the exact same text again. No further detail. No help at all.

  • 6/22 @ 9:38am We suspect these reviews are entirely automated, so we ask if we can speak to a “human reviewer”, hoping this will trigger a manual review (we also consider dropping an f-bomb for the same reason, but decide to remain decent for now).

  • 6/23 @ 1:28am They respond with some slightly different text, but still nothing useful.

  • 6/23 We try adding a lot more detail to the “justification” section for each of the permissions we use and we resubmit.

  • 6/23 @ 9:57pm They respond with the exact same text as the first rejection.

  • 6/24 @ 9:35am We respond with one more plea for more more information.

  • 6/24 @ 11:23pm They respond with the same text again.

Our mistake

At this point I dig into Chrome’s documentation once again with a fine-tooth comb and I make a discovery: we had been requesting both the tabs and activeTab permissions, but since we also requested permission to run on <all_urls> it turns out that the features made available by activeTab were a strict subset of the features made available by tabs. So the activeTab permission was redundant. We weren’t opening up any new functionality, we were just asking for a redundant permission.

This discovery made the Chrome review team’s communications far more frustrating in retrospect. The line that all of their emails repeated was “Request access to the narrowest permissions necessary”. And, sure, we had asked for activeTab when we didn’t need it, but that permission didn’t grant us any more functionality. They had rejected our extension 6 times with no detail because of a technicality.

We committed the 1 line diff removing the activeTab permission and resubmitted. A day later it was accepted.

Firefox gives us a glass of ice water

A Firefox version of our browser extension had long been on our list, but for the first little while it didn’t feel worth the additional support cost. We didn’t know exactly how large that cost would be, but we suspected that there would be enough differences between the two browsers that it’d be a bit of a hassle to maintain them both.

Boy were we wrong. When we finally started looking into porting our extension to Firefox we found that we had to make zero changes to the code. None whatsoever. Firefox even supported the use of the global chrome object for accessing extension APIs (if you’re curious, Chrome is not kind enough to return the favor).

So we created a Firefox developer account, submitted our extension, and girded ourselves for another rough ride.

Boy were we wrong.

  • 9/24 @ 10:45am We submit the first version of our extension to Firefox.

  • 9/24 @ 1:05pm Less than 3 hours later we receive an email from Firefox that says, in effect, “Sorry this is taking so long, but we’ll get to it soon!”

    Responses from the Chrome team usually came in the wee hours of the morning, making the effective turnaround about 24 hours. Firefox apologizing after fewer than 3 hours was hilarious to us.

  • 9/25 @ 10:45am We get an email saying the extension was accepted exactly 24 hours after submission.

Further updates have been even speedier, usually only taking 2 or 3 minutes to be scanned and accepted. One of our updates even got accepted before I finished uploading the unminified source archive (which they require if you minify in production). And the dashboard shows your position in the review queue to give you some idea of when it’ll complete.

Needless to say, this was a breath of fresh air, and we won’t be neglecting support for Firefox ever again in the future.


I realize that in some ways this is an unfair comparison. Chrome’s market share is much larger than Firefox’s these days, so surely they also have to deal with far more extension submissions.

But the lack of transparency in their process was infuriating and counter-productive. Had someone taken the time to manually review our case, or at least read any of the emails we sent, we could’ve resolved this issue with one response. Instead it took 6 responses and a week of wondering if this review process would kill our product before it even launched.

I really hope things improve, but I’m not counting on it.

A picture of me
Daniel de Haas is the creator of The Godspeed logo Godspeed, a fast, 100% keyboard oriented task manager - like Superhuman for your to-do list. He lives in Walnut Creek, CA with his fiancée and his dog.