Hacker News new | past | comments | ask | show | jobs | submit login
HTML Web Components (jim-nielsen.com)
440 points by goranmoomin 16 days ago | hide | past | favorite | 239 comments

I was interested to see this article explain what `user-avatar` actually did/provided but it never did. Does it just have styles in it? If so why wouldn't I just use css classes?

I also think having a `user-avatar` take a `src` prop makes way more sense than having to add an `img` tag inside it everywhere I use it. In that case what am I saving? What is reusable?

Vue/React/Angular don't seem like they are trying to "replace" HTML (re: "XHTML wanted to replace HTML4, but HTML5 wanted to augment it. HTML5 won.", in the "On The Web, Augmentation Wins in the Long Run" section), they are taking HTML/CSS/JS and building on top of them. If they all used canvas to render instead I might buy that argument but they don't. They absolutely push those technologies to their breaking point but it's nothing short of amazing in my book what you can accomplish with them compared to just HTML/CSS/JS and even "web components".

I was excited when Web Components were first announced but they are incredibly lackluster with no "Batteries included" and feel like they don't really help you build web _apps_ like the frameworks do. Every alternative to the big frameworks (looking at you htmlx) feel like minor syntaxic sugar for jQuery and friends which feels like a massive step backwards and completely the wrong choice for building a web app.

>Every alternative to the big frameworks (looking at you htmlx) feel like minor syntaxic sugar for jQuery and friends


>which feels like a massive step backwards and completely the wrong choice for building a web app.


I mean, I'd agree if by 'web-app' you mean something like google-sheets.

But I believe this whole "anti-react" movement isn't talking about such usecases, but rather against defaulting frameworks and building using them 'from the ground up', where trully all the website actually need is the "sparkling of interactivity on top"

> But I believe this whole "anti-react" movement isn't talking about such usecases, but rather against defaulting frameworks and building using them 'from the ground up', where trully all the website actually need is the "sparkling of interactivity on top"

We absolutely don't have shared language for these things and we aren't always talking about the same things. The thing is there are just vanishingly few places where you only need a "sparkling of interactivity on top". Yes your blog probably doesn't need a full framework, nor does your news site (which is just a blog++) or your marketing web page. But so many other things really do or things break down quickly. Also what your web site needs today might not cover what it needs tomorrow. I've seen a number of "web admin"/backend control panels (customer-facing for config) start simple then grow until they start to collapse under their own weight with just added jQuery as needed. Sure, at the start, htmlx/jQuery might cover all you need but soon you are building custom UI to represent business logic/ideas and managing with that gets very unwieldy. The people that say "all you need is the built-in HTML elements" are living in a fantasy land, try using the default date/time picker and get back to me.

I'm sure there are things I'd agree with the anti-react crowd on (places you don't need a framework) but all their examples are incredibly contrived and feel like the "TODO app examples" you often see for frameworks or learning a language. They don't even scratch the surface of what's needed for complicated apps, they are great to show off the simple things but it seems like the anti-react/anti-framework crowd thinks those simple examples are all you need and that's just silly.

At the end of the day I'll admit I reach for a framework earlier than I absolutely need it and that's because I've built 10's and 10's of sites (web apps) from the ground up and eventually you either use a framework or you end up creating a shitty version of one. So yeah, day 1 I might not need Vue but day 100 I'm sure glad I have all of Vue to build on.

Would this example be considered "trivial"? https://www.youtube.com/watch?v=3GObi93tjZI

But also, you can mix things togheter. You can just use react based app 'embeded' into mpa for when you need that heavy lifting, and the same keep the content part of your app simple.

"But why would i do that, if i'd already use react for some parts, why not every where".

Becuase then it leads to abominations like reddit or facebook, where websites that are basically glorified text forums will use gigabytes of memory, have terrible UX, be slow and will crash your browser if you leave them open for too long.

The wall of HTML soup he shows for facet "component" (time 11.33) is something I don't want to ever see again in professional setting.

Stringly typed logic and CSS / JS somewhere miles away in directory structure making it very hard to reason about.

I very much prefer sticking to small, composable, encapsulated, actual components made in React or sth similar.

That file has like, 60 lines. Calling it a "wall of HTML soup" is a bit disingenuous. But if you REALLY have that much aversion to code, there is no inherent reason why you couldn't split it even more. CSS being miles away is again, just a matter of taste. No inherent reason why you could't use Tailwind for example.

> why you could't use Tailwind for example

To have even more HTML soup? No thanks. Luckily I live in a world of better DX. With styled-components my CSS primitives are typechecked. Hell even with SCSS and CSS modules I have more sane and IDE supported experience.

But this styling lives in your component file, doesn't it? So it makes just as much "wall of [code] soup there as it makes it here". Tailwind was just an example pointing out you don't need a separate your code across entirely different directories, not recommendation of specific technology

I don’t like Facebook but claiming it’s a “glorified text forum” is utterly absurd. Please argue in good faith here

But it is though? I'm not talking about everything facebook provides, but main content page is just a list of posts with with discussion underneath them. Sure, you can embed some media into the it, but still. There is nothing inherently different about structure of facebook post compared to a post on a forum.

And yet, despite everything facebook is doing, the most (and only) reliable way to load new comments under the post is to force refresh entire site. Except it's not easy anymore, because facebook tries to be SPA.

So we gave up simple and reliable solutions in favour of over engineering that doesn't even work. And all that for no good reason, other then being trendy and having an SPA

Inherently different things:

- the social graph underlying every post and content producer (one of the reasons FB introduced graphql)

- the recommendation and advertising algos that are interdependent on the content feed

- the realtime “fire hose” nature of the feed integrating a huge number of disparate data sources

Again I don’t like FB the app and I’m not on it. But even its core product is vastly more complex than a forum.

FWIW I’ve developed social networks and forums professionally; social networks are inherently more interactive. My first real exposure to front end dev was when I worked on a social network. If I had to build the same webapp today there is zero consideration of writing it as a backend rendered application or restricting to only progressive enhancement. It would only put off the inevitable migration to real FE tech.

The things you mentioned are backend dependant, though, not intrinsic to how you render and present them.

What specific aspects of facebook's comment section under post make it that json response is so much better then a html one?

>But it is though?

At some point quantitative change achieves a qualitative effect. I would think Facebook or LinkedIn or Twitter have all reached that qualitative effect to change from being just a discussion forum.

However qualitatively the social functions of these apps present an extra functionality missing from traditional discussion forums. Being able to track users, notifications of the users updates, blocking certain users from being in the message - which is a traditional messaging function not found in discussion forums. Suggestions of people or subjects to follow given on what you have done in the past, weighted based on various algorithms to determine how recent your past activity was and what your current interests seem to be.. I'm sure you could think of a load of other functions that are not traditional discussion forum functionalities.

I don't know if you are doing that intentionally, but you are completely ignoring the context of the argument, which is advocating of mixing and matching statically generated content and using component based spas only where it's needed.

In the parent coment alone I emphasized that I acknowledge that Facebook as a whole provides more then just a forum, but it's core content inherently doesn't differ much from being one.

Moreover, functionality like notifications or suggestions are inherently server generated, as such they don't require content itself to be served in specific way.

Cool what Contexte did with HTMX, but personally I really dislike the amount of data packed into those HTML templates, those hx-get attributes are frighteningly long.

As a counterpoint: I consult for government agencies that have all separately decided to standardise on Angular.

They mostly publish static content: alerts, updates, reports, etc…

At most they might have a single page somewhere for submitting a payment or a simple form.

But because of this JS framework by default policy all their apps end up with extra complexity, extra build steps, and an awful amount of dependency maintenance.

Most of their sites could have been static HTML files on disk.

That's understandable. Though I actually can see some logic in it. It's got to be way easier to hire Angular developers than it is to hire someone who wants to eek out the maximum performance with this lightest-weight approach (and do it in a maintainable/understandable way).

I'll never say Vue/React/Angular are "light" and I'll fully admit we give up some performance for DX (and UX) but it's a tradeoff I think is worth it (I understand if you don't agree).

In the same vein, I know cross-platform frameworks like Ionic/Quasar are nowhere near as good as native apps. That said the skill set you need (and dedication to actually embracing the platform idiosyncrasies) to make _good_ native apps is not cheap or easy. Cross-platform apps might not fit in as well and might be heavier but they allow fewer people to do more with less. Heck, I have a side-business that relies _heavily_ on apps and it would not exist if I couldn't write them in HTML/JS/CSS as much as that makes some people's stomachs turn.

> It's got to be way easier to hire Angular developers than it is to hire someone who wants to eek out the maximum performance with this lightest-weight approach.

I disagree, at least around here. Frontend developers with react/angular experience are a hot commodity and really hard to hire, yet just about anyone from any tech tech can knock out html and some minimal css.

Kind of obvious why, any of the react based frameworks all fail an audit.

Doesn't even make sense to me why anybody uses them.

