Adam Innes · Blog

Blink Forks WebKit: What Changes for Web Developers

· 7 min · web development, browsers, chrome, css

Last Wednesday, April 3, the Chromium team announced that Chrome is leaving WebKit. Not for something written from scratch, though. Blink is a new open source rendering engine based on WebKit, which is a polite way of saying fork. Opera, which only announced in February that it was giving up its own engine for WebKit, is going along with Chromium. So in the space of two months, the browsers that shared WebKit have split across two related but separate engines.

If you build websites, your first question is probably whether anything breaks. The short answer from Google is no, not right away. The more interesting answers are in what they’ve said about prefixes and about how new features will get switched on, because those change how you should be writing and testing code.

Why they forked

The announcement, written by Adam Barth, gives one main reason. Chromium uses a different multi-process architecture than other WebKit-based browsers, and supporting multiple architectures over the years made both the WebKit and Chromium projects more complicated and slowed everyone down.

Chromium’s multi-process architecture design doc describes a browser process that runs the UI and separate renderer processes that handle web content. Each renderer runs the rendering engine inside a sandbox, and talks to the browser process over IPC. Other WebKit-based browsers are built differently, and one shared codebase had to serve all of those architectures at once.

The Blink project page on chromium.org spells out what the team wants to do now that it doesn’t have to worry about that. When Chromium started, the goal was to change as little of WebKit as possible. Now they want to make large changes without breaking other WebKit consumers. Examples they list include out-of-process iframes, refreshing networking code that they say is held back by old Mac WebKit API obligations, and maybe moving the DOM into JavaScript, which they note would be hard in WebKit because WebKit supports two JavaScript engines. The Blink Developer FAQ adds a second reason: room to experiment with performance, with the stated ambition of doing for networking, rendering and layout what V8 did for JavaScript.

There’s also a cleanup angle. The announcement says the team expects to remove 7 build systems and delete more than 7,000 files, over 4.5 million lines, pretty much immediately.

Little changes, for now

The blog post says plainly that in the short term Blink will bring little change for web developers, with the early work focused on internal architecture and simplifying the codebase. Nothing you shipped last week should stop working because of a repository split.

Over time, two engines that share a history will drift. Some of that drift is intentional (the architectural changes above), and some of it will be features landing in one engine and not the other. Neither the announcement nor the FAQ text puts a date on when Blink reaches Chrome’s stable channel, so plan for the drift to show up gradually rather than on a particular release.

Goodbye to new prefixes

This is the part I’m happiest about. The project page says that instead of turning experimental features on by default under a vendor prefix like -webkit-, Blink will keep the unprefixed feature behind the “enable experimental web platform features” flag in about:flags until it’s ready to be on by default. The page points out that prefixes hurt compatibility because content ends up depending on the prefixed names, which anyone who has maintained a stylesheet with four copies of every gradient already knows.

The FAQ answers the question a lot of people asked on day one, which is whether there will be a -chrome- prefix. There won’t. Blink won’t use vendor prefixes for new features at all, and the single about:flags setting is how you’ll get to try what’s coming. Existing prefixed features keep the -webkit- prefix, because renaming them would just cause pain. The team says it’s looking at real world usage data to work out how to deprecate prefixed properties responsibly, and that non-standard leftovers such as -webkit-box-reflect will be standardized or deprecated case by case.

Google isn’t alone here. The project page notes that Mozilla has been heading the same way, and the CSS Working Group reached a rough consensus last August on an experimental features policy that keeps experimental features out of release builds and ships unprefixed once the criteria are met. The blink-dev list shows engineers already working on the plumbing: on April 5 Ojan Vafai wrote that all new web platform features will sit behind that single runtime flag, in a thread about removing the compile time #ifdef feature switches Blink inherited from WebKit.

Intent to implement, intent to ship

