Infrequently Noted

Alex Russell on browsers, standards, and the process of progress.

The Absolute State of Management

It is by no means the gravest linguistic crime of the React epoch,1 but "state management" grates like nails on chalkboard. A Socratic dialogue I keep having about it goes something like this:

me: This UI is far too heavyweight for what it does, have you considered not using React?

them: But how will we do state management without React?

me: What do you mean? <alternatives> are reactive.

them: React manages state in our app.

me: It does? Then what are <various_libraries> for?

them: Oh, those manage state.

me:

The libraries that trigger this "Who's on First?" routine include:

Contrasts sharp enough to cut softened butter.2

Suffice it to say, the ecosystem has not picked a winner. Indeed, I regularly see several of these libraries on a single page. But even one would seem too many, given that we're adding a second "state management" system to a framework that spills considerable documentation ink chest-beating about its state management facilities.

One of the following must be true:

But in the to-and-fro of consulting engineering one can't just say as much, for fear of offence against frameworkist articles of faith.3

Thankfully, this is a blog post, so we can cut to the chase and admit that none of these tools manage state.

They might encapsulate state. They might even filter or transform state updates. But they do not, in any meaningful way, manage it.

Instead, they locally propagate notifications about state changes and, in some cases, post-process them or serve as caches.4 Conceptually, they are expressively equivalent to event buses and pub/sub systems, which are better understood as message passing backplanes.5

To understand the difference between state propagation and state management, we need to add the time dimension. React-centric "state management" libraries handle time the way C++ does for multithreaded code — which is to say, it's left as an exercise to the reader.6

Systems without a built-in conception of time and ordering can be subject to temporal effects. They can even synthesise compound state out of unordered, un-timestamped updates. But they occupy a world of hopes and dreams when it comes to asserting affirmative management of state because managing state means correctly applying changes over time and resolving conflicts.

A large fraction of the problems from overgrown React and Redux attempts at "state management" spring from the same wellstone: updates to the state propagation systems come from a variety of sources, with varying frequency and specificity. Pure propagation systems crumble under the incidental complexity that results from trying to sort out the consequences with only an event bus abstraction. It becomes unclear whose job it is to sort out which updates are "correct", and optimistic UI updates become a liability — or at least a bun fight.

At bottom, this is the same problem as managing data across multiple machines, and managing data over the network is the same as managing it across time that spans from the past, to the current moment, as well as the future.

This insight is important because it allows us to consider what's currently in memory vs. the same app rebooted at some future point without losing our minds. A future local instance of an app is conceptually the same as the app booting on an entirely different computer. Getting crisp on this is the key to throwing out jejune notions of "state management" and replacing them with tools that are fit for purpose.

Systems that manage state — rather than merely propagating or filtering it — have built-in concepts of time and order, and this allows them to handle both offline state and online real-time collaboration naturally. Instead of hoping that everything is happening in some window that we can squint at and call "now," true managers of state mutations have a way to reorder and resolve conflicts, and through that coherence, build a reliable and high-performance view of data changes over time.

You can distinguish them from state propagation tools by looking for variations of vector clocks in their internals. Time and order metadata attached to mutation enables global ordering, and we can't truly manage state without it.7

This conceptual break also provides an answer to our fish-or-fowl question: none of those libraries actually manage state; React included.8