You cant audit static sites (ones thing I don't like about having traditional linked libraries).

What makes certain libraries auditable? I doubt react was compliant when first came out.

Why can’t you audit a static site? Seems very straight forward. We already audit static sites for accessibility (503 compliance).

Any resources you can point to? Seems like it would be a worthy effort to make other tools compliant.

Definitely something I want to learn about.

What kind of audit are you talking about?

Probably since 99% of websites don’t need to pass an “audit”, whatever that means

I think the future of webdev is a framework-like system that can be added gradually to basic HTML, rather than one which requires that you totally replace it with JSX, etc. from the start. Webcomponents are a huge step towards a time when we can add state managers and things like that without bringing in a monolith all at once.

Some projects require 1% of a framework, others require 98%, but the majority are in a range between 25% and 75% which currently need you to re-architect for a total perfusion of React or a competitor.

Svelte is pretty close to this (at the expense of a build step). It gives you (in my opinion) better ergonomics that React, has no runtime and outputs sites that don’t require JS unless they do.

Sveltekit (its official fullstack framework) even encourages building apps that fall back gracefully for users with JS disabled.

Of course, none of that is to say that you can’t build bloated, badly performing apps in Svelte. Just that you *can* have the best of both worlds, even for simple/static sites.

And I'll happily use such a system once it exists but Vue/React/Angular exist today and have allowed a level of productivity, DX, and UX unheard of with what browsers provide by default. If browsers want to compete then be by guest but FF seems to busy doing next to nothing, Chrome is eating everyone's lunch and giving the middle finger to standards, and Safari is derided for not being Chrome and slow to implement some things (while being fast on others).

I think it's more likely to see some kind of WASM-based replacement take off rather than browsers get their act together. That's not to say browsers aren't improving, they absolutely are, but when it comes to competing with the existing frameworks the only answer so far has been Web Components and it was very lackluster IMHO.

All the things that "monoliths"[1] bring web components ate not bringing, and won't bring in any conceivable future.

[1] There are very few monoliths among the frameworks these days, and apart from React and Angular [2] most aim for rather small bundle sizes

[2] Out if the blue Angular just released version 17 with all the goodies you'd expect from a framework in 2023

> The thing is there are just vanishingly few places where you only need a "sparkling of interactivity on top".

I would say it's precisely the opposite.

Say 97% of work done by web pages and web apps in practice boils down to "render some data available on the server as HTML, then show it to the user". For these cases, putting what amounts to an entire GUI framework written in Javascript on the frontend is massive, bandwidth-sucking, performance-killing overkill.

There are absolutely exceptions. Google Sheets exists. But your project is probably not Google Sheets.

What is this “entire GUI framework written in JavaScript”? React isn’t a GUI framework, even Angular despite being quite batteries included is not that.

I swear the people writing these comments aren’t working in web development?

> try using the default date/time picker and get back to me.

Building my first web application in react currently and this resonated with me on such a deep level.

React is not a framework.

It is a fancy HTML templating library first and foremost and you should use it when you need HTML templates, which means you that can use as little or as much of it as you want.

I’ve built mostly static pages with React loaded and embedded into parts of the page. The webpages would function without JavaScript enabled.

How does the React part of your page work without JavaScript enabled? Are you using a static site generator (or another server side rendering tool) like Next.js?

Fully agree, thanks for elucidating.

IME there’s a crazy amount of strawmanning that goes on with these “anti-react” technologies/cults. Yes of course your html and css static site doesn’t need react. But most of us who are actual software devs/engineers aren’t working on static websites like that!

I think this is a little gatekeep-y. Building static sites is real engineering. When you're building a site that scales in content (for e.g. one that contains thousands of pages that are updated regularly) you need to really know what you're doing. A CMS can help you manage your content, but you need to decide how to build your pages from it. There are things in the React space that can handle a lot of the complexity (for e.g. Next.js on Vercel with ISR), but you need an engineer to make the right trade offs.

I think the Eric Meyer post demonstrates the intention of that much better: https://meyerweb.com/eric/thoughts/2023/11/01/blinded-by-the...

The benefit boils down to progressive enhancement: because an img tag has built in behavior you simply rely on default rendering behavior and provide "augmentation" as needed via your web component.

What's the advantage of this over just using divs for everything, though? If this used shadow dom, I could understand. But custom elements don't even behave like blocks by default. Namespace collisions with custom components are just as bad as class collisions, if not worse since you can't `.myns.button`. Is it just the `connectedCallback` versus some manual method of wiring up elements to their javascript behaviors?

Yup, connectedCallback is a lot nicer than a for loop applying the right code to the right divs.

That still doesn't click for me. Why wouldn't you make the label/slider part of the component itself. It feels like you have the worst of both worlds. You more or less need/expect it to always wrap those elements but nothing enforces that so this seems very brittle to me, not to mention verbose.

They mention not wanting to pass though all those props:

    <super-slider type="range" min="0.5" max="4" step="0.1" value="2" unit="em" target=".preview h1">
We will ignore the last 2 since those are required anyway. How is `type="range"` not the default that you would just set, no attribute/prop needed? Then min/max/step/value all feel like things you could have defaults for and then, yes, pass them through. In forms I'm always pushing towards consistency, I don't want to make it easy to just set random attributes on the underlying element, it needs to be deliberate.

I can believe I'm just missing something but Web Components just seem like extra work with very little gain.

The article argues between the difference of a JavaScript Web component and a HTML Web component, you describing the former, thus the need for JavaScript.

Personally I think the main problem here is client side rendering to begin with, with a modern server side templating library you get a component based structure too and can abstract whatever HTML tags you want in your component before client side JavaScript.

Problem with React is that it is JavaScript first, you always begin with a JavaScript function, but in my opinion the web should be HTML first.

> The article argues between the difference of a JavaScript Web component and a HTML Web component, you describing the former, thus the need for JavaScript.

The article goes on to add a good little bit of JS to make everything work they way they want. They still need JS to accomplish what they want. If you turn off JS things will break in that example.

> Personally I think the main problem here is client side rendering to begin with

I mean unless you want to roundtrip for new HTML segments (aka Liveview or whatever Laravel has) you either need to have client-side rendering or duplicate your rendering logic (in something like both PHP and JS for the fast update without refreshing on each click). I'll never duplicate rendering logic again if I can help it and that means client-side render (potentially with SSR for the first render). It avoids so many bugs/issues.

> but in my opinion the web should be HTML first

This just feels dated to me. I fundamentally do not understand this desire. What do you gain from the web being just HTML? What does that even mean? With a CSR framework you are still rendering out HTML, I don't understand why some people care that the HTML was generated server side or client side. The web has moved on from being just documents, it's interactive and that provides a much better UX.

Sure, the article is incomplete in the sense that it doesn't fully commit to the idea of HTML Web component as opposed to JavaScript Web components, but it is the correct way of thinking about this.

There will almost always be a roundtrip, either to fetch HTML segments or to ask for more JSON data, except for the rare cases you already have everything, because that is the nature of client-server paradigm.

By putting all your templates in the backend you can render them as a whole document or in parts in one go and send them wherever, to the browser, over Ajax or in the email. No need for buggy asynchronous SQL JOINs over HTTP and infinite state handling.

If you always start with a JavaScript function, and all that comes with that, you need a programmer to be able to create the web, but with HTML (and CSS) first you can have other categories of people do that, like designers. And combine that with a library like htmx you can then enhance that experience for interactive parts and still keep everything in the same backend template. And if it still a need for more complex interactive parts a programmer can can add that with JavaScript afterwards. That is a much better division of labour.

And it is not outdated, browser actually excel in rendering HTML documents, that is what they are designed to do, thus it will always be faster to render the HTML document as it is rather than building it on the fly.

And also the core idea of reaching for JavaScript before HTML will result in suboptimal solutions, I have seen so much unnecessary JavaScript code that could have been easily solved with a few lines of HTML. This change of perspective changes how we think and reason about a problem and therefore our solutions as well. That is why the bootstrapping of a "modern" web app has become more and more asinine.

Another problem with frameworks like React, Vue, Angular and et al have is that they have their own lifecycle and that has made the web closed and not open how it once was, closed in the sense that you can't enhance the HTML document from the outside after it been rendered, thus this leads to the assumption that the person(s) who wrote the site is also the person(s) that manages or uses it, that is a bad assumption.

> Sure, the article is incomplete in the sense that it doesn't fully commit to the idea of HTML Web component

What is that, exactly?

> By putting all your templates in the backend you can render them as a whole document or in parts in one go and send them wherever,

All frameworks can do that. Web Components cannot.

> If you always start with a JavaScript function, and all that comes with that, you need a programmer to be able to create the web, but with HTML (and CSS) first you can have other categories of people do that, like designers.

Web components quite literally don't work without Javascript. And they need Javascript to be able to do trivial things like form participation.

> What is that, exactly?

Component rendered before client side JavaScript.

> Web components quite literally don't work without Javascript.

That is why I'm not using them.

> I was interested to see this article explain what `user-avatar` actually did/provided but it never did.

Yeah, the lack of concrete examples makes this feel a bit too much like a shower thought to me.

Lack of substantial concrete examples is an issue with many of these anti-react technologies. Even svelte doesn’t seem to have many (any?) examples of large scale commercial projects using it.

In the last 10 years the only new web tech I’ve seen get traction outside of tech communities - so actual job postings etc - is vue.

This is a purpose of a blog.

This was not a tutorial or an article on how to use Web Components.

I mean, anybody is free to write how they like on their blog. I just don't find arguments like these convincing without realistic non-trivial examples.

What would a non-trivial example look like to you?

I'm working on building exactly this resource alongside a series of posts on web components.

One example would be a search field that shows suggestions from the server while typing.

Here's a pre-built one that I found that even lets you customize the debounce amount: https://ionicframework.com/docs/api/searchbar#debounce

The Stackblitz example is quite good too.

I'll give it shot to build a super simple one with just vanilla JS without helper libraries like Lit or Stencil. I think I'd take the same approach as I would with React, and I think the biggest difference would be where the fetch gets executed. In React you'd expose a prop like "submitHandler", but here I would emit an event from the component (after whatever debounce amount) and expect the caller to attach an event listener to my custom event to perform the fetch.

This is a better and more concrete example of the point made in the article: - https://www.zachleat.com/web/details-utils

The `details-utils` component enhances the behavior of the built-in HTML `detail` component. If for any reason you have JavaScript disabled, then using a web component like this would be just fine because the `detail` component would continue to behave like it always does. If you have JS enabled (or it's finished downloading) then you have an enhanced version of it that has features like collapsing when you click outside of it, etc. That's the part that's reusable when used like this.

That web component from the creator of 11ty is what made the point made in the article click for me. When I first started looking at web components I was like, "this still requires JavaScript and doesn't work without it," and that was the same point Rich Harris made in this article: https://dev.to/richharris/why-i-don-t-use-web-components-2ci...

> Every alternative to the big frameworks (looking at you htmlx) feel like minor syntaxic sugar for jQuery

Have you used htmx? Since it doesn't solve the same problem jquery did (UX for client side JS), the accusation is misplaced. htmx is (primarily) a way of avoiding writing JS by extending the server-side rendered html paradigm to partial pages instead of full page re-loads.

I think he knows that. The comparison with jQuery comes from the fact it is a DOM replacement logic too. Even if the syntax is way better, in the end, it’s still a way of working that scales badly, compared to components which embed their own logic.

htmx shines to add dynamic behaviour on some pages, but is not appropriate to replace a medium-sized SPA in my opinion.

I personally think htmx augmenting a MPA approach is perfect for medium-sized apps.

> Every alternative to the big frameworks (looking at you htmlx) feel like minor syntaxic sugar for jQuery and friends which feels like a massive step backwards and completely the wrong choice for building a web app.

Building an entire web app out of Javascript has been an incredibly dumb idea, and some ecosystems are trying to return us to the roots: most of the heavy lifting is done server-side, and JS is a sprinkle of interactivity on top, like the golden age of jQuery.

Before you bite my head off telling me about apps that necessarily have to be SPAs, how many apps are people using React for when a modern server-side framework would do (i.e. Phoenix Live View)?

I wouldn't put Phoenix in the "would do" pile. That looks like a decent learning curve. PHP Laravel and Ruby on Rails are in the "would do" pile. This doesn't take away from your point though!

The core of the web only need basic HTML with closing tags (and properly shaped singleton element/tags) with the basic grammar (from the specs), utf8 encoded, no script.

It is enough for a bazillion of online services, that without requiring a beyond insanely complex and massive web engine from Big Tech. basic HTML forms can do wonders.

Of course, you can have a full blown Big Tech web app, but don't forget to have a interop portal with noscript/basic (x)html browsers to avoid, at least for critical online services, Big Tech lock-in and unreasonable exit cost.

That said, it may be a good idea to be able to drive the display or not of <table> rules with the default styling (css or hardcoded) from the 2D semantic HTML document attributes (I should check the hardcoded style of links and lynx for <table> rules).

(I am not talking about the abomination of the "semantic" web we had a decade ago)

If you are only doing web as documents with links. As soon as you use any Forms and error back-and-forth you have to either patch over the web stardards, or annoy your users with sub-par functionality.

I don't agree, what you call "back-and-forth" is not negative, actually it appears more like "consistency" to me... and in the end, more than enough for a bazillions of online services and that at a ridicule technical cost compared to the one from Big Tech (not to mention all the corollary issues).

Of course, it is a trade-off, bells-and-whistles from rich GUIs are sexy, but the technical cost of such bells-and-whistles in a web context is grostesquely and absurdely unbalanced compared to what can be achieved with simple and consistent noscript/basic (x)html portals for any pertinent goal of a bazillions of online services.

A lot of web apps fetch data from the server prior to rendering; and the data that's fetched is often necessary for rendering. I suppose for things like a "control panel" that doesn't have much data on it, HTML Web Components might work fine; but a lot of use cases need non-stale server-supplied user data. I guess one other use case is caching stale data in local storage, and rendering that -- but even that requires JS.

Problem is, i dont see a page that does more then a blank text with simple logos to be user frendlly to regular non tech users. People care much more to what they see and the UX at the end, imagine handling all the use cases of a credit card register form before some payment without all the fancy schmancy we have today.

If you don't care about UI/UX then I agree. I do and even if I didn't the companies I work for absolutely do and the customers expect a certain level of UI/UX that is absolutely not possible with no script. I also work primarily on web apps which cannot be done without JS.

Well, it all depends on what the "client" "wants".

The problem often lies with the client tantrums.

I was more talking about critical online services which have a duty of interop with Small Tech and must not force users into Big Tech engines only, that to keep the door open to alternatives of reasonable "size", and at the same time to lower significantly exit costs.

But that's smashing open doors, most are aware of those issues here on HN. The real issue is implementation: it has to happen in a regulatory framework, laws dealing with discrimination, and my lawer has been looking into other legal leverages (yeah, I have an open conflict with my administration). The regulatory framework is here, but lobby-ied heavily by Big Tech, making it ineffective and pointless.

A bit like what they have in the US with the "utilities" which then have much more regulatory duties than "non utilities". You also have anti-trust stuff: dominant corpos are much more tied to regulatory constraints, that to let alternatives to be viable (well, that does not seems to work very well in the US). In my country, anti-trust ultra-aggressive regulations did wonders in the telecom industry.

You can still have a web app with a rich GUI, an anonymous simple and stable in time public HTTP-based middleware protocol (which allows to develop Big Tech independent rich GUIs), etc, until the core functions are provided to noscript/basic (x)html browsers (if one thing must work, it is this one).

No JS makes HATEOAS-like experience easy. Like for example right clicking an object you want to edit to open on a new page, edit it there, and click back and get it loaded as it was in less than a microsecond. Or opening 3 things to edit in different tabs, splitting them across the monitor and working with 4 copies of your app.

Basically, HTML Web Components are classes extending HTMLElement registered manually via JavaScript / DOM API.

  class superSlider extends HTMLElement {
    connectedCallback() {
      let targetEl = document.querySelector(this.getAttribute('target'));
      let unit = this.getAttribute('unit');
      let slider = this.querySelector('input[type="range"]');


For a more sophisticated example with scss, jsx/tsx and ES20.. you could take a look at https://github.com/cyco/WebFun

My personal problem with these "native" components is, that the shadow DOM is pretty restricted compared to component frameworks like React, Vue or Svelte.

I don't understand why people use the shadow Dom. Why not edit the Dom directly?

You are correct. You don't have to use the shadow DOM, when you create a new Custom Element.

The shadow DOM provides two things:

- style encapsulation (as well as `id` attributes)

- ability to use `<slot>` for templating

You should use it if you require one of the above or both.

>"with no "Batteries included" and feel like they don't really help you build web _apps_ like the frameworks do."

Define _app_. React doesn't have batteries, it has composability. Web Components do too but you have to know how (it's a lot easier in React, just return (html)) but in Web Components, you can register your custom element and provide the functionality that you call "batteries". [1] So if you don't care about attributes and just want semantic composable things, just call it whatever you want to. <user-avatar></user-avatar>. Conceptually it's a web component that extends HTMLDivElement.

[1] https://developer.mozilla.org/en-US/docs/Web/API/Web_compone...

I think the confusion caused by this article is because the author presents a false "pick your side" choice: "React-style" custom elements with props, or, custom elements with light DOM. Unfortunately, discussion of web frameworks often seems to occur with tribalistic attitudes, which can obscure a clear understanding of appropriate choices for a given application.

The author's dichotomy could be seen as unnecessarily divisive by creating an artificial distinction and suggesting only one must be chosen. It also seems not to reflect an underlying technical reality nor suggested best practice. In reality, both React and custom elements can enable either style, and the choice should depend on what's most appropriate for the situation.

Not only can both frameworks do both approaches, they can do them at the same time! You can have a wrapper style elements that also takes props. A window-box that provides diverse content with an OS-style draggable-window capability is a good example.

As to the author's suggestion that HTML components (which appear nevertheless to still require JavaScript) are better, and prop-style is to worse, in general, I'll have to think more about it. I may have underappreciated the light DOM style in my creation of Hyphen: https://github.com/00000o1/-

Instead of focusing on slots for templating (which you can still use if you want) in Hyphen, I made templates easy with JS template literals, because it's not always just elements you may want to insert, but rather class names, attributes, and so on. Check it out if you are interested in new approaches to custom elements! It's only 3K and less than 300 lines, aiming to provide maximal utility with minimal code.

> lackluster with no "Batteries included"

I wish this weren't so, but it perfectly describes my experience with every single web technology. JavaScript, DOM, Canvas, Web Audio... they all remind me of this quote:

"Beware of the Turing tar-pit in which everything is possible but nothing of interest is easy." -Alan Perlis

I am of course, slightly exaggerating, but... by way of analogy:

I used a PDF library that didn't automatically flow text onto the page. You had to do it yourself. Line by line. Page by page. So, I wrote a few routines to do it. Maybe 50 lines? And I'm just like... this PDF library is twenty eight thousand lines lines long... and they couldn't have included those fifty?! Why!

Meanwhile, a browser is 10-20 MILLION lines of code, and ... I originally ranted for several pages, but I'll just go and say that I never want to see the string "undefinedundefinedundefined" show up during runtime (and that this is 100% realistic and achievable in a dynamic language, without type annotations).

> 100% realistic and achievable in a dynamic language

Achievable by just removing automatic type coercion. Throw errors instead.

Would need to be feature flagged for backwards compatiability.

Exactly! You put that very elegantly. (I call that proposed flag "use sane")

I always thought JS needed static types to fix the insanity until I tried Python and realized that almost all the insane BS I get in JS are all runtime errors in Python.

There's a very good case to be made for reducing runtime errors, but it's a hell of a good start to at least have them!

Rather than what we have now, which is "assume the programmer is a beginner, who also never makes mistakes", and "given nonsensical commands, just do nonsense, and propagate garbage data throughout the entire program".

At least PDF libray you can update to include new functionality under a new version, but you can't just out of blue change the JS behaviour of undefined being rendered. It would definitely break something without warning.


No need to break existing software. "use strict" was a great idea. Let's do "use sane"!

My take is: As explained in the article, user-avatar does absolutely nothing. If anything, it could only enhance the existing markup (with behavior), but never replace it. It’s… semantic markup, if you will.

Baloney if you ask me.

Yeah I was thinking about what it could do, but I don't get it. The point of custom elements is to define a class in JavaScript that does something. Custom elements are just a part of web components tho, and you can use shadow DOM, more JS, and templating with slots.

I guess user-avatar could define a template that includes styles and slots to turn the image into a round image and maybe add some caption and link to it. But that would still require JS to print the template.content.

React has `props.children`, Web Components have `this.innerHTML`. But also, anything inside the custom tag you can query using regular DOM querying. Here's an example I just created: https://jsfiddle.net/qc35an1s/2/

I actually have zero Web Component experience so I'm not sure if I'm following best practices there, but I was able to get that working pretty quick

Also read these articles for more on the idea of "HTML Web Components":

https://meyerweb.com/eric/thoughts/2023/11/01/blinded-by-the... - "So there you have it: a few thousand words on my journey through coming to understand and work with these fully-Light-DOM web components, otherwise known as custom elements. Now all they need is a catchy name, so we can draw more people to the Light Side of the Web."

https://adactio.com/journal/20618 then suggests the catchy name.

I just don't get the point. They are cumbersome to use, so now you need a lightweight framework on top of the built in framework such as Lit (which btw is larger than Preact). Then they solve none of the real problems like state management, routing, etc... so you'll likely need to pull in more.

Sure you can get re-usable components. But are you going to pull in a re-usable web component that might use say Vue underneath when you use React? It just doesn't make any sense.

I think there's a lot of value for classic server-side web applications rather than SPAs. That handles routing, state, etc. I'm personally a fan and hope that the server-based application renaissance happens as some predict.

Most people using react aren't building SPAs. Vue/React can be used the same way as jquery, which is to add enhanced UI functionality that server-side HTML views simply can't offer.

The best example is a multi-select box, or a searchable select box with autocomplete (what W3 calls the combobox pattern https://www.w3.org/WAI/ARIA/apg/patterns/combobox/) which in jquery was usually via https://select2.org/

For example, on my company website there's a timezone select box with 151 options. Asking a user to scroll through 100+ options is a big ask vs typing a few characters and hitting enter. There really is no static server-side way to solve this problem (I tried hard to think of one)... without creating a multi-page Wizard for what should be a single field on a larger form.

If you're building a SaaS product there are many UI requirements that demand high-interactivity and and there's really no better mainstream solution atm than static-first sites with small "islands" of React/Vue/etc components (ideally with hydration).

People still abuse React/Vue of course and the trend is 100% moving back to "mostly static" rather than slow SPAs but IMO JS-powered components are not never going away unless browsers start offering a broad selection of built-in complex web components like comboboxes, datepickers, tooltips, etc.

The <datalist> element with a text input field is an HTML native typeahead, which works great with SSR or you could wire up the datalist client side with an XHR creating the datalist.

You maybe don't get full control over the rendering style of it, but it's a still significantly more usable than the Angular Material autocompletes.

That's an interesting one I wasn't familiar with.


It's a shame clicking on it doesn't show the options like a select box though.

Click again I guess?

> Recommended values in types text, search, url, tel, email and number, are displayed in a drop-down menu when user clicks or double-clicks on the control.

Clicking it shows the options for me (Chrome 119).

On paper, <datalist> is great but as implemented (or not) in all browsers, it has issues. This post walks through an example of using the element but also summarizes issues (as of June 2023): Under-Engineered Comboboxen?


<input> with <datalist> still doesen't work on Firefox Android.

> Most people using react aren't building SPAs

> People still abuse React/Vue of course and the trend is 100% moving back to "mostly static" rather than slow SPAs

I'm not seeing this at all, in fact I can't remember the last React project I worked on that wasn't a full blown SPA. I don't see anyone starting or advocating for static sites with islands unless they're using a framework like Astro or something.

Do you have any example sites or codebases using this approach?

Not elegant but we use a websocket for search in htmx.

Preact requires a build step otherwise you don't get JSX and you have to build applications a la mithril.js mode:

> const app = h('h1', null, 'Hello World!');

With Web Components no build step is required and you're still able to intermix HTML with JS just like JSX. See the code below this section: https://github.com/kennyfrc/cami.js#key-concepts--api

You can use the htm library as a pure client-side jsx: https://github.com/developit/htm

It is not completely the same, but far better than that h function madness.

State management is only a problem if you have client-side state that isn't HTML state. Lots of web apps don't fit that mould.

I think the criticisms of not solving state management and routing are well taken. I've tried to create a minimal sub-300 line, sub 3KB-compressed micro base class for using custom elements that reduces their cumbersomeness!

I wonder what minimal solutions to state management and routing might look like in Hyphen: https://github.com/00000o1/-

Web components are only useful IMO in the case of a large enterprise which wants to systematically and consistently style a large number of applications written by different divisions in different frameworks in different languages targeting different clients.

I'd add longevity. If your company works for a product where you'll have to maintain the code you write now for the next decades, you don't want to deal with then-ancient abstractions. The JavaScript of a well-written web component should be as valid now as it will be in 10 years, as you're just using the platform.

This year I pulled class-based React component into a greenfield React project. Worked without a hitch, even though its a 10-year difference between approaches.

Meanwhile, "use the platform":

- all form components written before form participation landed in browsers are broken

- all web components written before cross-root ARIA (not even a spec yet) are potentially broken due to shadow DOM

- ... you may continue this list at your own leisure ...

Yeah I don't get the comments either. React has been there for a decade now, is pretty stable and very backwards compatible. You can't really go wrong with it and it's a super lightweight "framework" (I know, it's not a framework, maybe a library would be a better term) all things considered.

The issue is just some sort of "front end bad" feeling at this point, imo. It's like some people think web components are the answer to the popular perception of the frontend being a mess of yearly novelties. When again, you can just use react and could have done so for a decade now.

I really appreciate there being some concerted advocacy for shadowless web components!

So much of the beauty & elegance of the web was how declarative everything is, as that grants such observability & malleability. Shadow dom felt such an enterprise desire, to build much higher encapsulation walls, to layer in so much certainty, and that never felt like a goal I shared.

This article shows how light dom work can compose. I want to see light dom advocacy go further. It always seemed clear to me a web component/custom element could and should just self-modify the dom inside of it, move children around, build new content. Another example in the comments talks about maybe the user avatar element adding a div with the users name... Maybe the page or framework adds the icon, and the custom element then inserts that name, or that name and some aesthetic embellishment.

I guess my one concern with light dom / html web components is it seems like there have been - in some cases - some good performance wins from shadow dom. This wouldn't change what I go for unless I was desperate, but as a dev, in my head I see how shadow dom can scope down and reduce the number of elements that have to be traversed for a css specifier. and I want that win to be available somehow to me.

Really elating to see a lighter take on custom elements / web components. Thanks for the great links Simon!

Could we shorten the catchy name further? Call them “HTML components”.

> they can render before JavaScript. React components cannot do this — full stop

Not a full stop; SSR means they could render before client-side JS.

The example is a bit too simple to make the author's point IMO. A web component that handles changes to state would be a better comparison, and make for a better argument.

Good point, and conversely, web components can't since they must be registered in JavaScript before the side loads.

Hydration solutions exist but are usually worse and come with surprising tradeoffs and harm composabilitiy.

This is the main issue for me with webcomponents, they are not SSR friendly.

Do you want SSR for SEO, or for fast first interaction? Because if the latter, then arguably some form of webcomponents might be theoretically better optimizable by browsers than DOM-element soups.

> then arguably some form of webcomponents might be theoretically better optimizable by browsers than DOM-element soups.

Arguably they might be less optimisable than regular web frameworks, as they make it difficult to coordinate between different components on the page.

This is a good point, but I would counter, perceived speed of rendering from a user perspective is more important than time to interact with the app/site (a reasonable time to interact is however very important.

Good load order and only loading in the content and JS above the fold initially helps a ton.

JS frameworks are huge and I am still saddened that proper tree shaking and optimization got left by the way side in how the modern web has evolved. I worked with google closure in advanced modes and the closure components for a few years and the compiler was absolutely astounding (and the components designed with the compiler in mind) in code splitting, tree shaking and minimization.

Oh, google closure was absolutely ahead of its time!

Consider the approach this article suggests.

You want to have the tags and content appear in the web component (not rendered by JS) which makes it easily and immediately available to crawlers.

You can pre-generate them on the client though.

How would an "Html Web Component" handle state change? I was a bit lost on the benefits given the example of wrapping an img tag. Sure you could group and reuse common elements but you would still need javascript to do anything interactive. Even in the example given the alt text of the image is typically dynamic now because of localization so even then content is missing with javascript.

That’s what JavaScript is supposed to be for: state change. Not rendering the page.

I think I've finally seen the light when it comes to Web Components:


> No Build Steps, No Client-Side Router, No JSX, No Shadow DOM. We want you to build an MPA, with mainly HTML/CSS, and return HTML responses instead of JSON. Then add interactivity as needed.

> Declarative templates with lit-html. Supports event handling, attribute binding, composability, caching, and expressions.

For me, that's the beauty of Web Components. You can find (or build) a base class that works the way you need it. I like a React class component style class with an XState-inspired state machine built in.


Have you tried HTMX before? Seems strongly aligned, with HTMX perhaps having a bigger community. Curious if you have, and found it lacking in some way.

The Cami page already mentions htmx.

ctrl+f htmx

"For folks who have an existing server-rendered application, you can use Cami to add interactivactivity to your application, along with other MPA-oriented libraries like HTMX, Unpoly, Turbo, or TwinSpark."

Replace JSX with a custom non-standard DSL, call it a win.

It's a win because it means no build step. You could also say that JSX is a custom, non-standard DSL.

One problem is that "web components" is not a thing, you don't make "a web component". "Web Components" is the name a stack of three things that, taken together, make up the Web Components API.

You don't really make "a web component", what you make is a Custom Element, which might use a Shadow DOM, and might use an HTML template. Three things of which the most important one is the custom element.

With the core concept being that you're just making "more HTML elements", everything you can do with those, including which attributes and JS API they support, is up to you, and the way you put them on a page, the way you interact with them, the way you listen for events on them, etc. etc. is the exact same as any other HTML element. If you known how to write web pages the "old school" way, then you already know how to use custom elements. You just need to learn how to declare them.

I've recently just started playing with Web Components without a build environment. Meaning, no npm, no bun, no webpack, etc, and no dependencies; in typescript. Intellij can autocompile down to js and the browser view injects a small onchange handler for live updates when developing. So far no problems.

The only thing holding web components back seems to be HTML Modules; being able to link to a .html file instead of a .js file to import a web component. Because of this if you want to use templates or anything more complicated you need to do the ugly inject of .innerHtml = `<tag soup>...`, which I thought would be a problem but the IDE parses the template string very nicely. It would be great to make a component in HTML and any javascript you would put in a <script> tag. It seems like there a lot of bureaucracy involved in getting HTML Modules out the door since its been eight years.


HTML Modules have been deprecated and removed in favor of JS-only imports.

And no, it's not the only thing holding web components back

I'm not sure I buy the "React is replacement, not augmentation" argument. At the end of the day/render, React still renders HTML elements... with javascript event handlers. Wrapping an '<img />' in a React component doesn't mean I've taken away any functionality of 'img'. I just add to it -- augmentation.

Maybe the author has worked in different React codebases than I have, but in my experience, we use built-in browser functionality unless we have a reason not to. Maybe I've just been lucky?

Surely every single web architecture ultimately renders HTML elements, that wasn't the point.

The point is that the flavor "HTML Web Component" does not rely on JS to start rendering, unlike React.

I believe Flutter doesn't (or didn't use to) - it rendered to canvas, and then in parallel built a hidden DOM structure so an accessibility tree could be derived and made available to screen readers.

You’re right for the large majority of cases, but there are exceptions. These days some use canvas or WebGL, in the past some have used Flash or Java Applets/Swing.

A popular app that some web developers here may use day-to-day recently is Figma, which uses WebGL for rendering.

Where does the data come from, if not JS? How then do HTML Web Components start rendering, without data?

The data would come as part of the server response in most cases.

A variation could be the rendering of a partial UI whilst you then fetch data client-side. Even in this case the web component has the advantage as no JS is needed to render the initial UI.

As long as you're not shoving everything into the shadow dom, then you've got a fallback HTML element that can render before JS is read (and even if the JS is completely broken)...


  <img src="/example.png" />

This image will render before the JS is executed, so you've got no blockers and a perfectly fine fallback, then with the web component you enhance your image with whatever JS you want.

I could be wrong, but it seems like the article is saying that the core difference would be this:

React (rendering in the browser, not server side): Page Load -> Component Load


Web Component Page Load -> Default Render -> Component Load

So if someone has JS disabled they would still see SOMETHING for the web component vs. nothing in React. And with JS they could get to some further render state.

In some cases, react seems to go out of its way to make the built-in functionality harder to access. For instance, if you assign "onchange" to an <input>, react will give you the "input" event, not the "change" event. (Actually, it gives a neither. It gives you a "synthetic" event that's closer to input than change) What if you know what you're doing, and you actually wanted "change"? You have to use an element ref an attach the handler using an effect.

You can access the `nativeEvent` property on the event object[0] if you prefer

[0]: https://react.dev/reference/react-dom/components/common#reac...

Doesn't solve this problem. "change" fires at different times from "input". `nativeEvent` is useful if you want the real event data object for the event that actually fired. In this case, it's a whole other event.

it's a well known thing in react (preact does it well https://preactjs.com/guide/v10/differences-to-react/#use-oni...), and probaly a design mistake on their side (now too late to change), I can't think of other cases like that

They could still expose a `nativeChange` event without breaking backward compatibility.

It depends on the architecture of your app. If you're using React to return HTML from the server, then indeed wrapping an <img /> in a React component means you're augmenting an existing element. But if you're rendering the entire thing on the client side, then the <img /> is ultimately inseparable from the React component.

When I read that I thought about the reverse: putting React inside other HTML. In my experience React works wonderfully when you’re using it from top to bottom (replacing your entire page structure) but it can be difficult to fit into an existing structure when you’re trying to do things like server side rendering.

> My takeaway is: if you’re looking for longevity, opt for a technical approach of augmentation and enhancement over replacement.

This is my experience too, and this philosophy have made my web projects last a long time with minimal maintenance and dependencies.

A web component should do ONE thing whereas a JS framework is a whole ecosystem.

I made a video player web component that could take in various inputs, with a torrent file being the most complex of them. I was then able to port it to Vue/React with StencilJS [0] (although it was good to go without). Just drop the `<awesome-player src="torrentOrVideoFile"... ></awesome-player>` along w/ its exported class from `awesomePlayer.js` and you have yourself a copy/paste HTML5 video player that plays torrents!

I also strongly suggest your web component attempt to mimic existing HTML elements, when possible, such as how I used `src` because `<video>` does. That way the consumer doesn't have to RTFM to interact with it.

[0] https://stenciljs.com/

I don't really agree that frontend framework components are meant to be replaced completely and are not composable. Maybe from the outside, but I use slots quite a lot in my components because they are very easy to do and they trivially work. Web Components on the other hand are usually demonstrated as insert <img-editor></img-editor> which basically inserts a ton of code to create some kind of an editor. Using slots in Web Components is a pain, a lot of appending nodes manually, templates as strings, for some more complicated things when I tried them I had to listen to the slotchange event etc. It's essentially the DOM api, which if it wasn't terrible, we wouldn't have switched to frontend frameworks like react etc.

Also disagree with the side note that XHTML failed because it didn't augment HTML. IMHO it failed because if forced the applications to be completely valid and it put the validation on the client/browser. If you'd really used real XHTML a small error in the markup would've crashed your page. So we all validated our XHTML to be future ready, but it was always utopia that a business would risk crashing their, well, business because a p tag was not properly closed.

Apparently not widely know, but…

> Svelte components can also be compiled to custom elements (aka web components) using the customElement: true compiler option.


This would negate the "vendor lock-in" arguments and allow Svelte for component development but web component for consumption and use. Best of both worlds. All the DX advantages of Svelte over web components without sacrificing interoperability.

I believe some people generally avoid Svelte for custom elements since Rich (and other maintainers) have consistently shown criticism towards Web Components in general.

Any examples of the web component code they spit out?

> <user-avatar>

> <img src="https://example.com/path/to/img.jpg" alt="..." />

> </user-avatar>

I thought the standard way to do it is:

<img is="user-avatar" src="https://example.com/path/to/img.jpg" alt="..." />

That is one way to do it, provided `user-avatar` extends HTMLImageElement and not the more generic HTMLElement. Extending built-ins and using the `is` attribute is not supported in Safari however and last I checked they were firmly opposed to it.


There is a polyfill for customiziing built-ins on Safari.


They're different things, though with an extremely simple component they might achieve a relatively similar goal. The downside of `is` is that you can only specify a single element to map to the component. An example of why you'd need to take the slotted approach is if you had something like this:


<img slot="image" src="...">

<div slot="name">Bob Bobson</div>


There’s almost no standard way to do anything when it comes to html style.

With the massive caveat that I'm not a web developer or react developer, doesn't this stuff just look XML? I know html is a subset of XML but this stuff looks more and more like the XML that everyone complains about.

Edit: I'm meaning the attributes being longer than what the tags are denoting.

Does HTML kinda look like XML? Yes.

Doesn't this create some nasty coupling since your web components look like a div but can actually require an arbitrarily complex HTML schema underneath? Can I write that down somewhere?

If things like slots are used, it isn't necessarily nasty coupling. But I agree this approach does make more a more complex tree structure than something you would see in a typical JSX/TSX file.

That said, I think the author's bigger point was that augmenting, rather than replacing/abstracting away basic web elements will win out long-term. Some degree nastier-looking coupling is a worthwhile trade over more opaquely-operating render libraries. I suspect augmented web components fail more gracefully too.

Yeah that is my confusion too. The nice thing about react components is that I don't have to remember to write all the div elements inside them, but from this example I do.

We've abstracted away <DIV> soup

*Shameless self promotion warning*.

If you're looking for a middle-ground between React and Web Components, check out Joystick [1]. I designed it to take a React v1 approach to ergonomics but you write your components with vanilla HTML, CSS, and JavaScript (no attribute hacks or new syntax to learn—if it's on MDN, it will work in Joystick).

[1] https://github.com/cheatcode/joystick

Maybe it is just me but for me web-components were never able to deliver what they promised or a viable solution for a simple reason: i18n/translations. As a European freelance web dev, I've virtually never been in a project where we develop single-language UIs - its always at least the national language plus English. Those translations can't reside within a "component" itself for a simple reason: Translators push you to always share translations across components to achieve consistency throughout your UI. Now with react-intl or react-i18n-next those translation strings will live in a single or just a couple of files for the whole UI, and be provided through a react Context. It is also one of my pet peeves when people talk about "independent, self-sustained components". That is just not a thing in UI land, in most bigger projects each component has quite some external dependency from some form of enclosing context (translations beeing the most common one). In the article, user-avatar is probable one without any text at all, but thats the minority of components.

I'm from inlang and we're building an ecosystem around globalization. Recently, we have released paraglideJS – a typesafe, super lightweight library that works with every framework. We've received a lot of good feedback in the last couple of days, feel free to try if it satisfies your purpose: https://inlang.com/m/gerre34r/library-inlang-paraglideJs

@lit/localize (https://lit.dev/docs/localization/overview/) give you the same DX of react-intl, but for (lit-powered) web components

Web Components are highly versatile. I built a chat app with GitHub OAuth login, blockchain-based authentication and access control using only 120 lines of HTML in a single .html file with no custom code, no framework, no custom server-side code. It can run anywhere:


You can try the app here (if you have a GitHub account): https://saasufy.github.io/chat-app/

The backend is serverless built using Saasufy.com - The platform/startup I'm working on currently: https://saasufy.com/

An effective approach I've found is to create components which consume slotted <template> elements to produce HTML that can be fully customized and injected with data they loaded from a back end. This allows you to create components which are declaratively bound to specific back end resources.

> ... with no custom code ...

Except all the custom code in saasufy-components

It's generic code, not specific to the application as it can be reused for any application. There is code behind native HTML tags too but we don't say that writing HTML is writing code, the browser handles that.

We use web components in our project (a reactive Python notebook that, among other things, lets users build simple web apps [1]) to make it easy for the user to instantiate and compose our UI elements. Users can easily interpolate these elements into markdown, for example, since their representation is just HTML.

[1] https://github.com/marimo-team/marimo

As someone forced to use an in-house library of html web components at work,I will opine, run. Run at full speed away from the shadow DOM. It's cumbersome to work, poorly supported in testing tools, and web components themselves are a pain to deal with when your use case doesn't perfectly match the original build.

I'd like to like them, but, no.

Hugs to you brother. I am in exactly same boat.

The encapsulation coming with shadow DOM can be done in other ways (CSS modules) so light DOM seems a like saner approach... but then you lose the slots and they are must have for any composability.

My first book on Javascript was "DOM Scripting" by Jeremy Keith. He is still at it, pushing progressive enhancement, making HTML more useful with JS. I love this.

> React components cannot do this — full stop.

Render your react components on the server and send them over the wire as plain html. no client side javascript required — full stop.

Or You could instead use this magic thing that has been around for decades, has massive tooling and most importantly, doesn't lock you into one specific ecosystem of language that was never supposed to be run server side to begin with;

Html templating

That's exactly what React is though?

Rendering react on the server isn't some magical hip technology. It's just a different template framework. I'm not pretending this is anything special or fancy.

Technically you're still running JS first, just on a different machine.

So just run javascript before your components render so you don't have to run javascript before your components render.

If you find a way to deliver a website without running any code, let me know!

I just think SSR is kind of missing it because web components allow a static frontend bundle to have a power that was previously reserved for SSR or HTML-only apps.

Moving the render off the client is nice, but removing the prerender altogether is something much cooler.

If you have a static frontend bundle, isn't that just SSG (static site generation)? And if you can generate the site at build time, what's the fundamental difference between any of the non-web component SSG solutions and a web component SSG solution? Sure, you can pretend like there will be "no build step". But only if you're fine with "no proper cache headers" (and a long tail of other things). So in practice - hopefully there _will_ be a build step anyhow.

Have a HTML page that you just send. It’s really simples.

Send like in the mail on a USB stick?

You don't think code editors use code?

Websites with ads should take notice of this.

> Render your react components on the server and send them over the wire as plain html. no client side javascript required — full stop.

Doesn't this then require the server to be written in Javascript as well?

Why even build a component, when it is an image which could have styles applied using a class? I understand web components appeal when building complex elements, but this probably just slows down website, especially when element is repeated hundreds of times on page.

It will be nice if/when these components can also be defined within HTML

<template type=component name="user-avatar" parameters="[src,alt]"> <img src="{src}" alt="{alt}"/> </template>

A problem I faced recently with web components using shadow dom is styling nested components within custom element:

From <user-avatar> we can give styles to <img>

<user-avatar> <img src="https://example.com/path/to/img.jpg" alt="..." /> </user-avatar>

but not anymore when its below <picture>

<user-avatar> <picture> <img src="https://example.com/path/to/img.jpg" alt="..." /> </picture> </user-avatar>

I recently used Web components to make a fairly complex form. It works well, but I am absolutely building the entire DOM tree inside the component in JS. The component relies on a bunch of tags being in the right place in the tree, with the right id. If the tags were specified by the HTML then there's too much opportunity to get it wrong. Templates might be do-able but there's no convenient way to add a template to a script file, or specify a template in JS (I guess this is why JSX came to be).

I definitely feel like I'm doing it wrong, but all the guidance I see doesn't help - they're all very "hello world" examples that don't get into the difficult stuff.

What's the preferred way to version web components since their name is global and you can't risk breaking old usages when you introduce a breaking change? user-avatar-v2? What's todays suggested practice?

It's a nice idea and I'm glad we can expand the language to differentiate between html web components and javascript web components. That's important because the vast majority of use of web components are in the form of javascript web components. The only time I've ever seen HTML web components are on blog posts talking about how you can use web components. Never on an actual website about something besides web components.

I want to believe... but reality is stacked against HTML web components. I'm just going to stick to HTML and leave the HTML with dashes to others.

I’ve made a couple of big SPAs that use Lit to manage views.

I can’t link you to them here without blowing my cover, but honestly I love working with web components, and being able to do it natively rather than propped up by a mound of JavaScript feels good.

You're not doing it natively. You're using a framework replete with its own custom DSL, multiple workarounds for issues like SVGs, its own data binding system etc.

It's just as native as any other framework under the sun.

Sorry, I’ve been working with web components since before they had wide browser support - so now, it’s ‘native’ in the sense that web component is a feature native to the browser, instead of being shimmed / polyfilled in. You can just write web components in an .html file, drag it into the browser, and it works, no build step or servers or external libraries required.

I do use them on my OSS work (https://github.com/mickael-kerjean/filestash/tree/master/pub...) since I've started migrating away from React to VanillaJS. The app itself is a file manager for every possible file transfer protocol there is (FTP, SFTP, S3, NFS, SAMBA, ....) and is used by many thousands of people

> but reality is stacked against HTML web components.

Because they don't exist. "HTML web components" are just HTML, and you don't need components for them.

Web Components are useless without Javascript.

This is what I do with my web-component framework:


The website itself also built with web component

I don't like web components because of the flash of undefined elements[1]. Hiding it with css tricks is clunky and ugly too. The sad thing is that web components seem like a great idea otherwise.

[1] https://www.abeautifulsite.net/posts/flash-of-undefined-cust...

web components are the quantum realm of CSS. What you know as normal might not work when you're trying to write style customization. My org has multiple teams working with different stacks, so at one point someone decided to write our component library using web components. Everyone hated it and we're now moving away from it.


Here is my blog post about custom HTML Elements. It covers state changes, etc.

P.S., I am looking for a Front End project, preferably writing vanilla JS. My email is on the page.

I always saw web components as the missing leaves to the root that CSS frameworks embody.

For those who read to the end... Angular still uses XMLHttpRequest and not fetch, IIRC.

Funny, huh.

No one is forcing you to use the Angular HttpClient though. You could just as well use fetch.

As of 2023, fetch() still doesn't support upload progress.

when is ‘composability’ getting added to the dictionary?

it is a pretty intuitive term - interoperable building blocks in areas that suffered from fragmentation - but isn't really part of the lexicon by the lexicon gods

React Component is a function.

HTML web component is NOT a function.

You don't just compare those things, they work and compose differently.

I would rather combine them: A html web component renderer for React.

So when react components were classes they were comparable, but now that react components are functions they are not?

A class is a closure ?

    function Dog() {}
    var dog = new Dog();
Hey look classes are actually functions, now you can compare them, have at it.

I think this article is emphasizing custom tags / code reuse as the primary feature of React, which isn't really the case? The whole reason React was a game changer was because it eliminated (as much as possible, anyway) the invisible extra state stored in the DOM from your app and made its rendering declarative, which greatly reduces how much state you have to keep in your head when reading and reasoning about your app UI logic.

Web components don't address this on their own, which is why a lot of libraries still exist that build on top of them.

>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.

I wouldn't say that React's component model is being ported to the browser, just that a component model is being implemented in the browser, independent of and different than React.

Microsoft ActiveX Dynamic HTML Behavior Components (HTC files, introduced in IE5, after DHTML finally started working well) allowed you to augment HTML in the same way, and that's very old technology (circa 1999 or so) compared to React.


>[...] At the time that NSAPI came around, JavaScript wasn't really much of a thing, and DHTML didn't exist, so not many people would have seriously thought of actually writing practical browser extensions in it. JavaScript was first thought of more as a way to wire together plugins, not implement them. You were supposed to use Java for that. To that end, Netscape developed LiveConnect.

>Microsoft eventually came out with "ActiveX Behavior Components" aka "Dynamic HTML (DHTML) Behaviors" aka "HTML Components (HTCs)" that enabled you to implement ActiveX controls with COM interfaces in all their glory and splendor, entirely in Visual Basic Script, JavsScript, or any other language supporting the "IScriptingEngine" plug-in interface, plus some XML. So you could plug in any scripting language engine, then write plug-ins in that language! (Easier said than done, though: it involved tons of OLE/COM plumbing and dynamic data type wrangling. But there were scripting engines for many popular scripting languages, like Python.) [...]

HTML Components:


HTC Reference:


I used them to implement nested piemenu components in a way that let you easily augment them with html in the browser (which was the wall I'd hit with OLE, not being able to easily use an animated gif or html table as a pie menu item, for example, having to draw everything myself with Win32), so you could embed snippets of HTML to define the menu background, center, items, and dynamic feedback.

That worked nicely in conjunction with XSLT to transform XML models into HTML pages with embedded trees of HTML components.

For example, the Punkemon Pie Menus used an XML database of Punkeland regions and Punkemon characters to make a tree of nested pie menus.

JavaScript Pie Menus - Punkemon Pie Menus:


Pie Menu ActiveX Behavior Control (htc file as text):


Punkemon Pie Menus XML Database (xml file as text):


XSL Style Sheet (xsl file as text):


For example the XSLT transforms the XML Punkemon database into HTML with embedded nested <piemenu> <item> and arbitrary html, like a table inside one of the items to make a gigantic pie menu item at the bottom, whose purpose is more like an info panel than a menu item, just showing you some information about the magnified animated gif of the character in the top item.

ActiveX Pie Menus that "hit the wall" (discussion near end of video):


>Well, I ran into a wall of complexity with this ActiveX control, and I wanted to be able to have as the menu items animated gifs, mpeg movies, fonts with nice attributes, and things like that. The first thought was "well let's just put a web browser in every item!", but that was a little heavy-handed. So instead I put the pie menus into the web browser as dynamic HTML components, which I'll show next.

All this stuff I explained in the video is incredibly obvious now, but it seemed really cool at the time in 2001, and it was a hell of a lot better and more web-centric than binary OLE/ActiveX controls. (Pardon my unabashed XML and Microsoft technology advocacy, but it really was a step up from what came before it, and you couldn't do anything remotely similar in Java!)

But it illustrates that the idea of augmenting and embedding html in components like that goes way back, and that HTML Web Components were obviously influenced by Microsoft ActiveX Behavior Controls more than they were React.

JavaScript Pie Menus: example of augmenting neste piemenu components with html:



Now the really convenient thing for user interface designers is that the way these pie menus are specified in XML markup language.

This test pie menu has eight items here, and North has a sub menu with four items. Now that map's very nicely into an XML tree. It has a piemenu element, and that has a name and ID.

The neat things is that you can put arbitrary HTML inside of the XML, and that is just copied and just dumped right into the middle of the menu to make it look any way you want. And then the menu, this pie menu item, contains, besides this stuff to display in the middle an item, an item.

It contains eight items, and this item's name is north, and that's its name to the program, which could be different, and that's what is displayed to the user here. Now it contains the sub piemenu, which is the North menu, and has even more.

You can see how you can intersperse XML and HTML to specify all this that you need to describe for the pie menu.

One of the really great advantages of using XML for the piemenu is that there are many ways to generate XML and many things that are represented by XML that you might want to make and then use for. In the case of the punkemon pie menus I really didn't want to make all those pie menus directly.

So maybe I'm making a card game and I have this XML file that I use to print all the cards and maybe do the online game and everything. I've defined the markup language for punkemon cards. There's the punkeverse contains punkeland where they live, and that contains a bunch of punkemons.

Now all these give information that is needed to make the menu for that. It's an application specific markup style, but it has information for menus in it. Basically all this gets translated into all this very automatically by an XSL stylesheet.

That's a macro language for XML that takes the nice clean to the point punkemon xml file and then transforms it into a piemenu tree and a web page that pops that pie menu up.



    <?xml version='1.0'?>
    <?xml-stylesheet type="text/xsl" href="punkemon.xsl" ?>


        name="Rave Caves"

          foundin="Rave Caves"
          attacks="Disturbing Cuteness, Pacifier attack"
          likes="Candy, Stuffed Animals, Loops"
          dislikes="Ambient music, spankings, bed-time"
            The youngest and perkiest denizens of the Rave Caves, Candibis                                                                                                                                
            spend much of their time spinning around in circles with one                                                                                                                                  
            hand high in the air and the other hand tightly clutching a                                                                                                                                   
            large stuffed animal. Naturally shy, these cuddly creatures                                                                                                                                   
            can often be enticed into a Punkeball with large amounts of                                                                                                                                   
            candy, especially if the candy comes in perforated sheets."                                                                                                                                   
        </punkemon> [...]
The header of the punkemon.xml file says "hey this is my stylesheet, if you want to display me, run me through this style sheet!" And what that style sheet does is expand to a web page with a title that says what it is.



    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
      <xsl:template match="/">


            <TITLE>Punkemon Pie Menus</TITLE>


        <DIV ID="Barf"></DIV>

        <DIV STYLE="width=100%;height=80%;behavior:url(piemenu.htc)"

            <H1>Punkemon Pie Menus!</H1>
            <IMG SRC="Punkemon/island.jpg"/>



                Pie Menus

              <xsl:for-each select="*/punkeland"> [...]
And then, the nice part is, this is how a web designer puts the pie menu on the page. You make a div, which is like just a section. And I'm giving it a width and height, and I give it a behavior.

The behavior attaches this JavaScript code to it and allows it to receive input events and translate them to a higher level semantics and then send these output events like the pie menu changed, and it's going to call my JavaScript function that's on this web page to handle it.

Now this div is the thing that's presented on the page that you click on, so it's got a little picture of the island there. Inside the div besides its presentation is an XML data island, which is just embedded XML that instead of being displayed on the page is just data that can be referred to.

The pie menu looks in there, finds the XML, pulls out the pie menu definition in it, and uses it. You can pack these things nicely together. You can also point to another file that contains the pie menus externally. But in this case we're going to have them inline.

The Punkemon piemenu contains the words "Punkemon Pie Menus". And then it uses the XSL macro language to loop over all of the punkelands, making items for each one of them. And that item is made by extracting fields from that punkeland, and just sticking them into HTML as either properties or content.

You can get the value of the name of this guy and stick it into that guy, and put a bold marker around it, and make a div. This is just a bunch of nested loops that loops over the database and renders it out as dynamic HTML embedded in a piemenu tree embedded in a web page.

And it works! That's what you're seeing over here.

There's a lot of other really neat applications of automatically generating the piemenus or any other kind of user interface from an XML specification, that could also be used for a lot of other things. And you're just describing your data in one place, and then algorithmically rendering it out to all sorts of other things.

> This feature of web components encourages a design of composability.

I am not a React, Vue (and friends dev) at all. Heck, I haven't done front-end or full stack for a long time now.

However, taking React as an example, where does it not encourage composability?

I like Web Components. I even spent the last couple of weeks playing only with the vanilla APIs (no Lit, etc.) just to see what is like:



Like many other people have pointed out in this post, it is great that you can leverage the platform. All the things you will learn e.g. DOM APIs, native elements and events, etc., are things you can carry over to React and Vue.

However, I believe articles like this fail to acknowledge the contribution React and friends brought to developer experience.

Building complex desktop like UIs was no longer impossible to maintain. You can easily make components and compose them, customise them, etc.

The general complaint is more around "you don't need Next.js" to build a news/marketing/blog website. The pendulum is swinging, especially with things like HTMX gaining traction.

IMO, people do it because:

- It's easier to hire developers that know the framework du jour

- Custom Elements are very flexible, so it's hard to enforce a particular style

- There aren't enough examples of people using vanilla Web Components (and I mean vanilla, not Lit and friends), so why use a web component framework when I can use a react based one?

Write more about how we can combine things like Custom Elements and "traditional" server side templating.

Write more about how a native element reacts to changes to its attributes or how it communicates user interaction and how that helps building a good custom element.

Or how building a good custom element is similar to building a good React component, and where it differs.

Antagonising existing knowledge or even the status quo is not constructive, and leads to poor discussions e.g. "Web Components is a failed technology" or articles like OP

I'm a backend php dev who is hopelessly behind on the frontend literature, so here's pseudocode for how I would like web components (dynamic tag definitions) to work:

      <my_tag $message="Hello, world!">
          setTimeout(function () { alert("Boop!"); }, 10000);
        <img src="my_image.png"/>
    <tag src="my_other_tag.html"/>
      <!-- shows "Hello, world!" -->
      <!-- shows "Hello, override!" -->
      <my_tag message="Hello, override!"/>
By default, the browser would allow setTimeout(), so the user would see alerts showing after 10 seconds. But there should be a custom script.js that works like stylesheet.css that the user can set for the browser. It could have a line like quitTimeout() which would disable setTimeout() for all pages. And something like setScriptLifetime(5000) which would run Javascript for 5 seconds in this case, preventing the alerts, then only allow new scripts to run upon user action. Or even have an option like setScriptLifetime(5000, 0) where the second argument sets a lifetime for new scripts, in this case preventing all future scripts from starting.

That right there would make browsers run about 1000 times faster regardless of how many tabs are open, as well as stop most of the slowdown from ads.

Maybe <tag> should be <tag tag="my_tag"> to make it inline. Or <$my_tag> so as to not confuse new tag definitions with existing tags. As they say, the devil is in the details. But I think it makes sense to nest the tag definition in case <head> or <script> tags are needed, which would maybe get installed in the parent page. And there are endless use cases for passing variables to/from tags which are beyond the scope of this comment. Probably that would happen through data tags, passing JSON or raw Javascript like for onclick="alert('Hello')" where myTag.data = 1 + 1 would be like re-rendering with <my_tag data="2">.

But if we had something like that, frontend code would end up several orders of magnitude smaller, because we'd get back to declarative interfaces with progressive enhancement, more like what Htmx is working towards.

Keep in mind that I thought of this in 1995 when I very first saw NCSA Mosaic, and was flabbergasted that html tags weren't dynamically defined this way. When Netscape copied Mosaic but failed to fix even the slightest oversights like this, I knew that the future of the web was in perile and that we'd end up with the imperative stateful mess we live with today.

I didn't have to read very far:

> ...they can render before JavaScript

what? Because web components are written in and run on magic?

> a design of composability... composing core content with HTML and then wrapping it in a custom element that enhances its contents with additional functionality

Put aside the self-reference, that's not what composability usually means, but I guess that sounds fancy to the uninitiated

I can't tell if people who champion web components don't understand why the React model took off, or purposefully pretend to not know why since web components don't really solve most of the things people using React care about, and thus look bad in comparison.

This article is a good example of this. For starters, the "one shell component" thing is kind of a red herring. There's plenty of React components that interact with children, and you can clearly make web components that also "hide all the details". So this seems to be more of a "general" good practice they want to encourage, than anything specifically tied to React or Web Components in particular.

Critically however, the whole idea of "hey, web components still look good before JavaScript!" is either intentionally obtuse or really misses the point of React -- React can have a better non-JavaScript initial render, thanks to SSR, which is significantly harder to do with Web Components. I don't really care if <user-avatar><img></user-avatar> "falls back" to some lame Web 1.0 rendering if my SSR-ed UserAvatar looks identical to the fully "active" component on first paint before any JavaScript runs. That is one of the main selling points of React and React-like systems today. You can't just ignore that completely and expect to convince anyone who's currently using that sort of system. But I understand why they don't address it, since the only real answers involve using some sort of build system with Web Components, which they've also decided to say are the worst thing ever. So their only choice is to compare non-SSR Web Components to non-SSR React Components. And, I dunno, maybe they're better than the way we did things 8 years ago when that was the case? I'd have to think hard about that purely academic question.

The funny thing is that these are often the same people that would push for as little JavaScript as possible, and yet Web Components are fundamentally tied to JavaScript. Whereas React-style components can actually generate fully static JavaScript-free pages if you want to. This sort of situation springs up a lot: Web Components go on and on about not being "shells single components", and yet React-style components make it so much easier to deal with children. You aren't forced into the ugly slot system which immediately removes the "illusion" of it being a "real" HTML component, and is easier to deal with in the catch-all case too. Not to get into another huge differentiation, but I also personally prefer a more "functional" approach of writing a single render function vs. dealing with a bunch of lifetime callbacks to track the changing states of attributes and children.

Most people just don't know what they are talking about. I think the only way that web components would be winning is if they were designed around a single render function to replace react but of course then the entire react/svelte/etc community would be crying out because they can't compete with a natively implemented virtualdom so everyone would have to switch to web components. But isn't that the point though?! Making life exponentially easier for developing a web application?! We shouldn't have to need all these extra frameworks like react, the browser could simply give us a blazing fast virtualdom and then everyone uses that and gets on with their lives.

You only get two things with web components: 1. style isolation (imo everyone will switch to @scope because shadow dom is unwiedly to use, even me probably) 2. the tiny nice advantage of being able to querySelector("my-element") and being able to actually call instance methods on the thing that it gives back, directly. Dont really need that very often though, it just feels super nice.

The argument for web components is really meager and the tooling is far worse, like you said: SSR is missing, autocomplete IDE support for elements and their attributes is missing, bundling and minification is missing for the html templates and you have to do it all yourself. People are now showing off unminified js and ordering their imports manually like it's 2011 again and act like that's good. No of course that's not better than what we have. lit.dev is okay partially because I think the fact that they use web components is almost besides the point, it's just a single render function like you have with react again.

I am more a fan of the augmented style because it doesn't entrap you in dev lock-in to platforms.

The problem with frameworks, especially web frameworks, is they reimplement many items that are standard now (shadowdom, components, storage, templating, base libraries, class/async, network/realtime etc).

DOM rendering speeds have been improved due to virtualdom but is no longer needed with shadowdom.

The web standards of today are amazing and take away the need for frameworks today: from templating to html templates [1], vanilla javascript with classes [2] and async [3] and better api access like fetch [4] and browser support for vdom with shadow dom [5], components with WebComponents [6][7], css now with lots of additions like variables [8] transitions[9]/animations[10], flex and media queries, canvas/svg/etc for interactivity, and so much more. There is little need to use frameworks except to sell books and conferences and keep developers locked in.

React for instance jumped ahead and front ran WebComponents and ShadowDOM, those are both part of the browser and standards now. The killer feature phase of React is over.

If you like the component style of other frameworks but want to use Web Components, Google Lit is quite nice. [11]

Google Lit is like a combination of HTML Web Components and React/Vue style components. The great part is it is build on Web Components underneath.

[1] https://caniuse.com/template

[2] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

[3] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

[4] https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/U...

[5] https://caniuse.com/shadowdomv1

[6] https://caniuse.com/custom-elementsv1

[7] https://developer.mozilla.org/en-US/docs/Web/Web_Components

[8] https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_c...

[9] https://developer.mozilla.org/en-US/docs/Web/CSS/transition

[10] https://developer.mozilla.org/en-US/docs/Web/CSS/animation

[11] https://lit.dev/

But if you introduce an open-source dependency to make web components usable, why not use a popular, complementary ecosystem like Vue?


Staying closer to web standards is always best for maintainability and portability. I personally like custom direct standards but that doesn't always work in a team for some reason today. There will always be less dependencies in a straight standards solution, that makes for better maintainability and opsec. I also think it is better for web developers to know standards over just abstractions, it makes for better developers.

Additionally, web standards like Web Components/templates/custom elements will always be faster at browser level.

The article from OP mentions this:

> But the unique power of web components (in the browser) is that they can render before JavaScript. React components cannot do this — full stop.

There are other reasons as well but these are the best reasons.

I think using a framework for a team isn't a bad idea, but for products and personal projects I like going custom or newer framework like Lit simply because of the web standards being less abstracted away and due to that, less need to constantly update on others schedules due to dev lock-in. There is less weight in straight standards.

If you remember React/Vue originally won due to virtualdom and being small parts that work into an existing web, but recently they have been very monolithic in that they take over the entire project. The web is more about augmentation as the article mentions and I agree, those items will be easier to maintain.

> Staying closer to web standards is always best for maintainability and portability.

I understand that argument, but Lit isn't a web standard, and it's an esoteric choice compared to Vue, which works great with custom elements.

Yeah agreed, that is why I said "if you like the component style of other frameworks but want to use Web Components, Google Lit is quite nice"

Lit is just a lighter weight version of that and closer to web standards without having it bolted on to a larger, almost monolithic framework now.

I still prefer direct and custom with less dependencies but Lit is somewhat trying to communicate web standards while other current frameworks really want lock-in to the platform rather than caring about making sure devs understand the standards.

> Staying closer to web standards is always best for maintainability and portability.

That's what you get if you chose literally anything but web components. Because web components are really bad at using and playing nice with web standards: https://threadreaderapp.com/thread/1717580502280867847

They need dozens of new web standards to fix their self-inflicted wounds and to work with the browser in a way that everyone else is already working

> Additionally, web standards like Web Components/templates/custom elements will always be faster at browser level.

[citation needed]

The 2010-era design choices that web components enshrined hinder a lot of optimizations that modern frameworks are doing.

There are reasons why almost none of the modern frameworks use web components as the foundation. Including those who originally used their design or whose authors were bullish on them (Vue, Svelte, Solid).

IIRC even Angular beats Lit in benchmarks now.

I mostly agree but Web Components is a web standards as is templates/custom elements now.

The others like React/Vue/Svelte etc are all going more for platform/framework lock-in over making sure people are doing augmentation of standards.

Those frameworks have incentive to lock you in while standards are lock-in at a lower level.

Other standards I like playing with direct like html/css/canvas/WebGL/storage/svg/video/audio/geo/etc and ones that are newer are WebRTC/WebGL/WebGPU/WebAssembly etc. All of these are and will be abstracted by some frameworks and people will know less about them and more about the platforms on top if they aren't regularly going direct. I think people that know about the standards more low level make for better framework developers an developers that use frameworks even.

I like platforms that make web standards the core aim not the platform lock in.

Lit is just a lighter weight version of that and closer to web standards without having it bolted on to a larger, almost monolithic framework now.

Lit is somewhat Angular like since Google make both.

> I mostly agree but Web Components is a web standards as is templates/custom elements now.

People keep repeating this mantra as if this alone makes web components good

> Those frameworks have incentive to lock you in while standards are lock-in at a lower level.

Or: these frameworks have the incentive to solve problems that web standards have been unwilling to solve for decades, and won't solve for another few decades.

> I like platforms that make web standards the core aim not the platform lock in.

Then you should use literally anything else but web components. Because web components don't make standards their core, are broken on multiple levels, and will require 20 more new standards to fix things that are not broken in literally anything else: https://threadreaderapp.com/thread/1717580502280867847

> Lit is just a lighter weight version of that and closer to web standards

The only thing that is standard in Lit is that it compiles to web components by default.

I mostly agree but Web Components is a web standards as is templates/custom elements now. Web Components are a standard.

You did ask. heh.

As I mentioned, I prefer direct standards or at least frameworks that make standards a main part of the design, even if only on output.

Standards are slower to finalize, frameworks front ran them via abstractions that may have been needed for a while --like Flash with interactivity before HTML5/canvas/svg/WebGL/etc and I was huge into Flash and plugins, those days are over though. Standards will be around longer and more maintainable on standard schedules not just feature/dependency pump frameworks of today that have verbloat.

Plugins and now frameworks innovate and front run, and influence standards, then standards win the long game every single time. Like why use virtual DOM when shadowdom is now available, unnecessary abstraction now that will always lose to native dom abstractions like shadowdom.

Right now with web standards where they are at, Javascript how far it has come, and the coming WebAssembly + WebGPU platforms now being ready or close to ready, the current frameworks are about to be lapped. It is just the way things go and the typical waves in innovation to standards and repeat.

About Lit, I mentioned it as I said in another comment "if you like the component style of other frameworks but want to use Web Components, Google Lit is quite nice"

We can agree to disagree on the rest.

web components are a failed standard, it was a good idea 10 years ago but now its a very bad idea

What makes them bad?

There are so many downsides of choosing web components you really need a very rare usecase to justify them. They are an artefact of a time we're all glad to be done with, they force you into OOP so you're doing inheritance acrobatics, add TS and now you're feeding two hierarchies of inheritance that don't quite match and bloat to a 80% of your codebase, making it unreadable, prone to hacks and bugs, impossible to maintain etc. The point of web components was to make components more shareable between frameworks, and code more reusable, but now code written in any of the major FE frameworks is more reusable (a component looks pretty much the same in React, Vue, Svelte, but not with web components).

> But the unique power of web components (in the browser) is that they can render before JavaScript. React components cannot do this — full stop.

Unless you... server-side render them. Then your definition of "render" needs to change

Sorta-- that means you render it at least twice.

1. You convert the JavaScript/JSX into HTML on the server and send it down (along with multiple blobs of JSON/code to re-hydrate).

2. The browser parses all the HTML and added JSON/code.

3. The browser then re-hydrates the page via JavaScript loading all of the JSON/code and computing everything (rendering it again).

Not if you use react server components, then markup is streamed in chunks as it gets rendered on the server and patched into the dom on the client. The JS for those components is never sent to the client.

With progressive enhancement, the page is "rendered" for all intents and purposes before any js enters the scene

>The browser then re-hydrates the page via JavaScript loading all of the JSON/code and computing everything (rendering it again).

isn't this exactly what's going on under the hood with web components? if you send an html page including <user-avatar><img></user-avatar>, the browser is going to draw the <img> tag and treat the <user-avatar> tag as a no-op because it doesn't know what to do with that. then your javascript kicks in and transforms the <user-avatar> tag into whatever the javascript defines it as, at which point it will get re-rendered.

Yeah-- but a single component is a much smaller degree of JS than an entire React application.

Depends on how many "small components" you need.

Reddit's new redesign downloads over 100 js files: https://x.com/dmitriid/status/1708772121260732494 to render a menu.

Of course there's a tradeoff--- if everything is a component then it may as well be an SPA (or at least bundle those files...).

I don't think the core idea was to ever use "hundreds" of components. HTML should be able to do a majority of the work, and you sprinkle a component here or there as needed.

At least you can server render web comppnents.

You've been able to server render React for like a decade.

Define 'server render'?

Output them on the server. Something you can't do with Web Components

You actually can't yet do that reliably. Declarative Shadow DOM is not yet supported by Firefox. https://caniuse.com/declarative-shadow-dom

You cannot, last I checked. JavaScript is required for Web Components and lack of SSR support is the only reason I moved away from them.

Am I misreading this or is it what https://htmx.org/ provides?

> But the unique power of web components (in the browser) is that they can render before JavaScript. React components cannot do this — full stop.

Umm, that's why SSR was created?

Web components are standardized by the web consortium. They are the way web browsers have agreed components should work. They have value inherently and don’t necessarily mean you can’t use react, in fact they can be used together very well especially for things like framework agnostic design systems. Basically, web components have more holding power inherently because they are browser native. React and SSR is just a great way to augment that.

While I write react daily and love it, I think it’s important to realize no methodology today will have any real importance or meaning 100 years from now. It’s all a means to an end and frameworks and web components are just different means.

In 2123, people will glance at a paragraph about react and move on to the next topic in programming history.

SSR is the traditional way to write frontends. PHP, Rails, JSP, most technologies that revolutionized the web were rendering HTML on the server. SSR, in one form or another, will exist for as long as HTML will.

Additionally, SSR doesn't replace web components, it's a different technology with an intersecting feature. There is no problem to use them together.

Which is React SSR. A few years down the line, React is gone. Legacy. Most on this forum don't care, they'll just move to another project.

Web components are encapsulated very well. It is different from template frameworks such as react. It is somewhat similar to frameworks such as angular. As we all know, angular fails because of its complexity. It uses javascript to look like java. Web components look like It is not that complicated, but it also introduces a lot of concepts. These concepts are rarely used by ordinary developers. It is generally difficult to change the developers' inherent concepts and development habits to adapt. If there is no react or vue, I feel that it may not be successful because there may be other simpler frameworks.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact