On writing the custom elements section for Modern Web Guidance
Nolan Lawson called the web components section I wrote for Chrome's Modern Web Guidance "discouraging at times," and he has a point about the tone. Here's why I leaned native-first, and where Nolan and I land in the same place.
On this page
My connection: I wrote the first iteration of the web components guides this post discusses. The original commit
Nolan Lawson published Do web components have a future if nobody is writing them?, and part of his case draws on Chrome's Modern Web Guidance, specifically the web components guides. I wrote the first iteration of those guides back in July (the original commit), including the section he links to, "Decide whether you even need a custom element."
# The native-first lean was intentional
When I drafted those guides, I was deliberately pushing models toward native HTML and CSS. Nolan describes that section as "discouraging at times"[1], and I can certainly see why.
Writing these guides, we all had to switch from our default writing-for-humans mindset to a writing-for-agents one; generally speaking, agents lean into abstraction. Ask for a button with a particular set of styles and there's a real chance you get a <my-button> where a styled <button> would do. The guidance aimed to set a higher bar: build a custom element when you need encapsulated state, a scriptable API, or behavior the native element can't express. A different look alone doesn't call for a whole web component.[2]
# Still a huge web components fangirl
I was a staff engineer on Spectrum Web Components at Adobe and co-founded the PatternFly Elements project at Red Hat[3] (one of the earliest web-component-based design systems from an enterprise company), so I've been discouraged by the industry's continued push to React-ify everything. If the choice is between a framework and a collection of web components, I'll advocate for web components every time.[4] I'm also part of both the CSS Working Group and the Web Components Community Group, and a lot of my standards work is collecting the community group's decisions, then presenting and advocating for them in the CSS Working Group.
What I keep running into, in framework libraries and web component libraries alike, is components built for jobs a native element and some CSS would do better: accordions that could be <details> and <summary>, modals that could be <dialog>, menus that could lean on the popover attribute. Those wrappers usually ship more JavaScript and lose some accessibility along the way. The people using them often can't see that, because they work with the component's API and never touch the HTML underneath.
The question that section asks is one I'd put to a React or Svelte component too: does this need to exist, or is the platform already doing the work?
As a first stab at turning that into a principle: web components are a good option when the project doesn't already use a different component framework, and the pattern needs at least one of these:
- Nontrivial markup beyond what a native element gives you.
- Interactivity. Custom elements have reliable lifecycle callbacks (
connectedCallback,disconnectedCallback), which beats wiring upquerySelectorAlland aMutationObserverto notice when elements come and go.
# Common ground
Nolan reads the line about design systems, embeddable widgets, and self-contained UI as a faint nod.[5] For me, those are the main use case. A design system primitive shared across apps built in different frameworks, or a widget dropped into a page you don't control, is where web components earn their place, and his own <emoji-picker> example fits right in that category.
I also agree with his closing point that web components have done a lot to explain the platform.[6] Guidance that tells an agent to reach for <details>, <dialog>, or popover first is pointing at features that web component ideas helped shape, through work like Open UI. By proving what features and APIs developers wanted, web components directly influenced the speed and maturity of the specifications.
# More to say
There's a lot more in the post that I'd like to come back to: the case for reuse when a rewrite costs one prompt, and the long-standing gaps he lists around server-side rendering, sharing stylesheets, and accessibility across shadow roots.[7] Those gaps are where I spend a lot of my standards time, and I agree that having agents write the code doesn't make those issues any less urgent.
So, the TL;DR: the native-first lean in the guidance was deliberate, an attempt to convince AI to reach for the platform before abstracting. Web components still have a clear job in that picture: shared design system primitives, embeddable widgets, and anything that has to work across frameworks. Where a native element and some CSS can do the work, I'd rather an agent reach for that first, whatever component model the project uses. To me, both approaches push work back to the platform.
Thank you to Nolan for writing this. He has spent years making the case for web components in public, and it shows in how carefully he weighs both sides here, including the parts he says were hard to write. His posts are some of the most thoughtful writing on web components out there, and I'm glad to be part of the conversation.
And thank you for following along as I think this through. If you see it differently, or you've watched agents handle components in ways I haven't, I'd love to hear about it. Tag me on Mastodon at @castastrophe@front-end.social.
Nolan Lawson, Do web components have a future if nobody is writing them?: "discouraging at times." Nolan is describing the guide's "Decide whether you even need a custom element" section. He concludes that an agent building a new product with this guidance probably wouldn't choose web components. ↩︎
One exception is a comprehensive design system library that ships its theming through a web component mixin or base class. Even then, a library could ship a set of core styles and document the expected markup instead. ↩︎
PatternFly Elements started as RHElements. Its base package, @rhelements/rhelement, was first published to npm on November 14, 2017. For context, Google's Polymer Paper Elements came earlier, around 2014, and Vaadin's elements had their first stable release in 2016. Salesforce announced Lightning Web Components in December 2018. ↩︎
A framework makes more sense when the app itself is the product: a lot of client-side state shared across many views, data that changes often and has to stay in sync with the UI, or client-side routing. A team already fluent in a framework's patterns and tooling is a good reason too. In those cases the framework's rendering and state model do real work that web components don't provide on their own. ↩︎
Nolan Lawson, same post: "a faint nod." He's referring to the guide's opening line, which recommends web components for design systems, embeddable widgets, and self-contained UI. He also points to a line in the Chrome extensions guidance that recommends shadow DOM for complex UI injected into a page. ↩︎
Nolan Lawson, same post: "explaining the platform." In his conclusion he calls this the clear win for web components, pointing to the user-agent shadow DOM inside elements like
<video controls>and to Open UI's use of web component ideas such as parts and slots. ↩︎Nolan Lawson, same post: server-side rendering, stylesheet sharing, and accessibility "still appear to be unsolved." He links the open discussion for each: server-side rendering, stylesheet sharing, and accessibility. ↩︎
Respond
The original takes comments in these places: