When we say "#WebComponents are just #HTML and the DOM", we don't mean that web components just render out HTML to the DOM.

That's what *every other component format does*. React, Solid, Svelte, Vue, etc. They are all JavaScript objects which sit *outside* the DOM, trying to peer into the DOM to make a change. Some do a better job of that than others.

That's not what web components do.

A custom element *is* a node within the DOM.

That gives it unique superpowers. Nothing else can top that.

You may have come across some sort of spicy take like "web components aren't 'components'".

Well here's a spicier take. 🌶️

React components aren't components.

Neither are Solid, Svelte, or Vue.

They are ephemeral constructs in memory which technically have no direct relationship to HTML at all.

As far as the browser is concerned, the *only* sort of component it can be made aware of is a web component. It knows nothing—can know nothing—of anything else.

Here's where things get _really_ interesting.

You could mount React/Vue/Svelte/Angular/etc. "components" inside of web components if you wanted to.

Write <my-happy-react-land></my-happy-react-land> and mount React right there!

Heck, I might even argue that's the only way you *should* use React. Little React "islands" everywhere. It's the only way to fly!

But, again, the browser knows nothing of that. All it knows about are elements inside of DOM trees—whether built-in or custom.

This isn't an academic subject. Whether we're talking about islands architecture, "microfrontends", framework interop, or any other of the various techniques quickly becoming default approaches to ambitious website projects, there's one common denominator.

The days of "I build my sites using [Insert Framework]" are over. The idea of a global <div id="root"></div> and mouting the whole world inside of it is past its prime.

Frameworks should learn to live *inside* of web component-scoped trees.

You can learn how to build web components from scratch which will mount small framework-specific applications. But I'd recommend getting started first with an off-the-shelf solution. Something like <is-land>.

https://github.com/11ty/is-land

I personally would *never* reach for a frontend framework without first encapsulating it within something like this.

That's why I always scratch my head when people talk about a framework comsuming a web component now and then.

I'd flip that script on its head!

GitHub - 11ty/is-land: A new performance-focused way to add interactive client-side components to your web site.

A new performance-focused way to add interactive client-side components to your web site. - 11ty/is-land

GitHub

@jaredwhite this is all super interesting. I’d really like to get familiar with web components, but have mostly stuck with frameworks and meta frameworks.

If you were building a statically generated blog site that had some js driven experiences (like a rich text editor), how would you approach that?

@ThePaulMcBride At the risk of sounding like a broken record…

There's a web component for that!™️ 😆

@konnorrogers is working on a really cool one called Rhino Editor. https://rhino-editor.vercel.app/tutorials/getting-started

@justinfagnani wrapped CodeMirror in an elegant way:
https://github.com/justinfagnani/codemirror-elements

Any editor I might ever use, if they don't supply me with a WC directly, I'll write one to wrap it.

Getting Started

Rhino editor is a durable and flexible editor designed to provide an easy to use out of the box experience while providing hooks and plugins to allow for easy extension.

@jaredwhite @ThePaulMcBride @justinfagnani I also have a codepen-like editor I plan to extract the "editor" portion out of. Its a ~20kb plain text editor with syntax highlighting compared to CodeMirror's 100kb just to get started.

https://konnorrogers.github.io/light-pen/components/light-pen/

"There's a web component for that" needs to become a thing

@jaredwhite @konnorrogers @justinfagnani very cool!

What is the backend/server side story for this like? Just pick whatever and have it render those custom elements?

That’s one of the things that keep web frameworks popular I think. There is a tightly integrated full stack flow. I’m going to have to play around with web components to really get an idea of what I do and don’t like about them!

@ThePaulMcBride @jaredwhite @justinfagnani Right now its per-component specific.

The ones you see here use Lit and can take advantage of Lit SSR.

Base web components from the "platform" dont really have a backend / server side story, so its largely up to the maintainer how they structure their component.

Declarative Shadow DOM is bridging the gap, but if your render functions require JS for things like sizing, obviously you can only get so far.

@konnorrogers @jaredwhite @justinfagnani not what I was hoping to hear, but I’m glad there is progress being made!

@jaredwhite re: frameworks consuming a web component

I think this is actually a positive thing, not something to criticize. Typically I have seen this approach where the app is consuming the web component as a library rather than another framework component. Call it a trojan horse if you like, but it gets folks used to consuming web components which should be the goal.

@McNeely Thanks for calling that out—I definitely do think that's a positive trend.
@jaredwhite @McNeely it also makes it way easier to migrate existing code to web components if you can switch back and forth between them and a framework. Less risk of getting stuck rewriting the whole universe before the one component you actually need at the moment.
@jaredwhite it's possible to mount different vue "islands" (on user action, with intersectionObserver etc.) in an HTML page without is-land (which is great, but unnecessary in this case)
@eQRoeil that's cool. do you mean just manually, or are you thinking of an official tool of some kind?

@jaredwhite manually, for example with intersectionObserver when one of the island element `isIntersecting` : app.mount(element)
```typescript

```

@jaredwhite It's not an Island if the page needs to load a library, which would be the case with React. Native web components, subsisting on their own JS code, are much more island-like.

@heydon @jaredwhite Eleventy Island can pre-render them to a degree.

@zachleat Worked with Vue for about a year and gained experience.

Note also, that the end of sponsorship meant another focus for Eleventy (not sure whether the new employer meant another change OTOH).

@heydon I think the original idea of the island was that it could come with some static markup and then get "hydrated" independently of any other island, if I'm reading @developit's original post right.

I'm not sure what we call it if it's maybe more of a little shell that can kick off a wad of client-side rendering.

