Daniel Immke

Manifest V3’s foibles

Beyond the wailing and gnashing of teeth

You have probably heard rumblings about Chrome’s Manifest V3. If you haven’t, here’s what you need to know: Google has been developing a new API for Chrome extensions for a while now. This API is more restrictive than its previous incarnation, Manifest V2.

Google claims this increases security and will lead to less incidents of malicious Chrome extensions. Detractors have argued this will prevent ad-blockers from functioning properly. This is further complicated by the fact that Firefox switched to using Google’s system for extensions in the mid-2010s now as well, and other browsers like Edge use Chrome under the hood, so the effects of this change reach further than Chrome.

I haven’t paid a lot of attention to this besides skimming a few of the articles on it. There’s been a lot of back and forth about it. I basically just assumed that ad blocking is so crticial that a way would be found to preserve the status quo and I’d switch if and when I had to.

The current situation is that since early 2022, you cannot submit new Manifest V2 extensions to the Chrome Web Store. Existing extensions on the store that use Manifest V2 (including ad-blockers) are slated to be completely removed at some point early in 2024.


A screenshot of the small visual change the extension does to Gmail A screenshot of the small visual change the extension does to Gmail

Today I wrote a very small Chrome extension for my own personal use. I used Manifest V3 and after seeing so much drama surrounding it, decided to write about it. I have created a couple of simple Chrome extensions in the past using Manifest V2. I went in with some familiarity, but not a lot.

First off, Google has a point

Google has a valid reason for rethinking extensions. Chrome extensions have long been a vector for spyware and malware. Sometimes a bad actor will buy a popular extension with a large install base so they can add things like data collection to it. It’s a real problem — not an invented excuse to ban ad blockers. Every time I have looked at my Dad’s computer to help him with something, I have found several sketchy Chrome extensions installed that he has no memory of installing.

Companies can make decisions that are potentially positive for their bottom line while also having legitimate technical reasons for doing so. Too many of the takes I have seen about this situation are completely one-sided and dismiss the technical justifications out of hand.

<aside> — The next few paragraphs digress, but are helpful in making my point.

The current brouhaha about Apple potentially introducing “Apple Certified” USB-C cables falls into the same category to me. There is an easy, cynical take to have: “they want to be able to keep charging insane markup for their cables.” Of course, when they do make the change they will have to contend with a less informed, likely much larger group that has their own gripe: “You couldn’t think of any new features to put in your phone so you changed the port to make me go buy a bunch of new cables!”

That linked article even goes so far as to accuse Apple of “missing the point” of USB-C.

It’s amazing and absurd — because Apple actually helped create USB-C. They were part of a small number of companies that helped create the standard in the mid 2010s and received a ton of flack for releasing laptops that only had USB-C ports in 2016. They switched their proprietary connector, Thunderbolt to be a superset of USB-C. Versions 3 and 4 of Thunderbolt have been interoperable with regular USB-C ports. They’ve also switched to USB-C on some of their like the high end iPad Pros, where Lightning cannot handle data transfer needs.

In addition to this, while Apple does sell OEM cords, they have a certification program called MFi and grant other companies a license to make cords that are higher quality and cheaper. Here’s a well reviewed cord that was the second result from a quick Amazon search. I don’t feel like $13 is a price gouging amount of money to pay for a well reviewed, braided cord that can handle fast charging. If they’re not doing this with their current cords and accessories, why would they start doing it with a switch to USB-C?

The long rumored real reason that Apple did not switch to USB-C for iPhones (if they were going to do it of their own volition it would have happened 2-3 years ago) is because they lose the ability to control who can make accessories for iOS devices. Apple profits from that, but it’s really about quality control.

Remember, the Lightning port is the sole port for iPhones. It’s not just used for charging cables, and Apple has full control over which companies can make cables or accessories like battery packs that utilize that port. With USB-C, they lose all of that control. It is much easier for a manufacturer to acquire a license to produce something with USB-C than to go through Apple’s MFi program. With that constraint released, you will have shady manufacturers building things like battery packs and competing solely on price. Consumers will be buying products that can cause damage to their iPhones. Over time, the perception of the iPhone’s reliability will go down as these experiences accumulate, making it less differentiated from Android. When you view it through that lens, it makes sense that they would want to guide their biggest revenue product category towards going fully wireless (I say this as someone who has personally wanted a USB-C iPhone for years.)

It would be wrong for Apple to block third party USB-C cables that are not MFi certified (I also think it would be insane — it would immediately prompt an additional round of punitive regulation from the EU.) If it does happen, then Apple will deserve the criticism they get, but if this is a continuation of MFi just for USB-C instead of Lightning for cables and accessories, it’s the same thing they have been doing for years. But I have seen many people saying that this is definitely going to happen, even though when you review the facts it seems unlikely.

</aside> — Whew! Hopefully that wasn’t too long.

To me, Manifest V3 falls into a very similar category. This is more than just “Google wants to kill ad blockers!” Just like with the above scenario there’s a lazy cynical view and a more nuanced take that requires evaluating the facts and applying some critical thinking. So let’s look at the facts.