Now that we can more accurately describe what these systems do (and don't do), the phrase "state management" mostly reads as confusion. But hold on to some grace; the folks deploying jumbled terminology come by it honestly.

Systems that really manage application state are not yet popular, and most teams are not familiar with the algorithms and systems that do it credibly. Discussions of CRDTs, Operational Transforms, Prolly Trees, and related approaches to consistency are still rare in the frontend discourse.

Thankfully the gap from upgrading our understanding of theory to deploying better patterns is small. Practical implementations are readily available; each have strengths and weaknesses depending on use-case, but all manage data in a time-aware way:

A beautiful, generative outcome of these systems is that because they think about time and conflicts, they're perfect for building systems that gracefully handle both edges of "now", enabling real-time collaboration seamlessly while simultaneously lighting up offline-first styles of development.9 Some (e.g., Y.js and Replicache) go far enough in this direction to enable true local-first development.

Regardless of which mechanism you adopt, these systems are a sea change. Data models stop being amalgamated hopium, and both offline use and realtime collaboration become possible as a side effect of getting the ordering of data mutation application correct.

This is the future we can have today. All we need to do is admit that "state management" isn't, then decide to do something about it.

FOOTNOTES

  1. By my count the worst linguistic misapprehensions spread by React's know-nothing culture are probably "server-side rendering," "pure function," and "concurrent." Each one camps out on a previously well-studied concept, re-defines it in a less-than-rigorous way, then flicks at the larger (more valuable) idea in order to justify a cheap knock-off.

    And that's to say nothing of the swindle being attempted through the renamings Reactors have given to the MVC bits of the React ecosystem. The very obvious MVC-with-global-variables patterns were marketed in an aloof, functional-programming-ripoff attempt to have something new to say when in fact they were just the old thing with more transpiler overhead.

    It's mank, and serious engineers are universally confused or pissed off by these cheap marketing theatrics.

  2. Given the hulking payload of Apollo, you'd be forgiven for wondering why it does not simply eat the other eight.

  3. Because it's generally unproductive (not to mention, kind of a dick move) to simply tell someone that their understanding of state management is entirely backward, the best I usually muster in conversation is heightening the contradictions by proximity.

    I wish that putting React's claims about state management next to those from other libraries triggered the same sorts of questions in others that it provokes in me, but the hit rate on this technique is dismal.

    Most developers only really seem to upgrade their understanding of what's possible when they look to add realtime collaboration to their systems, which is both understandable and somewhat frustrating, given the amount of effort that goes into pressing Apollo and Redux into service as ill-fitting sync engines.

  4. These systems might be caches, after a fashion, but they aren't databases, as they don't provide any method for querying data. Most also fail to address local persistence. The kludges I've seen to add storage to them further confirms they are not suited to any sort of scalable access role. It will always be a fool's errand to abuse a thin slice of a data layer snapshot as a generic access abstraction when the structure and metadata needed to do better than O(n^2) are absent.

    Major products have limped along in a self-degraded state, punishing heavy users thanks to approaches that wouldn't pass CS101 evaluations of their scalability. Huge apps have been caught trying (and often failing) to boot from JSON serializations of Redux.

    The fact that it ever worked — even on a developer's beefy machine — is testament to the ingenuity and dedication of hardware engineers, rather than any positive attribute of contemporary software pedagogy or frontend culture.

  5. A single-host instance of RabbitMQ would be just as expressive and generally perform better.

  6. Derogatory.

    For those not versed in both languages state of play, C++ is actually more capable regarding data access and updates over time in a stuctured way than JavaScript; it's just buried in C++11 Memory Model arcana.

    JavaScript, meanwhile, provides neither syntax nor standard library facilities for thinking about the time dimension of execution, despite continuing to slice aspects like program and class initialisation even more finely to accomodate reasonable defaults and their predictable overrides.

  7. The most common objection to the complexity of vector-clock-based update systems is that it isn't necessary in many cases to be able to distinguish now from then or when.

    This is (sometimes) true!

    Many UI components have internal state data that isn't complex enough to need accounting for mutations over time. Those components also don't want to integrate deeply into a single data management pattern, and prefer to handle changes through an out-of-time state machine, or a state chart without history. That's often fine.

    What's less fine is for us to pretend that once we escape the boundaries of these smaller components that we can muddle through with systems that attempt to extend the temporal void to conflicts that arise in application-wide contexts.

    These are fundamentally distinct concerns, and the React-ish belief that we can think of everything as an infinite regression of components without cross-cutting architecture is falsified by the practices of the React community itself.

    Said differently, Redux is a cry for help, and we have solutions that enable us to think more appropriately about how to quench the pain it introduces. But to get there, we have to step out of the void and into the stream of time.

  8. We can't in good conscience call these libraries "state management" tools, but I don't have a better name off the top of my head.

    Possible alternatives:

    • Event blenders
    • State strainers
    • Model muddlers
    • Mutation mixers
    • Modification marshes
    • Component complexifiers
    • Metamorphosis mystifiers
    • Confusion caches
    • Transform tarpits
    • Heap hodgepodges
    • Update imbroglios
    • Status SNAFUs

    If you have a better suggestion, drop a note on Mastodon or bsky.

  9. Honourable mentions for systems that try to deal with sync in a somewhat less structured way:

    • PouchDB: a classic of the genre, the library is continuing to get updates that remove cruft. Unfortunately, the conflict resolution strategy it adopts is too naive to recommend for new production work.
    • RxDB: unfortunately, RxDB leaves conflict handling as an exercise to the reader. Thankfully it does have a CRDT integration story, which is how I would recommend holding it.
    • Replicache: implements full state sync and good conflict control. It's also OSS'd, but somewhat unsupported by Rocicorp now. A good answer for folks who find Y.js too cumbersome but want full offline-first (or even local-first) development with an authoritative store in the cloud.

    Lastly, I would be remiss to omit that Google's Docs API is, in effect, an externalised entrypoint to the full live-editing OT system that powers Google Docs and Docs Offline. Unfortunately neither the server nor the client implementations of Google's modified-OT system are OSS or self-hostable, making it impossible to recommend.

Abject Praise

It's perilous to disagree with someone as wise and thoughtful as Jeremy, but for the past fortnight his post in response to Apple's iOS 27 marketing invades my quiet moments like a cricket in the attic.

"Why", I ruminate, "should someone who understands the state of play give Apple credit for doing less than the minimum while rubbishing those who have consistently done more?"

Like Apple's previous marketing of Safari 16.4 and Safari 26, the conjoined September release of Safari and iOS 27 documents an achingly slow release cycle. It would be one thing if the features or spec conformance were world-beating, but looking closely at the release notes, Safari 27 is set to deliver fixes for issues that, by and large, competing engines didn't suffer.1

Don't get me wrong: it's great that Apple is focusing on quality; it remains a persistent issue for Safari. But how much relief should long-suffering web developers expect?

The best comparative measures come from the communal Web Platform Tests project. Comparing the current experimental builds with stable channel releases can illuminate the scale of change we can expect when the next major version of each browser launches:2

90% is the minimum Apple requires across all WPT tests for competitors' engines in the EU and Japan where it has been forced to allow them (in theory). Safari barely clears the bar. Source: wpt.fyi

It would appear that Safari is closing on Firefox, but this is misleading. Apple managed seven releases over the past year, or a roughly eight week cadence. Mozilla and Chromium, meanwhile, have released 12 versions to stable, or one a month. These serve as denominators (7.4 weeks vs. 4.3) when calculating rates of improvement. Safari's larger increase in passing tests between nightly and stable versions (1558 vs. 990 for Firefox) looks large, and Apple wants us to think that's down to renewed focus. On a time-weighted basis, however, Safari continues to improve more slowly than Firefox, logging 207 improved tests per week since the last stable release versus Firefox's 230 and Chromium's 460.

But perhaps the most recent releases are outliers. Looking across a longer time period can help us level-set. WPT is flexible, allowing us to construct a query comparing developer channel releases of each engine in July 2025 to current builds:

Safari's WebKit remains least improved since this time last year. Source: wpt.fyi

Because new features are constantly added to browsers, the denominator continues to increase over time. It's helpful, then, to look at the change in tests passing as a fraction of all tests. This highlights the extent to which engines are progressing (or regressing) relative to the web's potential:

Apple might not care to implement some of the features Safari isn't passing tests for, but is that a reason they should be denied to all iOS users? And what does it say that others can improve relative to the overall test set, but WebKit has fallen further behind? Source: wpt.fyi

Total passage rates imply the role of engines as the blockers of widespread compatibility, but aren't a foolproof indicator. For example, if every engine failed the same way, it would be regrettable, but compatible. Web developers wouldn't have cause to throw shade at one browser more than others, so perhaps overall test failure rates obscure more than they clarify?

Helpfully, wpt.fyi also generates charts for tests that fail in just one engine; that is, cases where two browsers implement a feature correctly, and only one is out of conformance. But for bugs unique to that codebase, the web would be more capable and less costly to develop for. The higher the count, the more an engine holds back progress:

wpt.fyi single engine test failure counts over time
Lower is better. Over the past eight years, Safari's WebKit nightly builds have uniquely failed double the number of WPT tests as Firefox's Gecko on average. WebKit consistently racks up 3-4x as many single-engine failures as Chromium's Blink engine across the same time period. Source: wpt.fyi

At the time of writing, WebKit nightlies are alone in failing ~4,200 tests, Gecko is next at ~2,400, and Blink is the least incompatible with just under 800 unique failures. These relative rates have remained stable across many years, indicating higher sustained investment in Blink and Gecko versus WebKit.

wpt.fyi single engine test failure counts over time, including test262
Lower is better. With the recent addition of the Test262 test suite for JavaScript, WebKit's contribution to feature impairment becomes even more pronounced. Source: wpt.fyi

Including the test262 JavaScript conformance suite, we see a huge spike in WebKit-exclusive test failures. This is thanks to Blink and Gecko shipping the new Temporal API this spring. Temporal has been in development for nearly a decade; it hardly snuck up on Cupertino. Judging by the Safari 27 blog post, and confirmed by the state of the nightly test runs, it will not be included when new features ship in September.

Apple has repeatedly claimed to regulators that there's no need for real choice in iOS browsers because Safari is more than capable and the team is well funded. It's unclear how those claims can be squared with such an embarassing showing on a long-anticipted feature that Apple has no objection to.

One critique raised by this visualisation is that tests are not features. Some areas (like Temporal) include exhaustive test suites with many sub-tests, driving up their relative numbers. Other features may be foundational or internally complicated, but may have proportionally fewer WPT tests.

Thankfully, webstatus.dev has collated a feature-oriented view of the same data. Looking across the past decade, it shows that WebKit is the predominant reason features remain unavailable to users and developers, forcing both into the App Store where Apple demands a 30% cut:

webstatus.dev's chart of missing features over the past decade
Lower is better. As of June 30th, 2026 Safari is alone in blocking 59 features, Firefox keeps 43 from becoming widely available, and Chromium is blocking nine.3 Source: webstatus.dev

Blink has consistently maintained the lead on features and conformance over the past decade, but iOS users remain stuck with Apple's buggier, less capable engine, no matter which browser they choose.

Looking at large, heavily tested, uncontroversial regions of the platform shows that the gap isn't simply down to features that Apple thinks are problematic; even in areas where Cupertino is fully engaged, it consistently trails:

Test passage rates for the html/ folder as of July 3rd, 2026. Source: wpt.fyi

Remember that Mozilla makes something in the range of $500MM/yr from all revenue sources and spends the vast majority of that on browser development. Apple, meanwhile, rakes in more than $20BN per year from its web search deal with Google, or 40x as much.

With that much cash available, WebKit should be trouncing all comers; instead, it's barely middle of the pack when it isn't losing outright. Stable Firefox passes 84.9% of CSS tests, while Safari clears 86%, or a 1.1% difference:

Test passage rates for the css/ folder as of July 3rd, 2026. Source: wpt.fyi

Results from nightlies suggest that Safari 27 will widen Apple's lead versus Firefox to 1.6%, while trailing both Stable and Canary versions of Chromium (93.4% and 95.5%, respectively).

Improvement is improvement, but Apple's layout engine remains riddled with O(n^2) behaviours. Both Mozilla and the Chromium community funded multi-year rearchitecture projects improve rendering performace, but Apple has not made similar investments.

In other uncontroversial areas, such as networking, Apple's engine loses handily — both today and into the future. The fetch specification underpins browser networking, and WPT scores again highlight the consequences of subsistence-level funding for WebKit:

Test passage rates for the fetch/ folder as of July 3rd, 2026. Source: wpt.fyi

This continuing embarrassment is not a divergence from historical trends. But for Cupertino to feel any shame, or face any consequences, influential developers like Jeremy will need to look past marketing.

These large, persistent gaps matter to the mobile and web ecosystems because Apple is unique in denying access to more capable, less-buggy engines and actively erecting unlawful barriers to choice when forced by legislation to enable it. This is accomplished through eye-watering budgets for legal shenanigans, direct lobbying, and well-heeled astroturf front groups to maintain a capability gap between web and native.4

That chasm is instrumental in trapping users and developers in the extractive vice of Cupertino's App Store. A persistent, material gap in capabilities creates a perception of the web being less-than; a budget option for the unserious. Should users choose more capable, more private, less buggy browsers for a larger share of their computing needs, Apple might lose the leverage that enables it to extract rents.

Cupertino can put up with a lot of things, but it can't abide that. Which is why it spends lavishly to deflect and delay true browser choice, rather than investing those resources in the Safari team.

Having looked at the data, and having manually dug into dozens of the fixes listed for WebKit in the Networking and HTML sub-areas, I can say with some confidence that Jeremy's praise for Apple's comparative rate of bug fixing is simply off-base.

Cupertino might be talking up how much it cares, and we might all be desperate for green shoots given Apple's iOS hostage-taking, but our most fervent wishes and FruitCo's carefully presented narrative do not to change the reality that Apple is consistently out-engineered and out-invested by a non-profit with 1/40th the web-derived revenue. Against a near peer, the results of Cupertino's continuing under-investment are squalid.

What we see in these differences has a name: greed.

Apple is extracting tens of billions of dollars in private profit from browsers while socializing the costs to every digital business forced to work around Safari's buggy engine. Ecosystem-wide deadweight losses are even higher, impacting every user and business forced into the App Store by the incapability of Apple's browser. Not coincidentally, this is where Cupertino extracts a second vig. Higher prices for everyone else are not a bug to the monopolist's mind, but a confirmation of their own rightness and purity of charachter. Sure, that sounds like lunacy, but a lot of things go down more easily when you're absolutely rolling in it. Just ask anyone at Apple.

Like test conformance, security and performance are also indicators of quality that comes from consistent investment over time. News recently broke that a Blink for iOS prototype is showing massive performance upside relative to Safari on Apple's own hardware:

Speedometer, Jetstream and MotionMark test results for the Blink/iOS prototype versus stable-channel Safari. It's a bloodbath, and not in a good way for Apple.
The Blink for iOS prototype tested on Apple's own benchmarks, on Apple hardware. In the most representative test suite (Speedometer), Chromium leads by more than 25%.

That's to say nothing of the heavily requested features no developer can use on iOS thanks to Apple's sandbagged engine. Safari engineers have worked behind the scenes to keep important, oft-requested features out of Interop where a lack of progress might make Cupertino's choices more legible. As a result, we (Edge) maintain a parallel dashboard to track progress on important features cut from Interop through secret vetoes:

Firefox scores more than 3x stable-channel Safari's showing this year.
Firefox scores more than 3x stable-channel Safari's showing this year.

In more visual form, here's the Chromium iOS prototype versus Safari 26.5 running a test page that exercises just some of the features Apple is holding back:

If Apple allowed browser competition, all of these features would become instantly available to web developers willing to recommend better browsers to their users. Which is exactly what Cupertino fears.
If Apple allowed browser competition, all of these features would become instantly available to web developers willing to recommend better browsers to their users. Which is exactly what Cupertino fears.

Blink and Gecko-based iOS browsers would unlock more capable, more responsive, less buggy websites while simultaneously improving security. Progress would accelerate in a world with competition if only because it would spur Apple to finally fund WebKit at a competitive level. Under-investment is the absentee father of many starving children.

But today, Apple hasn't turned that corner. It's trotting out the same tired playbook:

Except for the ability to lock out other browsers, the script is identical to the one Microsoft tried in the bad old days of IE 7-11.

Which takes us back at square one: how is someone as clever as Jeremy falling for obvious propaganda?

One clue might be the Chromium-originated features he objects to. It's easy to be distracted by things you dislike and think "those people aren't paying attention to <good things>, they're just off on a tangent doing <bad things>". But that sort of feeling isn't data. I am not a fan of all recent Chromium features; in fact I'm the proximate reason the prompt() API hasn't launched more widely in the Chromium ecosystem.5

As a Blink API OWNER, my potential concerns about trailblazing efforts take on a specific cast: Chromium and Blink are explicitly organised to make and defend space for leadership, but our ability to lead in new areas is tied to quality. Final feature launch checks are focused on plausible interoperability — will the specs, tests, and implied architecture choices allow other engines to become compatible? — and demonstrations of developer support.

A few years ago I gave a talk for Blink developers outlining how the pieces fit when trying to solve problems for web developers:

TL;DR:, we don't trust ourselves to know all the answers. Instead, the API OWNERS look for quality signifiers, both from an implementation perspective, but also (and more importantly) from the perspective of end developers. When Blink is in the lead, our process is explicit about testing ourselves in an internally adversarial process to answer the question: "does this feature solve an important problem well?"

The key constituency for determining the answer are web developers, not other browser engineers or standards grandees. Working Groups gaining consensus after outbreaks of go fever have been the authors of much suffering, so we explicitly work to ground our analysis in sources of evidence less subject to groupthink.

Blink's process sets a high bar because we know the project is out in front, thanks in no small part to Apple's behobblement of both WebKit and Gecko. It's thanks to Blink's continuous work on conformance and compatibility that we can make path-breaking bets on feature investigations and spend the 3-5x it takes to get it right; particularly when other vendors do not join those (very public) efforts, or weigh in only to object to the colour of the bikeshed at the very last minute.

That's also why we've built mechanisms like Origin Trials to test features without risk of accidental burn-in. Developer feedback is the primary quality signal we evaluate above baseline reviews for security, performance, privacy, and accessibility. It also explains why Blink requires legible explainers, wide review, reasonable specifications, and good tests. We insist that web developers be able to understand and help shape proposals while they're malleable, and when the cement sets, tests and specs should be complete enough to ease the burden on other implementers.

The goal of this system is to pack as much learning as possible into feature development up front, listening to web developers, iterating as we go, and shipping at the speed of developer confidence.6

To a large degree, it has worked.

That's not a recipe for perfection, and nobody would claim we are infallible, but it is a recipe for leaving things a bit better than we found them. Listening intently to web developers and iterating in good faith is foundational to our process. But because we are so often in the lead, and so often iterating in public, work hangs in a liminal state longer than things might if we were able to count on other browser vendors engaging constructively. This invites critique, fair and misdirected alike. That's a price we're willing to pay to keep delivering the features developers tell us they need.

So if Jeremy has a problem with specific features, I hope he'll come to us with a critique of their qualities, rather than their optics. Because it's quality that we are always working to build and defend, and it's quality that makes space to solve new problems, rather than endlessly relitigating prior battles.

FOOTNOTES

  1. Many of the fixes Apple enumerates are issues that have been identified simultaneously in WebKit and other engines.

    Contributors sometimes fix bugs in multiple engines at the same time; an upside of the modern Open Source browser ecosystem. In other cases the addition of test collateral to WPT encourages projects to quickly address newly discovered gaps.

    In these cases, Apple's forced delay for feature releases hurts the pace of compatibility across the ecosystem. Safari 27 was announced in early June but doesn't launch until September, nearly four months later. Meanwhile in Chromium, the already quick 4-week release cycle has delivered fixes to the Stable channel from nightly builds in two to three months since 2021.

    Not content to rest on that relative advantage, Chromium is in the middle of moving to a two-week release cycle, and most Chromium-based browsers (Chrome, Edge, Opera, etc.) are committed to keeping that faster pace. Instead of a normal-priority fix taking two to three months to stabilise and deploy, the window will now be six weeks at the slowest. Patches that land just before branch cut could see deployment in just over a month, or 4x faster than Apple's feature release cadence for Safari 27.

    The upshot is that many fixes first developed for WebKit will appear for users and developers in Chromium browsers ahead of Safari 27's release. Separate and apart from the large feature gaps that remain endemic to Apple's engine, the slower pace of deployment continues to slow progress across the entire web ecosystem.

    Cupertino can pre-blog all it likes, but the world doesn't improve until the bits on users' disks are upgraded.

  2. The total number of tests enabled varies by less than 1% between engines. Therefore, we can safely compare pass-rates to get a sense of completeness and quality.

  3. There is reason to think that Chromium is missing fewer features than webstatus.dev captures because WebGPU is incorrectly marked as unsupported.

    In reality, WebGPU shipped first in Chromium, has been deployed most widely there (both across OSes and form-factors), and comes with the most expansive set extension features for developers, enabling richer applications more reliably than any other engine.

  4. My own estimates are that Apple clears something like a 95% profit rate on the web-derived revenue it takes from Google via the search deal, most recently revealed in court documents to be worth more than $20BN per year.

    Apple has recently increased its investments in WebKit, but it does not seem likely to have broken $1BN/year, all-up. Even the most Bork-addled thinkers cannot deny that margins this large, this sustained, on a product with defects so glaring must be the result of anti-competitive abuses of market power. Earning more than 40x Mozilla's income on a pure substitute, while delivering a substantially inferior product, hinges on excluding more competitive players from entering iOS.

    A market with real competition would force Apple to invest substantially more, would quickly improve quality across the ecosystem, and would deliver major gains to developers and end-users. Which is precisely why Apple won't allow it.

  5. The case of the prompt() API is a microcosm of Blink's values in a telling moment: a call we got wrong. As far as I can tell, Google enabled it for Chrome, proximately, in order to have something to talk about at I/O. This is a failure mode we try to guard against. Other Blink-ecosystem browsers pushed back, noting the lack of public test collateral and challenges in achieving interoperability. Unfortunately, and to my shame, I spotted that the Intent had garnered the necessary three votes to ship weeks after the branch cut.

    What happened next matters a great deal.

    Instead of doubling down on their position, Googlers took the concerns in the thread seriously, patiently answered questions, and are now working with the community to generate a comprehensive test suite. That should have happened prior to removing the OT requirement, but there is now a path to plausible interoperability based on objective quality metrics. No other Chromium-based browser is likely to ship until they're satisfied with the results.

    This is an uncomfortable and unusual situation. The API OWNERS have been clear with the team that they are expected to be responsive to ongoing developer feedback post-launch, and if radical changes are necessary post-launch, the Blink process provides that flexibility on an exceptional basis. Teams are guided not to make breaking changes, in part, because it harms developers. Because we care deeply about developers and not breaking the web, that harms the reputation of the team among the API OWNERS. Groups with a track record of causing pain for the ecosystem face heightened scrutiny when proposing subsequent features, and it's safe to say that the group that pushed prompt() through without bringing the rest of the Chromium community along is now in that unenviable position.

    Because Blink and Chromium feature useful, anonymised telemetry, we can keep hawkish tabs on growth of use of the API, currently several orders of magnitude below the rule-of-thumb use threshold (0.03% of pageloads) above which changes and deprecations become much harder to pull off. We're still in a moment when all's to play for.

  6. It's telling that Apple has not replicated these learning and iteration processes, preferring instead to move design conversations into smoke-filled rooms where it can leverage an explosion of veto players to obscure a fifth-column agenda.

    Jeremy is sceptical about the motives of Googlers asking which features to prioritise, and scepticism is always healthy — but only when applied evenly.

    To get a sense of the degree of good faith inquiry, we have to judge by track records; which engines give developers a structural voice in feature evolution? Which processes force work into the venues where developers can engage without committing to a Working Group meeting schedule (e.g., through incubation venues)? Which products provide transparent ways to engage, test early prototypes, and force developers to iterate in public?

    By contrast, which teams are working tirelessly to tear down and ignore easy-on-ramp venues? Fail to provide open processes for feature approval or insight into roadmaps? And which teams most often present fait accomplis, rather than opportunities to shape the future?

Previously