@heydon @jaredwhite nit: an island can load a library, it just can't leak any implementation details to the surrounding HTML/page. Its interface must be that of an element with attributes+properties+events.
@developit @jaredwhite Yeah, I'd say the components could load a library and still be island-like. But A single component loading React (which is just its own component interface) seems unlikely or of poor design.
@heydon @developit @jaredwhite this ad has two separate microfrontends so it needs two different versions of react, y’all
@zachleat @heydon @jaredwhite lol yeah, there's still no substitute for good judgement ("no accounting for taste"?)
@heydon @jaredwhite I've really enjoyed not seeing Jared in my timeline
@jaredwhite I think about this 2020 demo I made of an <auto-vue> web component sometimes: https://codepen.io/zachleat/pen/wvMxZYM
<auto-vue> Combines Web Components and Vue

...

CodePen
@jaredwhite Not that I don't agree with the overall goal of broadening the use of web components but I can't help but feel like this is a meaningless parsing of semantics. A component is an abstract concept like a class. Its not productive to give any attention to someone who thinks "web components aren't real components." Web Components is a grouping of technologies not a single thing and even then its not strictly defined.

@jaredwhite Why are web components better? Because they build on the native browser interpretation of what a component is meaning they work in all evergreen browsers. They are interoperable by definition meaning you really can have write once use everywhere functionality on the web.

The end goal should be frameworks targeting web components as a final build product. Vue and Angular (and maybe others I'm unaware of) already support this and its a major advantage for each of them over React.

@jaredwhite @heydon Components are a concept. Nothing is a component. Everything is a component.

@jaredwhite @heydon Web components are just ephemeral constructs in html which technically have no direct relationship to pixels at all.

As far as the user is concerned, the *only* sort of component they can be made aware of a is a rectangle with good borders or margins. They know nothing
—care about nothing—of anything else.

@nmn @heydon OK 😄

But “as a web developer”, I'm not trying to consume and troubleshoot and interact with pixels in my Dev Tools!

@jaredwhite @heydon If you like the debugging experience with web component frameworks you can use that.

Dev tools extensions exist for many UI frameworks any web developers find them easy to use.

The point was discussing what is and isn’t a component is silly. “Component” is concept. Browsers don’t have components. They have custom elements. You can choose to render custom elements or not with your framework of choice.

@nmn @heydon Not sure what you mean by "web component frameworks".

You can write 100% vanilla web components and the debugging experience is identical to what we've always had with HTML, CSS, and JavaScript. It's pretty great actually.

Devs can opt-into using a particular third-party UI framework, and decide they want to install an extension to suport that as need be, sure. But that's not part of the native web platform.

@jaredwhite @heydon Every “framework” renders HTML, CSS and JavaScript. You hand roll your UI components or use third-party JS to reduce some of the tedium.

You were right to take exception to people saying web components aren’t components. Of course they are. But you’ve waded into silly arguments.

@jaredwhite @heydon Let me help you though:
- we should aim to minimize the amount of JavaScript required to make the web fast.
- certain web frameworks like React are 80kb before you even write a single component so question if it’s worth paying that cost.
- for simpler use cases you might able to leverage web component APIs to build UI components without paying the cost for a “framework”.
- the calculus changes based on your application’s size and complexity.

@nmn @heydon Hmm, well I don't think they're silly arguments, and I don't think you've quite unpacked the point I've been trying to make. 😄

For example: Lit is what some call a third-party UI framework, sometimes in the same breath as React or Vue.

BUT…

A Lit component operates on a fundamentally different level than a React or a Vue component.

A Lit component is simply a subclass of HTMLElement—aka a custom element. As such, it is literally part of the DOM from connectedCallback onward.

@jaredwhite @heydon Yes. That’s the silly argument. Who cares if it’s a custom element. It does nothing for the end user.

But, by default Lit uses Shadow DOM. Shadow DOM can’t be server-rendered except in recent versions of Chromium.

By using Lit (in its default state) you’re hurting your users by forcing them to load JS before they can see contents of you custom elements.

@jaredwhite @heydon You could also use the light DOM which solves the downsides of Shadow DOM. But at that point you’re simply using custom tag that let you listen to mount/unmount/attribute changed events.

The downside is that you *need* a wrapper element for every component. And that means “display:contents” some of the times which has a11y issues.

Again, the technology you use to render HTML is pretty irrelevant if you achieve your goals and can ship a fast accessible app

@nmn @heydon *Sigh.*

Declarative Shadow DOM is supported in all browsers except Firefox, and they're prioritizing work on it right now. It's also easily polyfilled (still requiring JS, but that's like a few lines…mere bytes).

I'm about ready to bow out of this conversation to be honest. I don't feel like fact-checking all of your assertions, some of which are just plain wrong.

@jaredwhite @heydon I apologise, I missed that Safari just shipped declarative shadow DOM

Declarative shadow DOM supported on ~85% of browsers by usage. 15% is still too high a number to ship a worse experience to IMO.

Ok it can be polyfilled by a couple of lines of JS. You know what’s better. Plain old server rendered HTML that needs no JS to render.

Again silly arguments, so yes let’s end this discussion.

@nmn @heydon Once a Lit component runs through its internal template rendering process, it will have rendered out some new DOM—except that other Lit components, in fact other web components built _any_ conceivable way, are treated the same as built-in HTML elements. Those elements, living inside the DOM not outside of it, are wholly responsible for their own rendering lifecycle—whatever that may happen to be.

Every web developer should understand these distinctions. It's vitally important.

@jaredwhite @heydon Let’s try to simplify. Why does that matter?

First you have to draw a distinction between lightDOM and Shadow DOM. Which one are you talking about?