Chromium, Blink, and V8 are all open source. Webkit is open source. Gecko is open source. There isn’t a moat for creating a web browser when the key, foundational technologies to do so are all open source and free to use. Also, users love ad blocking. If ad blocking became impossible in Chrome, I would switch the same day to an alternative. If not same day, same week or month. And there would be an alternative. Mozilla already claims that their implementation of the Chrome extension system and Manifest V3 would permit ad blockers.

Additionally, ad blocking has been around longer than Chrome has. If it was something Google wanted to tackle, they likely would have far before now.

On top of all of that, Google is already tied up in antitrust litigation regarding online advertising. This would be more grist for that mill.

Maybe Chrome’s marketshare dropping by 40% but the people still using it aren’t blocking ads is the desired outcome. But I really doubt it. To Google, Chrome is a form of soft power. It’s a big stick they and everybody else knows they have and it brings other entities into alignment with them. Brazenly crippling it to juke ad revenue? That’s a 90’s era power move. Google knows more than anybody how fast browsers can rise and fall. Chrome hit the ground running in 2008 and never looked back. But there’s nothing preventing that from changing. A large (+30%) marketshare transition could happen much faster today than marketshare shifts during the 2000s and 2010s, perhaps on the order of months instead of years. Chrome is worth far more to them in indirect ways.

The final thing I will say is that no matter what Google does or does not do, none of this is an existential threat to ad blocking on the web. Now on to my experience with Manifest V3!

Building with Manifest V3

The repository, in case you missed it above.

It’s extremely simple in scope. It waits for a user to open Gmail and injects a script directly into the page that does some cosmetic DOM manipulation and style changes.

I encountered some issues both in building the extension and submitting it that I will go over in more detail. It’s also completely possible there’s a much simpler way to achieve this that I wasn’t able to figure out from the documentation, in which case I will happily update this post.

You have to set up middleware to get verbose logging.

Manifest V3 requires you to register service workers, but it does not automatically start or persist them. I registered mine in the background and it triggers by navigating to a Gmail URL. However, without using a try...catch in some passthrough code if your actual code has errors it will just fail and you won’t get any usable logs. I’m sure there are workarounds I didn’t think of, but I also didn’t see a common pattern in place that prevented this either.

You can view this in manifest.json and service-worker.js it simply tries to invoke my actual code, located in background.js.

I like that they’re focusing on using WebAPIs, but I found this confusing and the documentation didn’t help a lot in clearing it up. Maybe I am supposed to trigger it differently.

Injecting scripts and styles is much more restricted

My requirement was injecting my own function into a Gmail page after it had loaded, and this worked really well. It injects the script directly into the page itself, so you have access to Document, Window and all the other things you need. This was perfect for me, because it allowed me to move the debugging process directly to a tab with Gmail open instead of having to open the debug window for the extension.

However, Google Chrome has its own lifecycle events during navigation that you can hook into - and what I found was that when I was just injecting the script after onComplete or onDOMContentLoaded there was a second where the original content displayed before it was changed by my script.

I worked around this by just injecting visibility: hidden; on the document body at the onCommitted event and unsetting that on onDOMContentLoaded so the page is blank until it’s fully loaded instead of progressive. I can see this being an issue for content blockers (don’t want to load the content then hide it, but prevent it from loading to begin with) would have trouble with. However, it appears that there is a separate API for handling network requests that would be preferable to use anyways. I haven’t done a deep dive here, as I wasn’t building a content blocker, so maybe that API isn’t powerful enough to be used. I can’t speak to it.

3. The submission process doesn’t let you use WebP 😡

A screenshot of a form field to submit an image Google, what the fuck?

To submit to the Chrome Web Store, you have to submit example screenshots and a logo. Neither of which accept webp, which is a web image file format created by Google! Off the heels of my last post on how great it is, this was disappointing.

4. The submission process is more stringent

I was asked to justify every permission I asked for, as well as provide a description of exactly what the extension does.

I liked that - I don’t know how enforceable it is, but it felt more like Apple’s App review process. Less powerful APIs and a more stringent review process seem like a no-brainer to improving security around extensions.

At the time of this writing, the extension is still in review. I don’t care that much on a personal level if it is accepted or not. I wrote it for myself, and I’m already running the extension on my machine unpacked. But I will update this post with the result either way, just as a data point.

Update: Feb 7, 2024

The extension was approved and is available on the Chrome Web Store.

Conclusion

Aside from some annoyances and lack of example code to look at, I didn’t find the actual development experience to be that bad. That’s why I titled this post the way I did — it was basically just foibles. What I saw of the larger API seemed reasonable to me. I got the impression that Manifest V3 really was designed with the primary goal of increasing the security and performance of extensions. Admittedly, my extension was simple but I feel like I gained enough insight to write about it without going into intense technical detail.

Nobody can say what the future will hold, but I think Manifest V3 is an improvement and I hope this shakes out in a way where we can enjoy these improved protections and security without ruining ad blocking.

I have a pretty good feeling it will. The web is bigger than everybody, even Google.

Hey — My name is Daniel Immke. I’m a designer & developer currently building Pickwick.

If you liked my writing, check out more posts or subscribe.