https://www.baldurbjarnason.com/2024/liskovs-gun/ * Archive * Newsletter * Work * Contact Baldur Bjarnason Web dev at the end of the world, from Hveragerdi, Iceland 8 October 2024 Liskov's Gun: The parallel evolution of React and Web Components Contents 1. Web dev keeps arguing about web components 2. WTF are Web Components? 3. WTF happened to Web Components to make everybody so angry? 4. The painful transition from "v0" to "v1" 5. Unidirectional data flow! It's magic! 6. WTF does 'commodifying developers' even mean? 7. The schism this has created 8. Web Components are defined in terms of alterations to the DOM 9. Inheritance is fucking tricky 10. This is where the difficulty of using Web Components to implement Functional Reactive Components enters the picture 11. All of this matters because we really do need web apps Because this essay is over 11 000 words long(!) I've made a convenience EPUB file for offline reading. (EPUB only! No PDF this time.) You can download it over on the fulfilment service I use, Lemon Squeezy, with the option to pay what you want if you feel the urge to support my writing. Paying is absolutely optional. Web dev keeps arguing about web components Unless you're like me - an "extremely online" kind of web developer - you probably don't notice the dramas and brouhahas that erupt in the web developer community with regularity. Most of the time these flame-wars offer little of value or less in terms of technical insight and the patter of angry voices fades away before it reaches the ears of the less online. But a recent one, which began when the maintainer of the SolidJS web development framework wrote a long and very angry-sounding blog post outlining why he didn't think web components represented the future of web development, is a little bit less usual. Not because it has staying power. It's fading away at the same steady pace as these things usually do. It's interesting because it touches on what I think is a genuinely interesting technical issue, but in a way that pretty much forces every reader to ignore it. Normally, these "debates" are free of useful information. Often it's somebody railing against this or that for largely personal reasons - I've certainly been guilty of that. Other times the points being made on both sides are largely innocuous. The people involved just seem to be using their "outside voices", metaphorically speaking, for no particular reason. "You should write tests!" "Yes, but you need to do it properly! Otherwise, they just get in the way!" "I AGREE BUT I PHRASE IT IN A WAY THAT MAKES ME SOUND ANGRY AT YOU BECAUSE THIS IS THE INTERNET AND I'M PROBABLY ANGRY AT SOMETHING!" It's tiresome, especially because it's common for this mode of debating to split people who are largely in agreement into groups that chalk each other up as assholes. The worst part being that both sides are generally true. Everybody involved had an asshole moment or two. What makes the web components debate interesting is that, this being the internet, many of the participants are behaving like assholes (though not you, dear reader, you're one of the wonderful sensible few of the internet) while at the same time making interesting yet conflicting technical points. "These two groups seem to both be making solid technical points, and yet they end up disagreeing," is always interesting. It means the topic has curious nuances and, possibly, unresolved hard questions. That bit is genuinely fun, at least if you're of a personality type that finds unresolved hard questions fun. The tone and attitudes of some of the posts involved make it difficult, but discovering if there's a "there" there can be worthwhile. But, because of the "everybody defaults to 'asshole'" nature of social media, we often end up in a discourse archipelago where each island vehemently sticks to its opinions, never listening to the other, because most humans will resolutely ignore advice and observations if they come from somebody they consider to be an asshole. The core point of the current hubbub, if you dig through the rhetoric and follow the links back to earlier discussions and arguments is: It's really hard to add extensibility and "composability" to an already complex class inheritance tree with pre-existing and rigidly defined composition system without making some hard compromises. But to get to that point, the point where we can dig into the technical details of the whys and wherefores, we first need to understand the context. We need to be able to look past the assholes to see the forest. We need to understand what somebody means when they say "web components". WTF are Web Components? If you aren't directly involved in specific kinds of web development, you might not have a clear idea of what Web Components are. They are a set of web APIs that have been standardised and, for the most part, implemented by web browsers. They are a standard method for implementing and distributing reusable widgets. * Custom Elements. These give you the ability to, well, define your own custom element. Implement a class, give it a name, and you've got your very own tag you can reuse. You've extended the browser's Document Object Model (DOM)! * Shadow DOM. These give you the ability to encapsulate branches of the DOM, so they don't interfere with or get interfered by other parts of the document. Important for creating encapsulated and portable widgets but have historically caused a lot of problems in practice. Many of these issues have since been solved. Its capabilities are now much less controversial, much more broadly supported, and largely untapped. * Template element. A deceptively simple feature that has turned out to be very useful. It's a mechanism for safely parsing and storing HTML fragments without affecting the main DOM. They offer bare bones template interpolation when combined with the Shadow DOM using elements. That's pretty much it. There are a few features and details that surround these, help them integrate with other APIs, help smooth the edges, but this is Web Components. Together, these APIs let us build custom widgets that can be safely packaged into a custom element and will interoperate with pretty much anything that renders to a DOM, even React (though React specifically blocked custom elements for what honestly sounded like spurious reasons for the longest time and even now full support has only shipped in a beta release). Web Components aren't what you would call a "disruptive" innovation, but they are genuinely useful. More so now they more reliably work with forms in modern browsers. They are a "hey, you know that thing browsers do? Well now you can do a little bit of that yourself" kind of extension mechanism. Slightly complicating the issue, the term tends to get reused across a few contexts. * Those three clusters of browser APIs are Web Components proper * A custom widget made using those three clusters of browser APIs is a Web Component * A framework designed from the ground up to make Web Components, such as Lit, is often referred to as a Web Components Framework, but doesn't usually provide any ready-made components. * A framework that doesn't give you tools to make them, but offers a library of ready-made Web Components, such as Shoelace which is soon to become Web Awesome, is usually referred to as a library of Web Components. This last type of project is the one that's of most interest to those in software development who might have to do some incidental web development. Because of how late Safari was to supporting form-associated custom elements, we're only in the early stages of what Web Component Libraries can offer, but they have the potential to provide ready-made yet powerful and customisable widgets people could use when making websites, services, or web apps, no matter what client-side or server-side framework they're using. Described this way, you might wonder how an otherwise innocuous set of web APIs, designed to aid in the making of reusable widgets, so consistently cause tension and conflict among web developers. So much so that it's almost certainly a very bad idea for me to wade into it with this essay. Why do Web Components cause online web developer communities to erupt in anger and argument? To answer that, we need to go back over a decade, at least thirteen years, all the way back to 2011. WTF happened to Web Components to make everybody so angry? The impression you're likely to get from discussions online would be that web components were created as a reaction to the rampant growth of React-based frameworks bloating websites and breaking accessibility. You couldn't be faulted for thinking that web component APIs came about as a proposed fix. "Stop using React and use these APIs, they come with the web!" But web components not only predate the popular misuse of React and the rise of frameworks, they arguably predate React itself. Web components surfaced to public view in 2011 in a talk at the Fronteers conference by Alex Russell. These weren't the web components you see today as the code he was presenting was a library, not a proposed standard - that would come later - but the shape of it is extremely familiar to those who have used modern Web Components. React at this point was still an internal project at Facebook and had only been in use for a few months, if that. These were two very different approaches towards creating dynamic web-based user interfaces, and they were as good as invented simultaneously. Their launch as public projects also happened at pretty much the same time with Google's first attempt to standardise Web Components and Facebook's first launch of React as an open source project both happening in 2013. This was, in my personal opinion, the point where multiple schisms in web development began to happen, the break that has hindered web developer discourse since. --------------------------------------------------------------------- I should emphasise here that the following description of events is my opinion only and entirely based on what I saw as an outside observer. I was not privy to any private discussions or chats. I absolutely missed out on some important context, but I can say that this is what it looked like to a lot of people at the time. I appreciate that everybody involved meant well and had good reasons for their behaviour, but people will form their opinion of you based on what they know and see, which doesn't include the stuff they don't know about, and especially doesn't include the stuff you haven't made public. People do not read between the lines on the internet. At best, they make weird shit up and pretend it's true. --------------------------------------------------------------------- Web Components at this point were, and I know quite a few people will again disagree with me, an entirely proprietary Google project, much like React was an entirely proprietary Facebook project. Web components during these first three years, the first iteration that later got called "Web Components v0", were only ever implemented by Google, only promoted by Google, and its biggest users were Google products and frameworks. The "polyfills", itself a term that implies inevitable standardisation, were from the perspective of everybody not using Google's Chrome the actual implementation of Web Components. They were slow as hell. This made the overall experience of Google properties that used them, such as YouTube, noticeably worse in Firefox. Not a great look, folks! To make matters worse - and, again, this is based on my impressions at the time and I know plenty of people disagree with me - a few of the more "enthusiastic" Web Components promoters during these three years were parading around being absolute assholes, to an even greater degree than seemed normal in online developer circles. Many of them seemed to outright believe that a set of APIs made unilaterally by a single vendor would inevitably get railroaded unchanged into a standard - in and of itself a highly problematic idea - and talked about web components being "the future", implying that every other approach, no matter how new, was "legacy" or somesuch. Remember, React and Web Components were both released at around the same time - arguably React came later - and here these dudes (almost always dudes) were strutting around calling everything else outdated and obsolete. They claimed to be the only ones properly "using the platform". Their approach was "standard". A "standard" implemented by a single browser, pushed by a single company, with no interest from other browsers visible to an outside observer for at least three years. This is arguably normal behaviour in tech, where a dev-rel's thankless task of building up good vibes about an API or platform can be tanked thoroughly by a lead dev opening their mouth and managing to simultaneously piss everybody off in 140 characters dumped onto the hive of seething malice that used to be called Twitter. But, because none of us saw what may or may not have been going on behind the scenes, and because Google was even then at the very least a proto-monopolist... This all? It was not a great look! It didn't help that React was in full promise-the-world myth-making mode. It no longer really mattered whether Web Components were superior to React or not. Web developers largely focused on React, which has always had more competent PR than most other open source projects. Another problem was that nobody else seemed to agree with Google that this specific iteration of Web Components was the future. Firefox and Safari never implemented version "zero" of Web Components. Most developers favoured React's approach to reactive programming and composition which, arguably, became the conceptual inspiration for pretty much every reactive component framework implemented since. Everybody who adopted this version of Web Components ended up getting punished for trusting Google. The painful transition from "v0" to "v1" To say that the Safari and Firefox teams were sceptical about web components is oversimplifying things. The template element was relatively uncontroversial compared to the rest. "Autonomous" custom elements - the ability to define brand-new elements with custom names () - were also relatively uncontroversial. The Shadow DOM and "built-in" custom elements - letting web developers directly modify native built-in elements in situ through sub-classing - proved much more divisive. Many at the time seemed convinced that this reticence was nothing more than a form of road-blocking, that these Mozilla and Apple employees were obeying some sort of secret directive from their bosses to "slow-walk" improvements to the web, but a much simpler explanation is that their concern was genuine, because there was a lot to be concerned about. These particular changes affect the core of how the Document Object Model (DOM) works. The consequences of doing the wrong thing would be both long-lasting and far-reaching, and the web has much too many footguns already. Messing around with the composition and inheritance models of the DOM is something you should legitimately be hesitant to do. Those arguing for ill intent do have their smoking gun: Apple's unwillingness to ship the awesome that would be built-in custom elements is, to many, clear evidence that Apple hates the web. That the rationale for doing so involved citing something so clearly bullshit-sounding as the "Liskov Substitution Principle" has frequently been mocked by web devs on social media. (Don't laugh. Many web devs also think "Model-View-Controller", "Separation of Concerns", and "unit testing" sound like bullshit. The web software industry has a substantial curiosity deficit. Apologies for the "X" links, but that's where nonsense lives, retires, and dies of old age after an active life.) But, for the purposes of this story, Liskov's a different kind of gun: Checkov's gun. And I'm not just saying that because I think "Liskov" sounds a bit like "Checkov" and it amuses me to link the two. This gun will be fired in the third act and not in the way the "WebKit developers hate the web" types think. It turns out the Safari team had a point. Looking from the outside in, like that creepy dude in the "Sickos" cartoon, the discussions at the time looked involved and intense. The GitHub issue with the infamous "Liskov" remark I linked to above is over 500 comments long, and it's one of many, not to mention mailing list threads and, I presume, a bunch of calls and in person conversations. But, eventually, browser vendors settled on a design for Web Components. This "v1" of Web Components was quite incompatible with "v0", punishing everybody who took Google at their word that their proprietary v0 would eventually become a web standard: * HTML Imports were dropped. * Shadow DOM was changed to use elements over queries and insertion points and the interaction between the light and shadow DOM changed as a result. * Selectors for piercing the Shadow DOM were removed. * Selectors for targeting Shadow DOM parts were changed. And a bunch more changes that I won't go into here, but suffice to say migrating from v0 to v1 was a painful process for many. Moving an existing code base that used the entire Web Component v0 stack to v1 was non-trivial. It took YouTube itself a long while to migrate. Having to drop v0 and having to redesign Web Components to address the concerns raised by Safari and Firefox did not make the more avid in the Web Components crowd humble or change their tone. If anything, from the perspective of a regular web developer (me, that is), their rhetoric seemed to escalate now they could point to Web Components being an actual standard. If you are a masochist, you should easily be able to find GitHub comments or Tweets from this period, the early years of Web Components from 2016 to 2020, where a Google employee is calling all other approaches "legacy code" or "legacy approaches" or something similar. If you were a lurker at the time in the discussion threads between them and framework implementers, you'd have noticed that their advocacy also seemed to become much more targeted. The pressure was on those making the newer web development frameworks to build them using web components, not just be compatible with them, and it looked immense. The targets of this pressure were not Facebook's React here, but newer frameworks such as Solid and Svelte. These are made by folks that, by and large, are very much in favour of using standards if possible, whereas the React folks seem more inclined to go "meh" and do their own thing. These newer frameworks are generally much better behaved when it comes to interoperability, exposing native DOM APIs, and performance. Both Solid and Svelte even compile to Web Components meaning you can use them to implement reusable custom elements for your projects. The problem? These pro-web maintainers have differing definitions of what's "possible" from those more avidly promoting web components. Some of that comes from the fact that Web Components seem to be largely unsuitable to implementing a functional reactive component framework, which should not be surprising since the two concepts evolved in parallel, not in sequence. It'd have been quite the coincidence if web components had happened to be a useful set of primitives for implementing something like Svelte or Solid. Quite a few of the people who build and maintain the frameworks themselves hold on to a lingering animosity because many of them feel gaslit about the capabilities of Web Components. Their perception of reality was that these standards were not useful to them at all, but the message they got - insistently - was that web components were the inevitable future of their own frameworks. This is the background that led Ryan Carniato, the author of SolidJS, to write his blog post Web Components Are Not the Future. That blog post is a reaction to a specific line of rhetoric that has gone unnoticed by most web developers because they were not the ones targeted. That's why it looked like such an odd, angry, outburst to many and those foolish enough to support their chosen web development tech as if it were a football team took it or the reaction to it as validation that their "team" was better than the others. What's missing from this are the reasons why React and its descendants won out over Web Components and their ecosystem. Just because you might not easily be able to use web components to implement something like SolidJS, that's a very different kind of problem from what most regular web developers are tackling. Ryan might have a justifiable gripe against a small group of over-enthusiastic Web Components promoters, but that doesn't answer the question that rises when you realise that React and Web Components are generationally peers - to the point of React having its first stable release in 2016 just like Web Components: Why did React win? And the answer to that, in my oh so personal opinion, isn't "because Web Components aren't great for specific kinds of problems, such as those framework maintainers deal with" no matter how technically reasonable that might sound. Remember, these technical observations and conclusions are popping up after React was well on its way towards resoundingly winning the popularity contest that is modern web dev. I think it comes down to a simple difference in promises. Web components promise you that you'll be able to extend the DOM in ways that are idiomatically compatible in with the rest of the DOM. React promised us a silver bullet: unidirectional data flow would fix UI development once and for all. Magical silver bullets will always be more popular than boring old incremental improvement. React offered two benefits to organisations: 1. React promised a much simpler model for how to make a UI, one that would magically make coders much more productive. 2. React also commodified coders by letting them learn primarily to code against a simplified abstraction and the component model itself turned them into organisationally fungible units. Both of these promises are science-fiction, and experienced React devs as well as React maintainers are both likely to be the first to point that out. People still believed in these fictions, and many still do. Both require some explanation. Unidirectional data flow! It's magic! React's core innovation was to treat the UI as a virtual data structure that could be reconciled with, or rendered to, whatever stateful group of objects you were using to render the actual User Interface. This was deliberately agnostic about whether the rendering target was a Document Object Model, a hierarchy of AppKit or UIKit objects, or whatever it is that Android has got going. This meant you could structure your UI components as a set of functions or classes that together took the app's state and returned a tree-like data structure and, because these were in theory just accepting and returning data, you could steal ideas from functional programming - immutable objects, no side effects, baby! - to make the whole process easier. Instead of complex manipulations full of potential side effects, your mental model of your GUI app would be something along the lines of: UI = f(state) Events and actions generated by the UI modify state. That triggers the f(state) part again. The data structure returned from the components is diffed with the existing UI and the UI is updated based on that diff to reflect the new state. This is what the React scene calls "unidirectional data flow" ("one-way data flow" in more recent documentation) because data only flows from state to UI, whereas the data that flows from the UI back into state is labelled "actions" or "events", which means they aren't data, silly. No, the data the user is typing into the form isn't data. It's an action. Here, read this rambling blog post and library of old-style Twitter threads that explain it. Of course, you need to be smart enough to understand that data isn't data except when it's data, and it's always going in one direction except when it's going in the other, in which case it's a cycle, which makes it all one direction. Something about drawing it as a circle somehow makes people miss the fact that stuff is obviously flowing in multiple directions. Not just up and down, but sideways within a component and often React apps just completely drop the pretence and shove the data directly to where it belongs using things like the Context API. But, sure, the data only flows one way. You just need to have curious definitions of the words "flow", "one", "way", and "data". That, however, isn't the problem with the idea. It's actually a neat idea that forces you to rethink some of the basic principles of GUI software development. The problem is that it's pretty much only an idea: a myth. What we get in practice is almost always quite different in very important ways. The issues, in no particular order: * The DOM and CSSOM as a rendering surface is just one big fucking yarn ball of interconnected side effects that have side effects of their own. This means the components themselves are largely meaningless when removed from their rendering context. But React components are also intentionally abstracted away from their rendering contexts. Between the many different rendering engines, hooks, contexts, synthetic event system, server actions, and more, there really is no such thing as a genuinely "functional" React component. Even if it looks like a function that just takes props and returns markup, it isn't really. It is effectively impossible to fully understand what's going on in any given component that's a part of a big app just from looking at the component itself. * This also means you lose the easy unit testing that is usually associated with functional software development, to the point where large chunks of the React community have given entirely up on unit testing as a concept and instead focus on types and integrated testing. Those that haven't given up on unit testing often just do integrated testing, wave their hands, and pretend it's unit testing. This is what happens when you build a framework on a concept that pretends to be functional but actually isn't. * Diffing and merging a data tree of arbitrary complexity and depth involves big hairy computer science problems which, when combined with the problem of decomposing state into discrete parts that flow down into the components that need them, means that the only thing to do much of the time is to re-render the whole fucking lot - or at least big chunks of it - whenever something changes. Re-rendering everything on every update is exactly the sort of thing Single-Page-App types were trying to avoid when they arbitrarily decided that "POST to update, return a bunch of HTML" wasn't a good model for building "web apps", so React both has a bunch of internal optimisations that make the functional data model even more fictional, and offers a collection of state management interfaces - context API, hooks, lifecycle methods, for example - to help you manage state without causing full-tree re-renders, so in practice these "functional reactive components" look less like pure functions and more like the more heavyweight View objects you see in a more traditional Model-View-Controller app architecture. But, Baldur, you don't understand! You don't get React! Oh, I understand. When I use a model object that's connected to a view object using a coordinating object (controller, presenter, or whatever), then sure that's MVC or MVP. But, when you do it, it's a parent component that's using the context API and hooks to coordinate a state object with a functional child component. Effectively, as soon as you try to do meaningful work with React, the "unidirectional data flow" ceases to be an architecture and becomes an origin myth. Meanwhile the actual architecture is whatever uncoordinated "I can't believe it's not MVC" hocus pocus is popular in the React scene the week the project was started. For a very brief period, React's tag line was something like "The V in MVC", but they quickly gave that up because there's so much more in React than just the components. They have an entire array of state and event management tools that together assemble whatever app architecture you want. React has always been the whole kit and caboodle, not just a "V". It's just never enforced a single, coherent architecture and instead provided hooks and tools with no direction and soft boundaries. But it promised magic, and people didn't seem to notice that, in time, making and maintaining a React app was just as much work, if not more, as those made using more traditional approaches. Moreover, React apps that were explicitly structured using the Model-View-Controller architecture from the ground up tended to, in my personal opinion as an extremely biased outside observer, be less problematic over time than those that went all in on the unidirectional gravy train. A promise of magic is always going to be more popular than promising to give you sensible - the "wear practical shoes, it's going to be a long walk" kind of sensible - steps forward. Even if Web Components had met with universal approval among browser vendors right out of the gate, it's unlikely they would have ever won out over the promise of making the development of dynamic user interfaces magically easier. It should not be surprising that more modern component frameworks, ones that aren't saddled with a largely fictional core concept, such as Vue, Svelte, or SolidJS are by almost every metric faster, lighter, and more productive than React. Preact even manages to be a far superior "React" than React itself. React has become a bloated carcass of false promises, misleading claims, and unending layers of backwards compatibility - the wrong kind of backwards compatibility, as they still occasionally break your fucking code when updating. Pretty much anything else is a better tool for pretty much any web development task. There's also more genuinely useful innovation going on everywhere except React. SolidJS came up with signals, a genuinely interesting method for handling state. Preact adopted it and arguably came up with a more interoperable implementation of the idea. Vue and Svelte both hew closer to web norms in interesting ways. If you want innovation and experimentation, there's a lot of it going around. Just not in React. Promises of magic only go so far. Since the consensus of the overall effect that React has had on the web is currently ranging from "on the whole, probably not great" to "the only thing that would be worse for the web would be a comet wiping out all civilisation, and even that would be a blessed relief," if that were all, React would not be nearly as dominant in the web software industry as it still is today. That's where commodifying developers comes in. WTF does 'commodifying developers' even mean? In basic terms, what management wants is the ability to add, remove, or move around staff while pretending that said staff is largely interchangeable and that the moving around doesn't mess things up in and of itself. This is the case for most modern companies, not just the ones in tech. Any form of expertise or specialisation makes that idea even more fictional than it already is. Employers generally love whatever scheme they find that can narrow the skill sets required to do a task down to something that can be clearly defined in market terms. One way to do that is by requiring specific degrees and certifications. Another is to standardise on using specific tools and platforms and hiring for those. You don't try to hire people with good problem-solving skills, an ability for writing clearly, an affinity for numbers, or an understanding of how computers work that helps them pick up new apps quickly. You hire for skills in "Word" and "Excel". That lets you hire quickly, fire quickly, and move people around as if they were, I don't know, Legos or something. (Sorry, "Lego bricks", he corrects himself before the pedants light their torches and grab their pitchforks.) This is hard to accomplish in software development. The entire job is basically discovering and solving poorly-defined problems with squishy human elements at its centre. React stepped in just in time to help managers en masse fake their way to a promotion during a low-interest-rate bubble. Much like "Word" and "Excel" have become the "fungibility" stand-ins for "can write clearly" and "understands numbers", React has become a stand-in for "UI software development". It hides the complexities of what's happening underneath a layer of abstractions. Instead of learning a host of DOM querying and manipulation APIs or the workings of platforms like UIKit, you just return JSX. Instead of exposing the various nuances and intricacies of event handling on each platform, you get one form of event delegation and you're going to like it. The JSX data structures are so abstracted away from the actual platform that they even offer approaches for you to pretend there isn't any difference between a web, iOS, and Android app and let you target (or try to target) all with a single code base. React developers interact with a drastically simplified view of the world. Because that simplified view has limitations, the underlying platforms push their way into the job with alarming regularity. But because the point of hiring for React is to not hire people with the specialised skills to deal with the nuances of underlying platform, most of the time everybody reaches for a dependency instead. Something made by somebody with a deeper understanding of the underlying platform that packages up a set of solutions that those with full-on React blinkers can use. This heavy reliance on dependencies compounds React's many pre-existing performance problems. The bloat of these web apps isn't accidental but a by-product of how React is used by management. (I've written about this before, for those who are curious.) Understanding how the DOM works is a hard requirement for using tools to extend the DOM. This made Web Components a non-starter. Web Components didn't help enable the massive growth in head count that drove much of the decision-making in tech from 2011-2022. Bear this in mind below, when I go into some of the technical limitations of Web Components. Those limitations are not the reasons why React won. React ended up the winner because it devalued software developers and made promises it could never fulfil. The schism this has created If that were all, then web components would just be a textbook case of over-aggressive promotion and hubris leading to self-sabotage, and a useful but limited technology losing out primarily because of the market's many dysfunctions. Both are a regular occurrence in tech and software development. But has had other consequences. It has fractured the online web development community. The React-versus-everybody-else schism is obvious, but the other schisms are arguably more tragic. Specifically, drama surrounding Web Components and a steady parade of similar events has fractured the part of the community that is trying to get the industry to stop using what has now become the actual legacy framework: React. Instead of a united front that promotes a set of approaches as alternatives to React, each with differing optimal use cases, we now have three factions that do not collaborate nearly as much as they should: 1. "Use the platform". Standards-oriented web developers who have been promoting the idea that for many - if not most - web development use cases, it's faster, cheaper, and more reliable to just use browser APIs directly instead of through the indirection of a framework. Many people in this group tend to be against all frameworks, no matter how they are designed or implemented. A minority is even outright against the notion of JavaScript in the first place. 2. "Web Component" framework implementers that, for one reason or another, associate themselves with Web Components as a stack and some with the "use the platform" movement. These frameworks have usually been designed from the ground up to accommodate web components and inherit their limitations, at least on the client side. 3. Other reactive component frameworks that, for equally arbitrary reasons, don't associate themselves with web components or the "use the platform" movement. These are the ones that have felt targeted by web component advocacy. Most of these frameworks are already highly interoperable with web components and never had React's issues with using third-party web components, so Web Components advocacy that targets them seems to be entirely about how the frameworks themselves are implemented. Because of the adversarial relationship between them and the other two groups, these communities tend to side with what is arguably a more genuine threat to their existence: React. The differences between these groups are not technical. WebC and Svelte both use single file HTML components and compile to HTML, CSS, and JS, usually mediated through a chosen site generator - "meta-framework" if you will - Eleventy and SvelteKit respectively, and they both include custom elements as compile targets. Any debate that presupposes a fundamental technical difference, beyond just their relative sizes, between these two frameworks is already in the wilderness. Using Lit is not morally superior to using Vue. Different frameworks have different trade-offs and, yeah, that does mean that sometimes one is a more productive choice for a situation than the other. Sometimes that means that Lit, Eleventy with WebC, or Enhance, are the better choices. Sometimes it's Vue, SolidJS, or Svelte. The core difference between the second and third groups is that the third group, like SolidJS for example, often tried at some point to integrate various parts of the Web Components stack into the implementation of their projects and became very frustrated with the technology and now many of them seem to be quite bitter about web components as a result. They were promised platform fundamentals that - because they were the future of frameworks - would work as building blocks of their own projects. This is a needless divide. "Use the platform" developers, web component frameworks, and modern reactive frameworks can all use and benefit from web components today. You can use a web component in Svelte and you can use Svelte to make a web component. WebC will work well using a Svelte component that has been compiled to a custom element. Those who eschew frameworks can use components made in either in their projects. Web Components, if the goal was to improve interoperability and reuse, are a smashing success. They are an incredibly useful building block for modern websites that's only going to become more useful now that we have broader support for form-participating custom elements. Lea Verou does a good job of explaining what Web Components are good for in her own post on this topic: Frameworks already use native HTML elements in their components. Web components extend what native elements can do, and thus make crafting project-specific components easier across all frameworks (as well as no frameworks). I tried to find a better way to phrase this, but Lea already came up with the perfect framing. Most devs could just stop here, read Lea's post, nod a few times as they scroll, and be done with it. (Though, you're most of the way through this behemoth of an essay by now, so you might as well read i to the end.) This is how Web Components work. This is how we should be using web components and frameworks. (And, by the way, the fact that the Font Awesome people have hired her and Zach Leatherman have turned my scepticism about Web Awesome into outright enthusiasm, even if Zach isn't involved in it directly. I'm very much looking forward to seeing what they and Font Awesome do in the future.) However, the underlying technical reasons why web components are a bad fit for some software architectures are still there, largely unexplored. I've had to use web components quite a bit, myself. I largely like them. I even see the appeal of the Shadow DOM, despite its many issues. I've used web components (no framework), Lit (a framework designed with web components in mind), and Svelte (a reactive component framework) for complex projects, and I've experimented with a lot of the rest with prototypes. But, in my experience, using web components, with or without Lit, to implement a big project end-to-end was usually harder and more complicated than using a reactive framework for the same purposes. It was also sometimes harder than using no framework at all. When people say "use the platform" they aren't just talking about the handful of Web Component APIs. The platform has more to offer than Custom Elements and Shadow DOMs. Web components can be suboptimal for many projects for reasons that are very similar to the reasons why they aren't useful for the internal implementation of frameworks like Solid or Svelte, but I can't speak for framework implementers, only for myself. Web Components are defined in terms of alterations to the DOM The first issue has to do with how web components interact with the rest of the Document Object Model (DOM). Every API that's commonly bundled under the "Web Components" umbrella is defined in terms of their alterations to the DOM: Shadow DOM, custom elements, even the