In favor of Custom Elements built-ins

Andrea Giammarchi
4 min readFeb 23, 2022


Photo by Franco Antonio Giovanella on Unsplash

It should surprises nobody that knows me what I think about CEs builtin extends: these are the best primitive ever as well as, imho, the most underrated one out there!

People complaining about Custom Elements builtin extends usually have these arguments:

  • as Safari team stated they don’t like it, nobody wants to use a polyfill forever!
  • without Shadow DOM encapsulation wonder, Custom Elements make no sense
  • has the name clashing/versioning problem being solved?

At the very same time, the people convinced these are good arguments, do the following:

  • use 100K+ library to solve hydration (a best in class CEs builtin extend feature) regardless the numerous posts on the Web describing hydration as the most complex thing to obtain in a reasonable way, with reasonable performance, and without bloating the needed JS around it
  • whatever non CEs based solution they’re adopting, is not based on CEs but it solves encapsulation, just exactly like everything else has been working to date on the Internet, because Shadow DOM has never really been needed, and alternative solutions have been proposed for years … and guess what: builtin extends work out of the box already with every encapsulation solution already available to date!
  • enforce a specific Server Side Rendering solution that cannot possibly scale across programming languages and platforms; something CEs without Shadow DOM and builtin extends already solved because every browser understand builtin extends, even Safari out of the box, thanks to the graceful enhancement concept
  • everyone is OK using hundred megabytes of tooling dependency, when it comes to bundlers, and nobody apparently figured it out that name clashing for CE is just a matter of bundling, like I’ve done already for the last 3+ years with may of my projects … and so could be solved the versioning: <div is="special-div-v1-0"> is a tooling issue to propose/implement, not a platform one … can we agree there? (yes, versions work with CSS too … div[is^="special-div-v1-"] )

’cause if we can agree on these points, we should wonder how comes everyone is trying to solve what Custom Elements builtin extends already solved, cursing instead this part of the living DOM standard that has been working in my case since at least 2014, when I’ve written the first v0 polyfill, which also worked great for ~10 years and behind huge projects too!

This madness … but why?

  • Chrome, Firefox, Edge, Opera, Brave, all browsers but Safari/WebKit have 100% native support for Custom Elements builtin extends, and we live in an era where many don’t even test on Safari anymore before going in production, because “everyone uses Chrome, lulz!” … and yet, everyone is super defensive about using ~1K polyfill, optionally distributed via import maps, so literally a Safari/WebKit only thing and bandwidth “waste” (I mean … ~1K, seriously?!), but everyone is OK using 100K+ library to obtain an inferior hydration capability compared to the standard already available in every browser
  • every solution to date that is not based on Shadow DOM and Custom Elements is already solving the encapsulation issue, but it’s apparently incapable of connecting the built-in extends dots to drop every possible issue around hydration for every possible library out there …
  • how can anyone say “we don’t want a polyfill forever” and contextually use a library to produce any layout, so that they’ll need that library forever?

And that’s all folks!

I honestly can’t read certain comments anymore … like: “don’t use builtin extends, use React” (this is not a post against React, it’s rather a post about why on earth React, among other libraries, is not using CEs builtins to solve hydration) …

I mean, is anyone actually understanding the difference between solving a problem for 80% of the Web natively and polyfill via ~1 extra K only Safari, compared to the size of any library or framework they’re using daily, plus the code needed to provide meaningful hydration there?

The polyfill, for what is worth it, could even be inlined as script, and lighthouse wouldn’t notice the difference … so why is not everyone using it already? 🤔

This is the thing I don’t really understand, and to me it feels so illogical, yet people convinced builtin extends should be avoided like hell don’t apparently get it: they’re using an indirection backed in the DOM that requires a ridiculously small amount of code to be fixed, either via an unobtrusive polyfill, or a basic library, where both via dynamic import maps would result into real zero JS overhead to serve, and all of this through 100% SSR capabilities and compatibility … so why aren’t we combining our solutions with custom elements builtin extends?

As summary

I wonder if we could try to do a step backward, so that we can jump 5 steps forward later on, through integration, as opposite of spamming avoidance, of Custom Elements builtin extends: so much potential nobody is daring to explore, apparently, beside me and very few others, but I wish that wasn’t the case.

Thanks for reading this far! ❤ Happy to hear your thoughts too 👍



Andrea Giammarchi

Web, Mobile, IoT, and all JS things since 00's. Formerly JS engineer at @nokia, @facebook, @twitter.

Recommended from Medium


See more recommendations