The other big change is process. The Blink project page lays out a launch process for anything that affects web developers. You add the feature to the Chromium Feature Dashboard and file a launch tracking bug. Then you email blink-dev announcing that you intend to start implementing it, with your estimate of the compatibility risk, how invasive the change is, and links to specs, standards discussions and other browsers’ support. If anyone asks for an API review, you go to one, and you have to live with the decision. You build the feature unprefixed behind a runtime flag. When it’s time to turn it on, you send a second announcement to blink-dev, and a shipping API review follows if anyone asks for it (the page says that when in doubt, one is required). Then it ships.

How much scrutiny a feature gets depends on compatibility risk. The page lists rough tiers, from the safest case where two other engines already ship roughly interoperable implementations, down through one other engine shipping it, a standards body considering it ready (a W3C Candidate Recommendation, say), and a spec accepted by a working group with positive feedback from other engines. API review meetings are weekly and need at least three project OWNERS present.

You can already watch it happen in public. On April 5, Kenji Baheux posted an implementation intent for the IME API, aiming for a behind-the-flag implementation, and within hours it had a slot in the following week’s API review. The same day, Peter Beverloo posted a change removing the compile time guards on the CSS Conditional Rules module, meaning @supports and CSS.supports(), noting the spec is a Candidate Recommendation and Mozilla already ships it. Rather than just switching it on, Eric Seidel and Elliott Sprehn asked for a proper API review, and it went on the agenda. The names aren’t settled yet (the page calls these steps an Implementation Announcement and a Shipping Announcement, and early posts use phrasing like “implementation intent”), but the shape is clear, and blink-dev is where you’ll see what’s coming well before it lands.

Who runs what

Here’s where the major engines stand as of today. WebKit remains the engine behind Safari. Chrome’s stable releases are still WebKit builds, with Blink as the future. Firefox uses Gecko, which the Blink FAQ holds up as the model: an engine that isn’t WebKit but stays highly compatible with it. Opera said in its February 13 press release that it would gradually move to WebKit and Chromium for most of its upcoming browsers rather than keep developing its own engine, and the Blink FAQ now says Opera will be adopting Blink. The FAQ also points out that Opera is already shipping a beta of its Chromium-based mobile browser.

Test features, not engines

Here’s the practical upshot. If your code has a branch that checks for “WebKit” in the user agent and assumes a feature set, that branch was already shaky, and it’s going to get worse. The FAQ makes the point that WebKit was never one target: WebGL and IndexedDB only work in some WebKit-based browsers, and video, fonts and 3D transforms vary between them. And Chrome’s user agent string is modeled on Safari’s, with AppleWebKit and Safari tokens in it next to Chrome’s own, so matching on those tokens was never a reliable way to learn what a particular browser can do.

My advice is to ask the browser whether it supports the thing you need. For DOM APIs that means checking for the object. For CSS, check whether the camel-cased property exists on an element’s style, and try the unprefixed name first so your code picks it up as soon as a browser drops the prefix.

function styleProp(name, prefixed) {
  var style = document.createElement('div').style;
  if (style[name] !== undefined) return name;
  if (prefixed && style[prefixed] !== undefined) return prefixed;
  return null;
}

var transformProp = styleProp('transform', 'webkitTransform');
var hasIndexedDB = 'indexedDB' in window;

@supports will make the CSS side cleaner once it’s on by default in the browsers you care about, but as the blink-dev thread shows, Blink hasn’t made that call yet, so don’t lean on it alone.

The other half is testing. Keep Chrome, Safari and Opera on your list as separate browsers, including Opera while it makes its move to Chromium. If you’re curious what’s coming, turn on the experimental web platform features flag in a Canary or Dev build, and read blink-dev for new announcements. The project also says it wants to invest more in shared conformance tests, and when you hit a Blink bug or an interoperability problem, the project page asks you to file it.

Forks make people nervous, and some of that is fair, since more engines means more testing. But the policy Blink started with (no new prefixes, features behind flags, public intent announcements, review weighted by compatibility risk) is a better deal for web developers than prefix soup. If you write feature detection instead of engine detection, the fork mostly becomes something you read about on a mailing list.

← all posts