HTML Web Components
I think the word âcomponentâ in âweb componentsâ confused a lot of people â at least it did me.
âWeb componentsâ sounded like the web platformâs equivalent to âReact componentsâ. JSX had <MyComponent>
and now the web had <my-component>
.
But when you try building web components the same way you build React components, itâs easy to get frustrated and give up because web components donât work like React components â I know I gave up a few times.
The grain of a React component is not the grain of a web component. Their design prioritize different functionality and forms of use. If you try to use one like the other, youâll fight the direction of their natural grain.
Web components have their own grain and it favors enhancement over replacement. What do I mean by this?
A typical React component might look like this[1]:
<UserAvatar
src="https://example.com/path/to/img.jpg"
alt="..."
/>
You could write a web component this same way, e.g.
<user-avatar
src="https://example.com/path/to/img.jpg"
alt="..."
></user-avatar>
But the unique power of web components (in the browser) is that they can render before JavaScript. React components cannot do this â full stop.
This feature of web components encourages a design of composability. Rather than an empty âshell componentâ that takes data and (using JavaScript exclusively) renders the entirety of its contents, web components encourage an approach of composing core content with HTML and then wrapping it in a custom element that enhances its contents with additional functionality.
<user-avatar>
<img src="https://example.com/path/to/img.jpg" alt="..." />
</user-avatar>
This specific flavor of componentization is what Jeremy calls âHTML web componentsâ:
If your custom element is empty, itâs not an HTML web component. But if youâre using a custom element to extend existing markup, thatâs an HTML web component.
React encouraged a mindset of replacement: âforgot what browsers can do; do everything in a React component instead, even if youâre reinventing the wheel.â
HTML web components encourage a mindset of augmentation instead.
I like that term âHTML web componentâ. It stands in contrast to a âJavaScript web componentsâ which would be an empty element whose functionality and contents rely exclusively on JavaScript.
Per my earlier example, this would be a JavaScript web component:
<user-avatar
src="https://example.com/path/to/img.jpg"
alt="..."
></user-avatar>
It relies exclusively on the presence of JavaScript and is meaningless to the end user without it.
Whereas this would be an HTML web component:
<user-avatar>
<img src="https://example.com/path/to/img.jpg" alt="..." />
</user-avatar>
It has meaning and content without JavaScript â then is enhanced by its presence.
This idea of augmentation/enhancement over replacement is intriguing.
On The Web, Augmentation Wins in the Long Run
Augmentative approaches work best on the web because 1) the webâs grain encourages enhancement to improve resilience, and 2) thatâs really the best way to iteratively change something as big as the web.
Eventually all the best ideas of web-adjacent frameworks are subsumed into the platform to work in ways that augment the existing technology rather than replace it wholesale.
XHTML wanted to replace HTML4, but HTML5 wanted to augment it. HTML5 won.
Networking libraries wanted to replace XMLHttpRequest
and their best ideas were eventually ported into the fetch
standard â which exists in more places than just the browser these days!
The best ideas of Sass and jQuery were ported to the browser.
Typescriptâs best ideas are going to the browser, but in a way that works to enhance not replace what exists.
With web components, you might even say Reactâs component model is being ported to the browser. But itâs being done in a way that works to enhance how the web already works, not replace it.
My takeaway is: if youâre looking for longevity, opt for a technical approach of augmentation and enhancement over replacement. The webâs grain is arranged in that direction.