DEV Community

Cover image for Web Components did not fail!
Danny Engelman
Danny Engelman

Posted on Edited on

Web Components did not fail!

My comment to yesterdays Dev.to post: Web components failed. We can fix them became a full post:

TL;DR:

Web Components never failed.
Browser vendors have used Web Component-based architecture for decades.
Yet developers keep building apps, inventing frameworks, and adding dependencies instead of embracing the platform.

Build apps with frameworks. Build components with Web Components.

The technology isn't the problem. Our mindset is.

From the comments:

The line about every <video> being proof really stuck with me.
I swapped a framework-tied date picker for a Web Component a while back.
And it's the only piece that survived two framework migrations untouched.


Web Components Never Failed


Web Component history

The Web Component story didn't start with today's Custom Elements.

Almost 28 years ago, in 1998, Microsoft proposed HTML Components (HTC):

https://www.w3.org/TR/NOTE-HTMLComponents

In 2006, Mozilla took its own stab at componentizing the Web with XBL, first developed for Mozilla and later proposed as a specification:

https://www-archive.mozilla.org/projects/xbl/

Different technologies, different APIs — but the same underlying desire:

Make pieces of the Web reusable, encapsulated, and programmable.


Your Web Browser serves you Web Components...
on every Web page!

Browser vendors have been using Web Component machinery for many moons longer than we mortal developers have had today's standardized Web Components APIs.

To Us, Modern Web Components became broadly available roughly around:

Chrome 2016 · Safari 2017 · Firefox 2018 · Edge 2020

But browsers themselves have always had that same problem to solve:

  • The WHATWG specifies what an HTML element should do.

  • Browser vendors still have to decide how to build it.

Take a complex native element such as:

<input>
Enter fullscreen mode Exit fullscreen mode
<textarea>
Enter fullscreen mode Exit fullscreen mode
<video>
Enter fullscreen mode Exit fullscreen mode

From the developer's perspective, that's one element.

Underneath, there may be an entire internal UI: buttons, sliders, labels, tracks, controls and state.

That should sound familiar.

It is the same Web Component technology us mortal developers use!

With the appropriate DevTools settings, browsers can expose these internal shadowDOM trees for inspection.

<video> with sahdowDOM in Chromium

Chromium video Shadow DOM

<video> with shadowDOM in Firefox

Firefox video Shadow DOM

They're not your DOM to manipulate.

They're implementation details.

And that's precisely the point.


Web Components did NOT fail

So saying:

"Web Components failed."

has always sounded a little strange to me.

We interact with componentized browser <input> UI every single day.

The browser platform itself demonstrates why encapsulated components are useful.

The question isn't whether components work.

The interesting question is:

Why don't we build more of our own software that way?



Mortal developers and Web Components

I think part of the problem is that we keep thinking in Apps.

Frameworks encourage that.

They scaffold applications.

They give us routing, state management, rendering systems, build pipelines, dependency graphs and application architecture.

And that's perfectly fine when you're building an application.

But:

Frameworks scaffold Apps.

and

Components are components.

A component doesn't necessarily need to know anything about your application.

A <date-picker> doesn't care whether the surrounding application uses React, Vue, PHP, Django or plain HTML. Or the car is painted red.

A <relative-time> shouldn't need to know either.

Neither should:

<car-tire>
<steering-wheel>
<playing-card rank="Queen" suit="Hearts"></playing-card>
<mark-down src="playing-card-component-usage.md"></mark-down>
Enter fullscreen mode Exit fullscreen mode

They should just work!



We are still building Apps like it's 1899

There's another problem.

Many developers learned one particular way of building software and then taught those patterns to coworkers, and — directly or indirectly — to AI.

So AI happily reproduces them — and teaches the next generation that this is simply how software is built.

Ask AI to build something and you'll often get an entire application architecture when what you actually needed was:

<something-useful>
Enter fullscreen mode Exit fullscreen mode

The tool isn't necessarily wrong.

We're asking it to build the wrong thing.

That's a mindset change.

Change your perspective from:

Everything is an App

to:

Apps with frameworks. Components with Web Components.

There are Henry Fords out there already working differently.

And I suspect some of them aren't shouting about it.

Why would they?

Once you've trained your tools — and your AI — to produce small, independent components instead of miniature applications, it can become a competitive advantage.


"I can do Web Components better!"

In 2022 there were already around 60 Frameworks, Libraries and BaseClasses listed in:

I-can-do-Web-Components-better (aka All the ways to make a Web Component)

Sixty!

And here's where I think we repeatedly take the wrong turn.

  • You discover Web Components
  • You develop a few helper functions
  • Then: Oh, it needs this feature...
  • Then another feature
  • And another
  • Soon you've created conventions
  • Then abstractions
  • Then dependencies
  • Then documentation

