This post contains inline annotations/footnotes to help add context, helpful tips or expand upon a tangent in the text. Expand them by clicking or tapping on them Annotations might have their own annotations Such as this one! inside of them too.

I like making browser extensions. Big Surprise. Correction: I specifically like making browser extensions that aren’t hampered by Google’s unabashed attempts to kill ad blockers at any cost. Eg: MV3 seems like a real crap shoot so far, tbh

Browsers are pretty great pieces of software, am I right? They’re integral to our digital world these days, rendering everything from the endless cats and memes to our work and collaboration spaces. But they do a lot more: browsers have long had their own micro-ecosystems. They give users the ability to extend them with additional software that can change how the browser functions or imbue websites and apps with additional functionality and superpowers through browser extensions.

The Golden Age

I got into extension development back around 2017; I’m admittedly late to the party and missed out on the great XUL jazz. That said, I’ve built some pretty cool things over the years regardless and we appear to be approaching a nice golden age of technology for extensions to enhance webpages.

Why is that? Well, we have fairly good support for Web Components Ironically, Chrome is still lacking here even though Google is behind some of the first big pushes into Web Components: you have to use a Google maintained polyfill for Web Components inside of Chrome extensions. FFS and Shadow DOM which give nice and succinct ways to encapsulate components in a “good-enough” isolated environment. Aiding that, many frameworks are starting to integrate with these technologies to make building self-contained components much easier, such as Svelte and Lit. On the browser extension side, they have Content Scripts With the added ability of being able to register content scripts dynamically at runtime A feature that Firefox has had for a long time and Chrome reinvented for MV3 rather than play nice and work together to improve the existing solution. Because screw cooperation. , this gets even more powerful while potentially better respecting the users’ privacy by not needing the catch-all <all_urls> permissions. which run alongside the tab’s DOM, allowing for the Content Scripts to make changes to the webpage that are visible to the end user.

Couple these together and POOF you can inject UI onto a webpage without fear of style collisions. That’s awesome and powerful. Grammarly Putting the privacy concerns around their data collection and what not aside, they have a pretty well-functioning browser extension that is a great example of using extensions to enhance normal webpage experiences. uses this to inject their UI into text boxes, rending all the suggestions and the little tone icons and what not. Keepass-XC’s extension use this to add little indicators to login fields they’ve saved as well as several other UI elements.

While this is possible without Web Components and Shadow DOM, it gets messy with the older IFrame techniques floating around out there. Making matters worse, this technique isn’t well supported in frameworks leading to some weird looking code, and the risk of style collisions on your outer IFrame.

But for all this magic, could it be better?

Yeah, I think so. From my experience, there are two main styles of UI enhancements in browser extensions:

  • Those that inject elements into the page, changing the layout and flow of the document
  • Those that overlay elements onto the page but don’t change or interrupt the flow of the document

The former case is used by the likes of Refined-Github to inject near-native That is, components that look and often act like they’re a part of the original website rather than part of the extension components into the site that add functionality that’s missing from the original page, a use case which is already pretty well supported by the current Content Script abilities and not of interest to me today.

The latter interests me a lot, however, as it’s the realm that most of my extensions fall into and the use of Web Components and Shadow DOM feels … overkill for the features I often need. Something that comes to mind when thinking about this conundrum is an old overhead transparency put on top of a piece of paper.

Would having an API like documentOverlay or transparency make sense for Content Scripts? It could be a separate DOM, overlaid on top of the existing page with a transparent background that an extension’s Content Scripts could render directly into without fear of style collisions, no need for Shadow DOM and Web Components, or other hacks. That seems like it’d be a fantastic solution for the use case.