Web components are a set of web technologies that allow us to create reusable HTML elements. They make it possible to develop framework-agnostic, custom components that use the HTML syntax. Browsers can natively interpret them without a third-party library such as React or Vue.js.
These days, web components are a divisive topic. They were once expected to revolutionize frontend development, but they’re still struggling to achieve industrywide adoption. Some developers say web components have already died, while others think they’re the future of web development.
Let’s zoom in closer and explore what web components are, why developers are reluctant to use them, and what the future holds.
Where can you find web components?
One of the most asked questions about web components is where or how to find them. Currently, web components don’t have a distinct home. It’s not that they are completely homeless. Rather, they’re couch-surfing within W3C’s extended ecosystem.
Originally, web components had a standalone W3C specification called Custom Elements. Custom Elements was deprecated in 2018 and its parts moved into the HTML and DOM standards, respectively:
- Custom elements (defined in the HTML Living Standard specification)
- HTML templates (represented by the
<slot>elements, also defined in the the HTML Living Standard specs)
- Shadow DOM (defined in the DOM Living Standard as shadow trees)
The web components technology used to have a fourth element, HTML imports. HTML imports aimed to package HTML modules as
Just like there’s no distinct home for specifications, there’s no central place or library where you can find and download open-source web components. Even though there are some promising projects (we’ll look at some of them below), you have to find them on your own.
How do web components work?
Before delve further into the issues of web components, let’s quickly review how they work.
Here’s the basic process of setting up a web component:
- Create a
MyElementclass that extends the
- Define the
<my-element></my-element>custom HTML tag that will represent the
CustomElementRegistry.define()method or the DOM API’s
- Attach a shadow DOM tree to the custom element’s constructor using the
Element.attachShadow()method. This step is optional and only applicable when the web component has child elements — see a web component example without (
<flag-icon></flag-icon>) and with (
<popup-info></popup-info>) a shadow DOM
- Create an HTML template using the
<template>tag. Place the reusable content of the custom
MyElementweb component within the template and append a clone of it to the shadow DOM. You can also add
<slot>tags (the latter is for dynamic content within the template) to the template. This step is optional, too, you only have to add a template if you want/need to
MyElementas an ES6 module
- You can use the
<my-element></my-element>web component on your page the same way as any standard HTML element
Why people aren’t using web components
Web components have promised many awesome things. Why aren’t more developers using them?
It’s not due to a lack of interest for a browser-native technology that extends HTML and makes modular frontend development easy and fast. One problem with web components is that the barrier of entry is too high. Existing web components, for the most part, are not very user-friendly, and there are some technical issues with the specifications themselves as well.
In other words, web components are a good idea in theory, but the implementation is still lacking.
Let’s look at some other drawbacks to using web components.
Web components don’t follow native HTML behavior
Web components were intended to behave similarly to native HTML elements. That means developers should be able to control them using HTML markup, such as tags, relationships between parent and child elements (think
In theory, it would be possible to create well-designed custom elements that fit with native HTML behavior. This simply doesn’t happen frequently in practice. Jeremy Keith summarized this problem in his conference talk, “Evaluating Technology,” back in 2017 (the landscape hasn’t gotten improved much since then):
Issues with backward-compatibility and SEO
Obviously, if a web component doesn’t follow HTML design principles, you can’t add content for older or nonsupporting browsers, so people using those browsers won’t see anything on the screen.
Ideally, custom and standard HTML elements should be used together and complement each other. Custom elements are only necessary when there’s no corresponding standard element.
Say you want to create a horizontal tab element, for example. If you want to make it compatible with nonsupporting browsers, you can design it in a way that it works together with a standard HTML element, such as
<div>, depending on the type of content that goes into the tab:
<horizontal-tab> <p>CONTENT</p> <p>CONTENT</p> <p>CONTENT</p> </horizontal-tab>
For lower-level compatibility, you could create another custom element for the tab items but still add the content via HTML. Introducing
<tab-item> is unnecessary since you could store the internal content in a standard HTML tag. Here’s a real-world example of this solution.
<horizontal-tab> <tab-item>CONTENT</tab-item> <tab-item>CONTENT</tab-item> <tab-item>CONTENT</tab-item> </horizontal-tab>
Dropping HTML imports
<link rel="import" href="module.html">
Since browser vendors expected that ES6 modules would replace HTML imports with time, they decided not to implement the feature; Mozilla, Webkit, and Chrome all stopped considering adding HTML imports.
Currently, web developers use ES6 modules in place of HTML imports to package web components. This further adds to the complexity of a process that was intended to be easy and beginner-friendly.
Technical limitations of the web component specifications
As I mentioned earlier, specifications related to web components can be found at three places:
- Custom elements
- HTML templates
- Shadow DOM
But, this is just one of the problems specs-wise. There are many other technical issues that you’ll encounter if you start developing a custom element.
Michael L. Haufe collected some of them in his excellent article, “The Criticism of Web Components.” The most troubling issues include the following:
- CSS pseudo-elements, such as
:checked, don’t work with custom elements
- Standard HTML elements ignore custom elements if their behavior is related to each other — for instance, the standard
formelement ignores a custom input element
- Custom elements can’t extend higher-level standard elements such as
HTMLButtonElement, but they need to extend
- ARIA roles have to be re-added to custom elements and also to their child elements, even if those are standard HTML tags with default ARIA roles (see more about this on the Salesforce Developer Blog)
These technical issues stem from the limitations of web components standards and have to be addressed using various hacks or extra code (that further increase complexity).
No central directory
It’s not easy to find web components. There’s no central directory or index, so you have to surf through the web to find what you need.
If you find more than one web component of the same type, it’s difficult to figure out which one fits your projects better, mainly because many web components lack good documentation.
UI libraries vs. web components
UI libraries, such as React, Vue, and Angular, serve the same purpose as web components: they make component-based frontend development possible. Even though they’re not native to web browsers (you have to add the libraries separately while web components use web APIs built into the browser, such as
CustomElementRegistry), they have a huge ecosystem, good documentation, and many developer-friendly features.
So, it’s natural that many companies opt for these popular UI libraries rather than experimenting with web components — especially since it’s also easier to find developers with this kind of knowledge on the job market.
The future of web components
Even though the web component technology faces many problems, using web components still has some advantages.
Most importantly, while frameworks are coming and going (think Backbone.js, which has almost completely disappeared), web components are browser-native technologies. That means if you’re planning for the long term, you can future-proof your project by opting for custom-developed web components.
Many popular UI libraries also publish their elements as web components so you can use them in your projects in a framework-agnostic way — for instance, here are Angular components packaged as custom elements. This also shows that the creators of these frameworks count with web components in the long run.
There are some promising web components projects, all developed by big industry names, including Microsoft’s FAST components and Salesforce’s Lightning Web Components. In addition, Google still maintains the Polymer project ,albeit with a new component-based class.
If you don’t want to use someone else’s web components and would rather create your own, there are some open-source tools and resources, such as the Stencil.js web component compiler by Ionic (also used by Apple), the Open Web Components toolkit, and the Gold Standard Checklist for Web Components , that can help you follow best practices.
Given these developments, there is still some hope that web components will be adopted more widely in the future.
Overall, having access to more accessible, easier-to-use web components that resemble more native HTML elements would be a great advancement for frontend development.
To achieve this, developers of web components need to follow best practices, give more respect to the principles of HTML, create better documentation, and think about backward compatibility.
To stay in the loop, you can follow the latest news, issues, and discussions related to web components in the webcomponents GitHub repo maintained by the Web Incubator Community Group (WICG).
LogRocket: Full visibility into your web apps
LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.