Congratulations!

You're building a framework (or a Design System)
And your ego just publsihed it to NPM

Instead, write the abstractions you need for your components.

  • They don't have to become somebody else's architecture.
  • They don't even have to be shared abstractions in your components.
  • Duplicate your code! Something every "guru" developer told you not to do. A well trained AI is great at managing those.

What about (Google) Lit?

Yes, I consider Lit a framework.

It provides its own abstractions for rendering, reactivity and component state.

That's useful if that's how you want to work.

But it's not the only way to build Web Components.

You don't have to write Lit's HTML template blobs.

The DOM already has an API.

document.createElement("button")
Enter fullscreen mode Exit fullscreen mode

isn't primitive.

It's powerful.

You have the entire browser platform underneath you.

Use it.

Write a one line helper function (sell it to your PM as a mini-Framework)

const createElement = (tag,props={}) => 
                       Object.assign(document.createElement(tag),props);
Enter fullscreen mode Exit fullscreen mode

And you are really using the platform!

Note: That "guru" developer in your team now tells you to make this a library you can import.

Don't! You are creating a dependency!
Use AI to manage your code! It is an AI skill

customElements.define("the-obligatory-counter", class extends HTMLElement {
    constructor() {
        super() // sets and returns this scope
            .attachShadow({ mode: "open" }) // sets and returns this.shadowRoot
            .append(
                createElement("button", {
                    part: "plus button",
                    textContent: "-",
                    onclick: evt => this.count--
                }),
                this._count = createElement("count-value", {
                    part: "count value",
                    textContent: 0
                }),
                createElement("button", {
                    part: "min button",
                    textContent: "+",
                    onclick: evt => this.count++
                })
            )
    }
    set count(val) {
        this._count.textContent = val;
    }
    get count() {
        return ~~this._count.textContent;
    }
})
Enter fullscreen mode Exit fullscreen mode

Developing Web Components

Develop Web Components like you use .reduce():

No developer ever told you that you must use it exactly like they do.

That's the freedom Web Components give us.

There doesn't have to be one architecture.

There doesn't have to be one framework.

There doesn't have to be one correct abstraction.

Build the component.

Give it a useful API.

Let the browser do the rest.


So:

Web Components never failed.

Maybe we just haven't learned how to use them yet.

Browser vendors already showed us how.

Every <input>, <video> and <textarea> is proof that complex functionality can live behind one simple HTML element.

If Browser vendors can do it. Why can't we?



Top comments (6)

Collapse
 
pengeszikra profile image
Peter Vivo •

I’m also interested in web components, so I set out to demonstrate their usefulness.
There is a Markdown editor web component somewhere in my program, too—I think it’s worth checking out.

Collapse
 
dannyengelman profile image
Danny Engelman • • Edited

Yes, I checked out your M A R K E R page
I pasted the contents of this DEV.to post...
Your code needs some work:

<mark-down> is a great example were AI can do most of the work,
because Markdown is an established file format.

My <mark-down> is 2200 LOC because I added more syntax parsing;
which is tottaly fine as long as I do NOT publish it on NPM

I wouldn't be surprised if, 5 years from now, you publish MD on a page,
and a <mark-down> parser is generated ad lib (by the browser)

I learned this lesson from my CDrom adventures in the 90s
Its fine to reduce your 600KB PNG to a 50KB JpegX by hand.
But ALWAYS save & keep your sources, because, one day, the server will do it for you.

Collapse
 
pengeszikra profile image
Peter Vivo •

this program written by hand, so that why so sort ... and unfinished because meanwhile I need to ready the whole program to deadline.

Collapse
 
sgaggjhkjh profile image
Arjun Sharma •

The line that browser vendors themselves have always been Web Component users hit me hardest. Inspecting the internal shadow DOM of a video element once completely changed how I think about encapsulation. I also appreciated the caution about growing a helper into a published framework, because I have done exactly that. Question: for components with richer interaction needs, where do you personally draw the line between staying on the raw platform and reaching for something like Lit?

Collapse
 
dannyengelman profile image
Danny Engelman • • Edited

Of course you will built your own software layer that makes your development easier. If you keep that to yourself/your team and don't become a dependency for others you have full freedom. There will be no breaking changes because they are your changes.
And do steal the good parts from Lit and others and incoporate them into your own code.
Both Picasso and Steve Jobs said "Good artists copy, great artists steal"

Collapse
 
nehznah profile image
zhen •

The line about every being proof really stuck with me. I swapped a framework-tied date picker for a plain form-associated custom element with ElementInternals in an internal tool a while back, and it's the only piece that survived two framework migrations untouched — which I think is exactly your point. Where I still get stuck is SSR: rendering these on the server without a JS runtime still feels like the unfinished half of the story.