Hacker News new | past | comments | ask | show | jobs | submit login
Web Components could replace frontend frameworks? (dannymoerkerke.com)
450 points by technojunkie on April 11, 2019 | hide | past | favorite | 239 comments



Web Components don’t offer a declarative way of updating the DOM; it’s still `innerHTML` and using DOM APIs to edit the state of the live DOM. Backbone was a hassle to manage in any sizeable app because updating the view was left up to every dev to figure out themselves. React brought a declarative wrapper around the statefulness of the DOM, and that is the killer feature that Web Components does not offer at all. Vue adopted the declarative template approach as well.

The Web Components spec was written before React and Vue were very mature, and it unfortunately shows. Web Components might offer a better primitive for higher level frameworks to build on, but I would not suggest to anyone to use barebones Web Components over React or Vue.


There is lit-html and lit-element, though you can get tripped up by the difference between props and attributes coming from React JSX where everything is props because it’s all native JS until the DOM render...

It’s tricky to recommend them because I’m using web components at work and find the transition from React especially rocky. But they are native and standard, and other frameworks are slowly moving in that direction... I expect React will be the last to adopt them, or they’ll push for spec changes before they do...

open-wc is also worth a mention: https://dev.to/thepassle/announcing-open-web-components-5h7 - their guide and setup for using web components is over here: https://open-wc.org/guide/#quickstart

You can also technically start using native es modules in browsers, either localhost in Chrome 74+ or via origin whitelist with Google. Or use a polyfill such as Guy Bedford’s https://github.com/systemjs/systemjs/blob/master/docs/import... or https://github.com/guybedford/es-module-shims — but you’ll have to consider solutions for custom syntax, scss or non-es module dependencies. I personally think there’s a gap in the npm ecosystem which is building “source packages” that are native single-file es modules you can easily import or compile from with a native JS module system...


But at that point the headline is "framework x could replace framework y"?

Web Components are great for reusable components like date pickers that you might want to re-use regardless of framework. If they're just the technology backing the implementation of some framework, than that framework is only worth switching to if it provides something fundamentally better than the framework you and many others already know, because the mere fact that it's built on Web Components no longer provides a significant advantage...


Templating libraries are far from frameworks. lit-html doesn't have a component model, and it's use in a web component doesn't leak outside of that component. You could switch from lit-html to something else and it wouldn't be a breaking change to users.

Try thinking about writing a React component that doesn't use React to render. Or seamlessly intermixing React and Vue commoners. Then you see the difference.


You can use JSX syntax for building web components using this tiny library: https://github.com/wisercoder/uibuilder


You can absolutely use web components with react... you just have to use `<lower-case-component>` for webcomponents, since a capital first character will trigger JSX transforms.

So you can use, for example this set of components with a react application and get some of the best of both worlds. The only down side is attributes in web components aren't passable via the markup, only via DOM reference.

I happen to like react as-is, but Vue is probably much closer to web components and could see Vue becoming a compile to web components option sooner than later.


Vue already offers compiling to web components.

https://cli.vuejs.org/guide/build-targets.html#vue-vs-js-ts-...


Well I like stencil for its typescript and jsx but I haven't dug into it hard enough yet to discover its agony points. Its just that when it compiles its all native code calls, no framework to ship but you still benefit from jsx and typescript in development.


And, there is Stencil JS (https://stenciljs.com/) which in my opinion offers a neat API to create Web Components.


There's nothing wrong with using a DOM templating library to give you declarative DOM updating. There are a number of solutions, many even JSX-based, and this is also why I created lit-html, which offers extremely light weight template expressions, similar to JSX but in standard syntax, and very fast updates.

There's no requirement that you use web components without helper libraries. That was never their intent.


> That was never their intent.

No one remembers what the intent was. Just two years ago the whole narrative from the proponents of web components was “the future is here, no need for frameworks, get rid of your reacts and angulars and... and...”

But then people actually tried using them.

So, curiously, the narrative quickly shifted to “oh, these are just primitive APIs never intended for direct use, and only intended for library and framework authors”.

Curiously, at the same time the narrative usually keeps going “react is crap, you should drop it in favor of web components”.

A nice recap from Dan Abramov: https://dev.to/dan_abramov/comment/6kh1 and more in the discussion here: https://dev.to/ben/why-the-react-community-is-missing-the-po...

And we are in yhe comments to an article that literally argues that Web Components will replace frameworks. While half of the people in the comments say “yeah, the intent is for them to be used only by library and framework authors”.

There’s a certain hint of schizophrenia in how Web Components are described by their proponents.


Amen!

The core problem now is that Web Components aren't any faster than userland frameworks like Preact.

Specifically:

1) First Contentful Paint: Web Components require client-side JS to render, which guarantees that their FCP numbers will be slower than React/Preact server-side rendering solutions, which can render without client-side JS.

2) Time to Interactive: LitElement + lit-html at 4KB is smaller than React (but not if you include WC polyfills), though it's not smaller than Preact (3KB).

3) Efficient Updates: lit-html might be able to beat out React/Preact here if you have a large page and you don't use shouldComponentUpdate or React.memo, but lit-html doesn't use Web Components (custom elements, shadow DOM). Haunted "virtual components" (lit-html + React-ish hooks) look pretty cool, but that's still not WC.

Without a credible performance advantage, Web Components are a zombie standard, walking dead.


If I need to use server side rendering, there are plenty of server side rendering frameworks more mature than React/Preac.

Any JS component library needs JS by definition.


> If I need to use server side rendering, there are plenty of server side rendering frameworks more mature than React/Preac.

Not if you need both server-side rendering AND a rich frontend. Unless you want to duplicate logic between two frameworks.


Server-side rendering and a rich frontend are orthogonal.

And yes, JavaScript is absolutely not the best way to actually make use of the server rack.

https://www.techempower.com/benchmarks/


They are, unless you want to avoid duplicating logic, like I said. That's where most of the benefit of server-side rendering via JS comes from: you can render the initial page on the server, but then have the client-side framework take over on load, all from the same framework and with very minimal code duplication. Otherwise you have to write most of your rendering logic twice, in two different languages/frameworks.

Re: benchmarks, I don't know what that has to do with anything. JavaScript (via V8) is much faster than Ruby and Python, and yet Rails and Django are still massively popular. For most apps, using a super fast backend language is not a concern.


I rather go with rendering performance of HTML, CSS and minimal JS.


No one working on web components had ever said that they're intended to be used with absolutely no helpers.


What I don't get is why there isn't a native, declarative DOM templating API yet. It would be so much faster and would mostly eliminate the need for React and the like. Instead of a "virtual dom", a native "dom buffer".


I have high hopes for Flutter/Hummingbird in that regard. When their renderer is implemented using web APIs, this is basically what we'll be getting.


this is just replacing framework a with framework b. It's not a "native, declarative DOM templating API yet"


Well, yes and no. They are implementing a rendering engine that supports things the web famously doesn't support, which includes fundamentals like UITableView from iOS. They are doing this by leveraging new APIs to access what browser layout engines do under the hood. So in that way, it generates native browser elements, and their API is declarative. So it's at least one abstraction layer below React and friends.


....no and no. The call was for a declarative interface to the DOM, like React, built into the browser. Flutter, being not built into the browser, is not that.


There are a million things that do this already - including Qt, which already works in WebGL. The point is to leverage the rest of the web's existing features while also getting declarative templates, not to create another Flash.


Flutter/Hummingbird will be writing DOM elements, so it's not just an opaque WebGL texture.


In terms of "dom buffer" there's a proposal in the works for the buffer "other half" to `window.requestAnimationFrame()` to queue DOM reads (where RAF is the place to queue DOM writes). So far I've heard it has the unimaginative and odd use of grammar name `window.requestAnimationFrameAfter()`.

Still would be too low level to easily work with though without a framework like React.


Yeah, articles that proclaim the end of frameworks due to Web Components always revolve around a misunderstanding of what those frameworks bring. This article, likewise, starts out on the same incorrect premise:

> [Frameworks like Angular and React] have enabled us to do what we always wanted but never were able to: creating reusable autonomous frontend components

That's not what we always wanted to do, and not why people are using these frameworks. How often do you re-use your Angular and React application?


I reuse react components ALL the time.

I think the problem with the article is that it is just looking at components (as a developer I have wanted the encapsulation this methodology brings), whereas react offers more than that - the virtual DOM, for example.


Ah, yes - within the same applications, components are often re-used. Still, it's a stretch to say code re-use is the main reason people are using React. Rather, its advantage lies in its composability and how easy it makes it to separate view logic from other logic. And probably a few other reasons that other people would name as well; in any case, it's not just the ability to re-use components, and an alternative only providing that part is not going to replace React in my applications any time soon.


I reuse components in different applications. There are also popular third-party components (and even whole libraries) to be found on github and elsewhere.

I don't think web components will replace react, simply because they do different things. You can write web components in react which gives you the best of both worlds.


> How often do you re-use your Angular and React application?

A lot, our Angular components are re-usable across projects.


I'm constantly reusing modules/components/pipes/guards/interceptors/etc across angular projects. Saves a lot of time. It's not the reason I use the framework, but it gives me more incentive to stick with it.


Our company standardized on React company-wide along with a company-built framework of reusable components to share across all applications.

Apparently at least some people choose frameworks because they want that.


We have been using a small bit of glue code to write Web Components declaratively with Snabbdom for a couple of years at Mixpanel: https://github.com/mixpanel/panel. Happy to talk further about our experience!


Thats what lichess uses as well.


"React brought a declarative wrapper around the statefulness of the DOM, and that is the killer feature"...

Yes, If there was a native standard for watching and manipulating state then frontend frameworks would be largely unnecessary.



(For security purposes, in vanilla js we should all be using textContent, not innerHTML, and creating dom nodes directly.)


When you control the data, innerHTML is fine. It's only untrusted data coming from the user that's the problem.


Only if you can, with absolute certainty, keep track of which of those is which, and never have it change, or have some offline process polute data that was supposed to be clean.

There is almost never a reason to use innerHTML, and by avoiding it you reduce the surface that could be attacked.


You are just making things extreme without giving your fellow software engineers some confidence that they won't screw up. Plenty of variables are string constants, or numbers coerced into strings or some such. A good type system will always help though.


In the words of Jeff Atwood, "Give me parameterized SQL, or give me death" - and HTML escaping is little different. My fellow "software engineers" are human. They will screw up. That's simply a matter of human nature and statistics. Even if we only employ godlings, we'll eventually hire a human intern.

"It happens to be safe for the moment because it's a constant" isn't a high enough bar. I've refactored plenty of string constants to new locations, and then to dynamic strings. If that's the bar you're using, every such refactoring is now a security critical change that requires a thorough security audit.

There are uses of innerHTML, but the post you're replying to acknowledges that - "almost never". If you're building the APIs that enable safe DOM manipulation, you have some use cases. If you're serving HTML fragments directly from the server, you have some use cases - although I'd hope you're using safe APIs serverside if it's dynamic, instead of hand-building HTML in code!


apart from where you actually have html formatted text. not plain text.


innerHTML has to parse the html, so won't it be a bit slower?


Wouldn't the JavaScript engine need to parse your long and complicated chains of `document.createTextNode(blah)` or `parent.appendChild(foo)`?


Never use .innerHTML! Instead use .appendChild, .removeChild, and .innerText. Using .innerHTML is like having a program patch itself during runtime.


textContent is usually better than innerText.


While I know what you're getting at, the word "never" really isn't helpful or useful. There are certain times where innerHTML(or insertAdjacentHTML) is the best approach. It's really not that slow that it can't be the most clear and concise solution.


Its not about performance. innerHTML is actually fast. Its about security and maintainability. InnerHTML makes it easy not only for the developer but also an hacker to inject code into a web page/app. innerHTML is like a global missile satellite network that can fire anywhere at any time. Instead you want to design like a plumber, where data flows via a pipe to the database, then back again in another pipe which change the state of the view. You should not have a single HTML tag in your single page application!


I use lit-html and it is more than enough for our needs!


what about slots?


Slots require shadow DOM which means there can be performance and CSS issues on widgets designed for local use with shared CSS. But I agree they’re also an option. :)


Performance issues? Native Shadow DOM, especially with Constructible Stylesheets, is a perf boost. Limiting style resolution to smaller scopes and less rules is good.


True, I don’t have benchmarks, but there was a time period where shadow DOM was popularly disabled due to performance hits, but perhaps it was all the performance hit of polyfills and less efficient implementations in browsers. https://github.com/WICG/construct-stylesheets/blob/gh-pages/... is interesting, though Sass still looks unlikely to be added to the browser so we’ll always need some amount of CSS compilation if you want CSS nesting the way you expect it in Sass. Here’s more documentation on constructible stylesheets: https://developers.google.com/web/updates/2019/02/constructa...

I wasn’t aware of this because this stuff is being developed and released so dang quickly! (I do worry that APIs developed in relative haste might be replaced or iterated on in relative haste, especially if they aren’t adopted widely first...)


  :is()
can make concise CSS of some of what nesting does in Sass

https://developer.mozilla.org/en-US/docs/Web/CSS/:is

there's a lot New coming into web all the time. I watch chrome status for drops.

https://www.chromestatus.com/features


Very early ShadowDom had worse performance, but the major browsers have been hard at work improving it for a while now. I haven't benchmarked in several years but I wouldn't be surprised to find that it is now a boost in many cases.


You might want to check out https://cssdb.org/#nesting-rules native nested CSS rules have hit stage 1!


I checked the spec earlier and it’s impossible to make it backwards compatible with Sass without some slight edits, at least according to their GH issue on it. It’s worth watching though I suspect <style type=“text/scss”> or something like it will be added before we see broad adoption! :)


Possibly. I think the extra `&`s are something that could wash out with one-time tooling, and that the desire for `@nest .parent &` would bump the conversion rate, but it's always fun to watch the comings and going of standards.


Perf boost compared to what? It can't be a FCP perf boost relative to server-side rendered plain old CSS and HTML, because shadow DOM requires client-side JavaScript.

Plain old CSS is able to parse and render before the JS required to launch web components has even finished.


It can be a performance boost because it only updates the part of the DOM tree that has changed. Not completely unlike React’s virtual DOM


This. I feel like an old man yelling at a cloud, but while everyone seems to focus on how awesome shadow DOM and isolated CSS is, I need to deal with using a global theme and styles.


I have the same problem with global styles when using Web Components. Using @import in the components to include the shared style files solve the problem.


:part and :theme CSS puesdo-selectors will help address these issues


you can also use :host, which target the custom element specifically (and using :host on custom-element children does not, from what I recall off hand, get broken when nesting) and then target its children.

Also, css variables can be global and still enter into the shadow-dom unobtrusively (This is without using the polyfills, though, I believe this is a limitation in the polyfills currently, which might be why that part of it has been confusing in the past.).


Shared CSS can be dealt with using @import.


"declarative way of updating the DOM"

Updating is not declarative.


It's React that does the updating, the programmer only writes declarative code.


> Web Components don’t offer a declarative way of updating the DOM;

What does that mean? The methods provided by the web components spec appear declarative as do the methods provided by the DOM spec. Declarative example with nothing like innerHTML: https://developer.mozilla.org/en-US/docs/Web/API/Element/att...

Either way this discussion is stupid as updating the DOM is stupid simple even without a framework. The DOM is neither stateful or stateless, but rather that describes the implementation of your application logic.

* DOM - https://prettydiff.com/2/guide/unrelated_dom.xhtml

* state - https://en.m.wikipedia.org/wiki/State_(computer_science)

* stupid - https://github.com/prettydiff/wisdom/blob/master/Delusional_...


> The DOM is neither stateful or stateless, but rather that describes the implementation of your application logic.

One of the bizarre realities with those forced to write their own "virtual DOM" library, as I have done, is to deal with all the so-called hidden state. Form field values, the user's current text selection, scrolling position. Without a virtual DOM, simply replacing existing nodes with innerHTML or replaceChild will stomp this away. I'm not of the opinion that you need a full framework to handle this state (I wrote my own 10-line helper function which works in most cases I care about [0]), but you do need something more structured than just replacing nodes wholesale.

[0] https://github.com/magcius/noclip.website/blob/master/src/ui...


Is that really valid ES6? Or are you using typescript


> src / ui.ts


?


......

The .ts file extension generally means TypeScript.


What about with using appendChild or insertBefore instead of innerHTML?


> * stupid - https://github.com/prettydiff/wisdom/blob/master/Delusional_...

It seems you wrote this article; have you read it back? You bury the lede under 1230 words explaining some social concepts rather than anything programming-related.

Additionally, you use many complex words to describe simple subjects. And you do this knowingly: for example, you felt the need to link the definition of "acquiescence" to the word. If you felt that it was complex enough that this was warranted, why not instead rewrite the surrounding content?

If the purpose of this article is to convince people that disagree with your statements, you have certainly lost those people by the end of the article.

I don't even disagree with you; the DOM is great and WASM is definitely just another option and not a replacement for JS.

Finally, I have to note: there aren't any citations for your claims in the programming section. One might otherwise wonder where you get an idea like

> That DOM mechanism will allow a WASM application to execute DOM methods without having to provide its own DOM application, but it will be limited to markup within the WASM application.

when I haven't been able to find anything indicating this elsewhere on the web.


A wiser man than me once said its hard to have rational conversations on this matter because delusional people more invested in their opinions than they are in the work they perform.


> If the purpose of this article is to convince people that disagree with your statements

You missed the point. It isn't about disagreement. Its about not throwing away evidence to retain a challenged opinion. The first two thirds of the article was very explicit about this.

> when I haven't been able to find anything indicating this elsewhere on the web.

Then you didn't search very hard. The article specifically mentioned this is in relation to the web assembly host bindings proposal. The first search on any search engine brings me to the spec on github. As far as DOM work you would have to dive into the DOM string portion of JS API integration section: https://github.com/WebAssembly/webidl-bindings/blob/master/p...

If you are confused as to what the article says then submit a pull request with a superior recommendation. It is on github after all.


> You missed the point. [explanation of the point]

If it's that simple, could you consider replacing the first 1k words with this instead? I'm entirely serious.

> Then you didn't search very hard.

Okay, I'll bite. I searched for the phrase "host bindings extension to WASM" (the literal phrase included in your treatise) on DuckDuckGo, which brings me to https://duckduckgo.com/?q=host+bindings+extension+to+WASM&ia.... The first result is https://github.com/WebAssembly/webidl-bindings/blob/master/p..., a 404. If you want someone to find something so badly, link it instead of making claims about how much effort they might have put in. The onus is on you to prove the claims you make, and I wish this were something you took the time to link instead of the definition of "acquiescence".

> As far as DOM work you would have to dive into the DOM string portion of JS API integration section: https://[...]

You don't make clear which part I'm supposed to be looking at, and I don't explicitly see it stated that DOMString will be the only way WASM can interact with the DOM; there's just an example of how a WASM function might take a DOMString and return a DOMString, and how the binding machinery works in that case.

Additionally, after some additional searching, I found https://github.com/WebAssembly/function-references/blob/mast... including "Easier and more efficient exchange of function references between modules and with host environment" and information about closures. I'm not certain about it, but doesn't this run counter to your point about code running against `window.document`? After all, you could (if I'm reading this correctly?) pass in a bunch of closures that directly manipulate `window.document` through something like this.

> If you are confused as to what the article says then submit a pull request with a superior recommendation.

If I don't understand the article (you've just told me I don't), how do I help you make it better?


> If it's that simple, could you consider replacing the first 1k words with this instead?

No. I am not going to change anything because strangers online cannot read. If you have a better approach submit a pull request.


One does wonder what the point is of trying to communicate something, if the speaker does not care about whether the listener understands their message...


This can be seen in scientific papers as well as in some books.

It is based on the literacy of the powerful that we know from the dark ages. To use complex language as a substitute for easier formulations is a tool for literate people to prevent lesser educated people from understanding their texts.


Calm down, have some dip.

This article claims Web Components could replace frontend frameworks. React is a component library often used in a frontend framework.

React wraps the DOM with a Virtual DOM that provides a declarative abstraction for stateless updates. That is, you can write a plain function - given data X, produce DOM state Y - and React works out all the DOM calls required to arrive at the desired DOM tree from the current actual DOM tree.

So, with React, a developer does not need to make granular element-by-element, attribute-by-attribute changes. Many developers have found that leaving this diff / patch work up to the computer is easier than working out all the DOM calls themselves. Even more so than the concept of components, this has enabled architectures that many developers find pleasing.

Now, you can call that stupid or delusional if you like, but at least understand what's being referenced here.


I would argue that for what the OP was discussing `textContent` (From the linked example) is very much like `innerHTML` (As it’s a safer version of the former). I’m not sure what you mean by the DOM being neither stateful or stateless, or describing an implementation of logic. Could you clarify?


The DOM is a model of a markup language instance plus access methods. State describes memory of properties resulting from a change. For example HTTP is stateless.

The DOM can be both stateful and stateless, neither, or one of. The statefulness depends on your application logic rather than any intrinsic quality of the DOM itself.


Any stateful data structure is stateless if it’s not changed. That doesn’t seem to me to be a particularly deep revelation about the DOM.

Back to your original point, that code example you linked attatches a shadow dom, creates an element in it and then puts text in it. I fail to see how that’s declarative or stateless, and AFAIK that’s the only way to populate a shadow DOM (the original HTML of the document cannot put elements there).


Ah yes, the quantum DOM.


Also I would say that the statement "The DOM is extremely challenging and working to the DOM destroys architecture" is a straw-man here, or at least a red herring.

The DOM is not all that challenging. It can be a tedious API, though. React shifts much of the effort to manage element and attribute changes to an algorithm, thus relieving tedium. Many folks find managing the DOM through a functional paradigm to be an enjoyable & productive approach to working with client side web apps.


>Web Components will replace your frontend framework

Yeah, I very much doubt that.

Web Components is basically a suite of browser technologies. It's actually particularly heavy and I kind of hope it doesn't catch on personally, since it pushes so much to already giant monolithic web browsers.

Frameworks and libraries like React and Angular are tools for developing applications first and foremost. The actual technologies they're backed by doesn't matter, but if you can't reimplement either of them using WebComponents it should probably tell you something about WebComponents:

- It's very opinionated about a lot of things.

- It disagrees with many of the (much more popular) frontend frameworks far too much.

React does a whole lot of things right, and it does them right in a relatively small package with a relatively small API surface, and you can extract the essence into even smaller libraries. With functional components, you can even build React components that have almost no React in them at all, other than JSX.

I don't think we need new complicated technologies to solve the kinds of problems React solves. If anything, we need less, like an alternative to the current DOM model.

Most of the innovations in the frontend world don't seem like they can be cleanly applied to Web Components, or even layered on top of it. And if we want to update it down the road to a new major version, we have to wait for every major browser vendor to have a stable implementation and iron out edge cases/differences. That's not a good bet at all based on how it went with Web Components the first time.

In other words, No Thanks, I'll take my framework.


How do you feel that web components are heavy? They're a pretty small set of low level APIs, and being native they have no download cost.

They're also pretty unopinionated. They only let you define an HTML element and hook it's lifecycle. They let you know where to render (the element instance and it's shadow root), and when to do things (lifecycle). The rest is up to developers, and there are lots of helper libraries with different opinions on how to implement a full element.

I think you'll find that some of them, like lit-html, LitElement, and Haunted, have very similar ergonomics and models to React. And much better performance and bundle sizes.


>How do you feel that web components are heavy? They're a pretty small set of low level APIs, and being native they have no download cost.

This is a weird misnomer to me. Stuff that's provided by the browser is not magically faster or better. Further, native browser functionality can slow down applications just by existing, like for example Mutation Events (which were removed in favor of Mutation Observers.)

In that sense I really dislike what functionality is being loaded onto HTML elements, effectively the lowest level primitive of web apps.

>They're also pretty unopinionated. They only let you define an HTML element and hook it's lifecycle.

In itself, there's not a whole lot wrong with this... But as fate would have it, the idea that HTML elements themselves should be components is an opinion hotly debated. In Angular 2, you have both directives, AND components that are selected from attributes. In React, the component tree is a fully separate entity from the DOM tree, and components don't even appear in the DOM.

To me these are not small details that can be reconciled. Part of what makes React ergonomically nice is that it can generate a nice, clean DOM free of component cruft and scoped CSS or whatever.

>And much better performance and bundle sizes.

Modern JS app performance is just not that simple. We've got server side rendering with hydration, scheduling rendering asynchronously for better responsiveness, bundle splitting, etc. Simply saying "WebComponents are better because they're faster" means little to me. Is my app bottlenecking on React? Often it's really not.

And if React's ~100kb is really killing you, there's plenty of libraries that implement just the basics in much less. Preact is quite good.


> And much better performance and bundle sizes.

I understand that you're the author of lit-html - would you say that the above is the main selling point of it?


> It's actually particularly heavy

Huh? It's a very small API built _into_ the web browser. What's heavy about it? It's kinda similar to how JSX works just with less bells and whistles, more standard web stuff.

> It disagrees with many of the (much more popular) frontend frameworks far too much.

Ember, React and others plan to eventually support them. So, I am unconvinced that it disagrees with them at all. In fact I think it enables them to have wider access to developers.


>Huh? It's a very small API built _into_ the web browser.

Being built into the browser doesn't make it lightweight.

I mean, if you look in terms of functions that WebComponents adds, it's a relatively small API surface. However those APIs encompass an awful lot of different functions that imo bloat basic concepts by introducing complexity into HTML elements and the DOM.

>Ember, React and others plan to eventually support them. So, I am unconvinced that it disagrees with them at all. In fact I think it enables them to have wider access to developers.

I'm very much not holding my breath for that. I do think interoperabilility with WebComponents is a definite future, but thats it.

React fundamentally disagrees about what a component is. At the most basic level, React components are not DOM components, their entire DOM representation is what they render. This is not something that can be reconciled.

However should React let you export a component as a "WebComponent," via custom elements, sure, that's fine. Interoperabilility is not really notable though. It's also possible to interop React with Angular, Angular 2 with Angular 1, etc etc. Many of those are done today. In big apps. In production.

Edit: Reacts take here. https://reactjs.org/docs/web-components.html

>React and Web Components are built to solve different problems

Could not agree more, and that is precisely why no, WebComponents are not replacing my JS frameworks.


> However should React let you export a component as a "WebComponent," via custom elements, sure, that's fine. Interoperabilility is not really notable though.

I don't really care about exporting my React applications as Web Components; I'm not going to re-use them inside another application anyway.

What I care about is React supporting interoperability in the sense of allowing Web Components to be used in a React application. I think that's largely possible already, but slightly cumbersome, IIRC.

I also don't really care about the other option: exporting a React Component as a Web Component. If I want to re-use a component in a different application, that's when Web Components by themselves are the right choice, and I'd prefer not having to ship React with it. Especially not once you get to the likely point where you'd want to use two different Web Components that use two conflicting versions of the same framework, or multiple components pulling in different frameworks.


Yeah, React is pretty much anti-browser standard APIs.

Vue.js, Angular or vanilaJS are our JS frameworks, exactly because supporting Web Components is part of the culture.


On the contrary, the React team has had a bunch of discussions with the Chrome team recently about adding new scheduling APIs to the browser platform, specifically to support the kinds of things that React (and other frameworks) need to do.


Were those discussions public?

Yet another Chrome specific API?



Thanks for sharing, it seems pretty much specific to Chrome.

So it is anyone's guess if this will ever land in other browsers.


> "I don't think we need new complicated technologies to solve the kinds of problems React solves. If anything, we need less, like an alternative to the current DOM model."

It seems to me as if you're saying:

"We don't need new complicated technologies."

"Also, we need a new, complicated replacement to the time-tested DOM."

This probably wasn't the intent but it exposes the need for web components to be built the way they are: progressively enhanced from what's already standardized in browsers. Web components really aren't that complex, and comparing them to React in this way is a disservice.


Yeah, the DOM the web layout engine isn't complicated at all ...

    display: block;
    display: inline;
    display: run-in;
    display: flow;
    display: flow-root;
    display: table;
    display: flex;
    display: grid;
    display: ruby;
    display: block flow;
    display: inline table;
    display: flex run-in;
    display: list-item;
    display: list-item block;
    display: list-item inline;
    display: list-item flow;
    display: list-item flow-root;
    display: list-item block flow;
    display: list-item block flow-root;
    display: flow list-item block;
    display: table-row-group;
    display: table-header-group;
    display: table-footer-group;
    display: table-row;
    display: table-cell;
    display: table-column-group;
    display: table-column;
    display: table-caption;
    display: ruby-base;
    display: ruby-text;
    display: ruby-base-container;
    display: ruby-text-container;
    display: contents;
    display: none;
    display: inline-block;
    display: inline-table;
    display: inline-flex;
    display: inline-grid;
Of course that's just CSS/the layout engine. The DOM itself is sort of unrelated. But to that effect, I'd like to mention two filesizes.

React 16.6.0 base library, minified: 6.21 kb

React 16.6.0 DOM integration, minified: 100.39 kb


Those file sizes miss the dependencies that are native to the browser.

Web Components: 0 kb


You forgot the polyfills.


Cynical me saw Youtube in Chrome loading instantly while Firefox was served a build with the high parsing cost of Polymer polyfills. And starry-eyed developers importing if and for statements and writing imperative dom updates, while running some JS transpiler just like a React guy does. Never mind two major versions made Googling impossible, or debugging methods available to only geniuses.


The browsers we target don't need polyfills.


So you aren't targeting Safari, Edge, Firefox ESR or any version of IE?


Never had to deal with Firefox ESR, and very few customers are still stuck on IE 11, thanks to the ongoing migration to Windows 10.

Latest versions of Firefox, Chrome and Safari support all necessary features for Web Components.


"I don't think we need new complicated technologies to solve the kinds of problems React solves."

Isn't web components the standard, and react is the complicated technology?


I think most of the rationale is around sharing components easily, at a level separate from NPM/&c. For things like JIRA/Disqus widgets, or for small components shared across otherwise disparate parts of a large site (things like Office 365).


Curious what you think about React Canvas https://github.com/Flipboard/react-canvas


I don't necessarily think everything should be Canvas, but rethinking the way pages render wouldn't be a bad idea. The issue I take with Canvas in particular is that it's poor for accessibility, password managers, and other services.

I think part of the reason why the DOM and layout engines are so slow and complicated is just because of years of cruft and whatnot. A minimal layout engine with most the abilities of Flex and Grid would be nice.



Thank you for your constructive argument. I now know I don't need Web Components either ;-)


The reality of Web Components is that it was never intend to take share away from the large frameworks. Instead Web Components is intended to fill the middle ground between a simple web page and a full blown web application. There is a real need for web page developers to be able to just drop in a prebuilt web component and go without having to reach for the 10,000 pound gorilla of frameworks. That’s where Web Components can have real value, real benefit.

Is Web Components flawless, hardly. While the APIs are accepted standards and implemented in most browsers there are still a few holdouts, and to be sure there are still edges to iron out. No technology is without it warts, its awkward teen years. But Web Components is maturing and the tooling around it is maturing as well and Web Components most definitely has a place and is most definitely here to stay.

Also it is worth keeping in mind that the Web Component APIs are specifically written as low level APIs and intend to be built upon by libraries and frameworks to simplify and aid the process. Libraries like the one I am currently pitching, ZephJS [1], which aims at making writing and distributing web components mind numbingly simple to do. ZephJS is a perfect example of the new generation of Web Component libraries to facilitate answering the need I espouse above: the middle ground between basic and beast that so many web developers live in.

[1] Introducing ZephJS: https://gist.github.com/arei/8083a6270e704b830c68a2020f3e5e3...


> The reality of Web Components is that it was never intend to take share away from the large frameworks. Instead Web Components is intended to fill the middle ground between a simple web page and a full blown web application.

Exactly. More specifically, it was created in response to the years-long hiatus in development of the HTML spec, when we were still waiting for a date picker element (heck, we still are!).

With Web Components, we might all use the same widely supported and actively maintained emoji picker regardless of the framework we're using. But they do not solve the problems that framework solves.


I love writing Web Components, but they're never going to really be a thing. The promise was that we could create native components without any dependencies at all but it just hasn't worked out that way. Shadow DOM support, the real killer feature, is patchy at best without polyfills. Orchestrating them into any kind of complex app still requires some kind of framework to handle things like passing down props and event binding, which at that point you might as well go full on (React/Angular/Vue) + Webpack/Babel. The dream of being able to share reusable components breaks down the moment your designer wants an extra 5 pixels of padding here or there. It's fun to use them for small things but it's just not viable as an alternative to frameworks.


Strongly disagree. We (Ionic) built our new version directly on top of Web Components and they are certainly a thing for us and our users building real apps on top. Plus, they are a huge reason why we now support React and Vue and plain JS.

Frankly, this has been transformational for our project and for our business. I'm completely sold.

One problem with the WC debate is people constantly compare the raw Web Component collection of APIs to a framework, when in reality, you'll add in libraries or extras on top of your Web Components to get similar functionality (like Stencil: http://stenciljs.com/), but you'll likely not build apps with them as much as you'll build components to share with others.

In that sense, the killer app for Web Components is actually Design Systems, not SPAs.

I disagree with the idea that Web Components replace your framework, however. They solve different problems! For Ionic as a cross-platform Design System, they are a major asset.


I'm glad to hear this take. I came from Angular v1 and got sick of the framework churn, so jumped over to Web Components around 2015/2016 instead of going React. I abandoned Polymer pretty quickly around v0.6 because things were changing too much and just went plain vanilla JS + Web Components. I've been building applications since then with just Web Components and couldn't be happier. Unfortunately I just don't have enough experience with React to debate any of these points - I guess I just have to leave it that React is a need I don't have.


> In that sense, the killer app for Web Components is actually Design Systems, not SPAs.

My read too


> The promise was that we could create native components without any dependencies at all

This isn't true at all, and it's a big misperception about web components.

Web components are pretty low level APIs that expose a few abilities that the browser natively has: defining a tag name, hooking into element lifecycles, creating an encapsulate DOM subtree.

Web commonness have no opinion on rendering, state management, etc. and leave other aspects, like responding to property changes, to existing features like JavaScript accessors.

It's expected that developers will use libraries to help implement web components, but the libraries won't have to implement a component model, or DOM composition, or CSS scoping. So they'll be smaller and more focused, and the overall product will be faster have fewer proprietary parts.


(sorry, I'm not well versed in some of these things)

Would it make sense for React to start using this native web-component at some level moving forward, to improve efficiency ? Maybe another library will replicate most of Reacts features but is powered by this native (faster/cleaner) technology?


afaik web components are mostly about encapsulation and semantics; they let you box up arbitrary HTML, JS and CSS and put a little bow on top so that it looks like one “custom” HTML tag to the rest of the document. (I could be misremembering.)

React is mostly about life cycles, propagation, and composition. The first two are orthogonal to web components afaik. The third has some overlap, but it’s mostly complementary with web components (once again, afaik.)


Angular has kept web component compatibility as a high priority. You can publish angular components as web components, and even leverage native functionality like shadow Dom.


Shadow DOM is now supported across all major browsers.

Also, don't understand your padding comment. Web Components are style-able.


The tooling is woefully inadequate, and the premiere Web Component tool is stringly typed to all heck which makes it a non-starter for me. I don't want giant blobs of runtime parsed text with no validation, syntax highlighting, and obviously no type checking.

But yet, here's Polymer 3:

    static get template() {
      return html`
        <style>
          .response { margin-top: 10px; } 
        </style>
        <paper-checkbox checked="{{liked}}">I like web components.</paper-checkbox>

        <div hidden$="[[!liked]]" class="response">Web components like you, too.</div>
      `;
    }
Cool. What an enormous regression over TypeScript with React and Vue. My editor just sees components as enormous blobs of text, and what do you know, so does my build system.


If you are starting a new project today, use LitElement. Only use Polymer 3 if you're coming from Polymer 2.


Types are cool, TypeScript is cool, and types with JSDocs are cool, https://dev.to/dakmor/type-safe-web-components-with-jsdoc-4i... and what's more, they're all cool with web components.


I'm confused, I scrolled down and still saw this:

    return html`
      <h1>${this.format(this.title)}</h1>
      <div
        class="dot"
        style=${`left: ${this.bar.x}px; top: ${this.bar.y}`}
        title=${this.bar.title}
      ></div>
    `;
That is not type checked. I can change any of the HTML tags in there, any of the attributes on the HTML tags, I can make the template ill-formed HTML, and nothing in my editor or build system will check that.

    const el = /** @type {TitleBar} */ (document.querySelector('title-bar'));
Why would I do that instead of this, if I'm using TypeScript?

    const el: TitleBar = document.querySelector('title-bar');
Moreover, this is an unsafe type coercion, we have no witness that the return value is a TitleBar. document.querySelector returns an HTMLElement, and if you were using strict TypeScript types this assignment would not type check.


There exists plugin for VSCode which checks for attributes inside template literal https://marketplace.visualstudio.com/items?itemName=runem.li...


That looks extremely useful though it's definitely in the "early adopter" phase of utility. It looks like this extension and the underlying TypeScript plugin that allows typechecking are being developed by a single person, and I think a team or individual would have to make a judgment call on whether to depend on it.


Polymer is deprecated in favor of LitElement which comes with TypeScript decorators.


With LitElement you are still encoding markup in strings and only the interpolated expressions are typechecked [1]. Not to mention that LitElement is far more clunkier and tedious.

[1] https://lit-element.polymer-project.org/guide/start#use-lite...


The lit-plugin VS Code extension provides type-checking and code-completion for lit-html temptlates. The approach can be adopted for a tsc plugin.


It’s still opaque string blobs no matter how you try to dress them up.

—-

I should probably edit this:

It’s still string blobs that are totally opaque to the browser, and that are parsed with regular expressions[1] at runtime[2] and dumped into DOM via innerHtml[3].

[1] https://github.com/Polymer/lit-html/blob/61c08a615abadbe58bc...

[2] http://exploringjs.com/es6/ch_template-literals.html

[3] https://github.com/Polymer/lit-html/blob/61c08a615abadbe58bc...


It's a bit disingenuous to say the templates are parsed with regular expressions. The way lit-html generates DOM Templates from strings is by letting the browser parse the string through innerHTML. The purpose of the regexes you are referring to is to find the correct insertion points for dynamic values in the template, and has nothing to do with the HTML parsing process.

There is nothing fundamentally wrong with using innerHTML to parse HTML strings. You use the same parser for the content of index.html, and I don't think anyone is advocating to replace index.html with a single script that creates these nodes using a virtualDOM type rendering system.


> It's a bit disingenuous to say the templates are parsed with regular expressions. The way lit-html generates DOM Templates from strings

"generates DOM templates from strings" <- this is what I'm talking about. lit-html literally:

- parses opaque string blobs [1]

- parses them with regexps [2]

- concatenates string chunks together [3]

- dumps the resulting string blob into DOM via .innerHtml [4]

So it does everything that was considered bad programming practices as early as 1999. And does all that at runtime.

> and has nothing to do with the HTML parsing process.

Yeah, no. This is literally parsing HTML with regexps. Because lit-html has to know whether a value is inside an HTML attribute, or inside a tag, for example. In order to know that it has to... well, parse the string that's passed to it. And what do you pass into lit-html? Oh, HTML. That it parses.

> I don't think anyone is advocating to replace index.html with a single script that creates these nodes using a virtualDOM type rendering system.

Yeah, you're apparently advocating to replace index.html with a function call that parses strings at runtime and dumps blobs of strings via innerHtml into DOM.

[1] Because tagged template literals are just function calls with lists of strings, and some values

[2] https://github.com/Polymer/lit-html/blob/master/src/lib/temp...

[3] https://github.com/Polymer/lit-html/blob/master/src/lib/temp...

[4] https://github.com/Polymer/lit-html/blob/master/src/lib/temp...


Yeah, lit-html scans template strings to determine what kind of markers to join them with - comments for text expressions, {{}} for attributes. This is before handing to the browsers HTML parser.

So what? You always pop up to complain about this, like it should be some obvious fatal flaw, but you never explain why it bothers you personally so much.

Does it make lit-html slower? No. lit-html scanning + native HTML parsing is faster than native JavaScript parsing of transformed JSX.

Are lit-html templates "opaque"? That's arguable. Tagged template literals were invented and added to browsers for a reason. lit-html takes advantage of a very nice browser feature, and then hands the result to the native HTML parser, which does understand them. I'd say it's no more opaque than compiled JSX: the browser has no way of knowing that those nested function calls represent HTML, so they're "opaque".

I'm going to continue to shrug every time you complain about this until you explain why it's even bad.


> So what? You always pop up to complain about this, like it should be some obvious fatal flaw, but you never explain why it bothers you personally so much.

I pop up to complain about this because I refuse to give in to mass delusion about what tagged template literals are. Others have said it much better than I have [1]:

"...we’ve learned not to write code in strings. You’d think this would be a fundamental law of software engineering... Writing code, not strings, means you can do everything to it that you can do to code. You can type check code. You can lint it. You can optimise it, compile it, validate it, syntax highlight it, format it with tools like Prettier, tree shake it"

Edit. Found another great quote [1.1]:

"The benefits of the component as plain, non-stringified data are not the avoidance of closing tags, but what you can do with those components computationally. E.g. instrumentation, behavior/attribute injections, configuration, filtering etc. An approach based on string interpolation can only go this far, whereas having everyting as arrays, objects, iterators your possibilities of composition & transformation are almost endless..."

> Does it make lit-html slower?

The problem isn't performance, is it.

> Are lit-html templates "opaque"? That's arguable.

It's not arguable. It's a simple fact of life.

Not a single piece of the entire tech stack involved in working with them knows what they contain: not the editor/IDE, not the bundler, not the JavaScript VM, not the browser. In case of lit-html they only stop being opaque when they get dumped into the DOM via innerHtml, and when the browser attempts to parse that string as HTML.

> I'd say it's no more opaque than compiled JSX: the browser has no way of knowing that those nested function calls represent HTML, so they're "opaque".

The browser has no idea that those blobs of string are HTML until you dump them into the DOM.

However, the browser knows a great deal more about the Javascript code that gets executed in it's VM.

> I'm going to continue to shrug every time you complain about this until you explain why it's even bad.

Above are some quotes from other users that express these concerns.

I can also quote myself from elsewhere [2]:

In a language that’s already a laughing stock for its insane dynamic type system, we said: “It’s all right, we’ll have all our code in strings now, thank you very much, and we’ll make sure we parse it at runtime because what can possibly go wrong”.

The only reason projects like lit-html, HTM and some others can boast about their “accomplishments” building fast, effecient libraries is because string handling has been insanely optimised by the modern Javascript VMs. And that .innerHTML is no longer the slowest operation on the DOM.

...

Why is this bad again?

Because this isn’t code. This is literally taking a bunch of opaque string blobs, parsing them at runtime, and producing some result. All of programming has been busy moving away from coding in strings and parsing stuff at runtime. For the past few years Javascript has been happily re-introducing the worst programming practices. And devs get away with it, too, just because modern Javascript VMs and browser DOM are optimised way more than they have any right to.

...

Since these are just arbitrary strings, no common tools will be able to lint them, analyse them, optimise them unless you write a very specific tool for this particular very specific string structure. And yes, that includes JS VMs.

...

You wanted macros? Here, have run-time string concatenation and regexp parsing, and stringly-typed everything.

[1] https://news.ycombinator.com/item?id=18511943

[1.1] https://news.ycombinator.com/item?id=18052072

[2] https://dmitriid.com/blog/2019/03/tagged-template-literals/


Honest question: How is React/vue/etc. different in this regard?


React is pure JS, no string parsing is involved at runtime (JSX is just function calls [1]).

Vue has its own templating language that gets compiled to function calls that are very similar to React’s [2]. I have my fair share of criticisms against Vue (as any templating system, it’s quite inconsistent[3]).

I don’t think any of them just dump string blobs via innerHtml. And I doubt any of them parse strings with regexps at runtime.

[1] https://reactjs.org/docs/react-without-jsx.html and https://overreacted.io/react-as-a-ui-runtime/ (specifically section on React elements)

[2] https://vuejs-tips.github.io/compiler/#v-else

[3] https://news.ycombinator.com/item?id=19199423


> React is pure JS, no string parsing is involved at runtime (JSX is just function calls [1]).

Why does this matter? React still eventually compiles down to DOM operations whether that be innerHTML or XML modifications.


To quote stevebmark [1]

--- quote ---

…we’ve learned not to write code in strings. You’d think this would be a fundamental law of software engineering

Writing code, not strings, means you can do everything to it that you can do to code. You can type check code. You can lint it. You can optimize it, compile it, validate it, syntax highlight it, format it with tools like Prettier, tree shake it…

--- end quote ---

https://news.ycombinator.com/item?id=18511943


Looks like there is a typescript plugin already [1], meaning this is not restricted to VS Code and should theoretically work in any editor with LSP support. That's better than I thought.

[1] https://www.npmjs.com/package/ts-lit-plugin


Web Components did replace frameworks for me. I built KanRails (https://www.kanrails.com/) with LitElement, without React/Vue/etc.

The alpha is at https://app.kanrails.com/signup. Again, it's in alpha. It is essentially a Trello + Google Forms + Workflow wannable.

How? Stick to patterns, not libraries. Check out https://pwa-starter-kit.polymer-project.org/ for LitElement starter kits. And just use Webpack, rip out the Polymer CLI. Oh, I also use Redux.


Just to elaborate a bit further to help fellow sojourners:

1) I use Webpack to bundle, still practically indispensable.

2) Redux state management. I use Redux-ORM to denormalize data but it has its own quirks.

3) Shadow DOM is on by default (both a curse and a great thing), which can be a problem with styling because your global CSS can't penetrate everywhere. What I do is have lots of CSS utils files (ala TailwindCSS), and import the utils as I need on demand. Drawback: Browser is parsing a lot more CSS than it needs to, as each component imports it's own CSS utils. Happy to hear about other approaches, but the browser really didn't break a sweat.

4) With Shadow DOM, you can use <slot></slot> to compose components.

5) Routing, see the starter kit for patterns, essentially it's a router pattern, not a router library.

6) DOM event bubbling is very useful (CustomEvent), I even threw in a small Pub/Sub library somewhere for sibling communication

7) You could use some sort of DI (dependency injection), currently using di-ninja which seems a bit overkill

Essentially, nothing much changed. Use the browser. Use JS. Use patterns. Use libraries as you see fit (watch that bloat).


"Stick to patterns, not libraries" - Such a simple statement, but concise as hell. It's whats been my mindset, but I haven't put it to words. Like normal DOM event bubbling is going to cover lots of use cases. When it doesn't, an event bus is crazy simple to write. A centralized data model can just be a static module. Need observables? Easy to write a simple one - otherwise there's likely a bazillion of them on npm. Not that I've used it, but it's not like Redux or MobX are restricted to React either


Right... why use an existing framework when you can just build your own!


So I tried web components two years ago, and it was very painful, and I crawled back to react.

Why should I invest my time in it now?

IE support? Are you kidding me?

I really wanted web components to take off, but they didn’t.

Without a new compelling narrative, I fail to see how they are “the future” in any meaningful sense.

Releasing an early version of something that is bad and doesn’t work (and let’s not pretend the shadow dom polyfill works, it doesn’t)... it’s just, not the right way to do this sort of stuff.


No more reason now than 2 years ago.


Browser specifications are not nearly as transient as proprietary frameworks. Web components will be here next year, five years from now, ten, and thirty years from now. We should focus on how we can take advantage of the new spec to enhance existing frameworks.

Popular projects like React use templates but require you to bundle the entire framework and the speed of the vDOM diffing happens at the speed of JS. What if it could take advantage of HTML templates to work at the speed of C++ by leveraging built-in browser support?

One of my hopes is that we can stop the bad trend of rewriting the same front-end components over and over again. Instead there could be a set of canonical components that people use for different web site types. If you're building an e-commerce checkout system, you could pull in the email address input built by Twitter, Stripe's credit card input, and the address input built by some person on GitHub that has 5,000 stars. Authors could leverage CSS properties and ShadowDOM for nice style hooks so developers could customize the branding.

The job of web frameworks could shift from "how do people build UI components" to "how do people build SPAs with routing, cookie auth, service worker caching, etc.". Not that current frameworks don't try to handle app level things but there is a lot more that could be done to make this easy for developers.

It would be nice to see web components as orthogonal to framework UI styling. We should be able to pull in web components from anywhere and frameworks should be smart enough to co-opt the components by treating them as native DOM elements (like div or span).

Sorry if this was sort of a rant I didn't have much time before work...


Forms are where web standards are most lacking. HTML5 took us from the stone age to the bronze age by adding some still-basically-useless inputs for e.g. colours and dates.

Everyone is reinventing the wheel over and over here and it's infuriating. I recently tried to find a good component to provide an internationalised currency input - it's incredibly difficult to find a quality implementation for this, yet it's something that the vast majority of web applications will need to use at least once. Same goes for phone numbers.

It would be nice to see web components take these roles away from frameworks. It would be nicer to see web standards identify the importance of many of these inputs in the first place.


I strongly believe Web Components will catch on, but not in its vanilla form. Writing code for them is a pain in the ass for non-trivial stuff.

They're too low level compared to modern frameworks.

IMO the future of the web will be about compiling React, Vue, Svelte, to Web Components, for interoperability reasons. And nope, Polymer isn't as good as any of those.


I worked with Polymer-based components ~2 years ago (an eternity in frontend-land), and I want to share my biggest pain point: you may want to integrate a `<cool-carousel>`, but it does not "look right" in your design (eg white website, but the carousel has a black background). If the author did not set up CSS variables, you have to either try overriding stuff, or fork it. This problem is why every organization (eg GE with Predix or Electronic Arts) had to create their own components, so they can share the same "art style"/design. Can you share your experience about that?


No matter the underlying technology, "lightweight, truly reusable UI components" is almost an ideologic dream, at the web scale. (some companies might achieve it on their own scale with a lot of effort, but not sure for how many years)

As the maintainer, you don't want to cave in and add every possible configuration option people ask for so you have to decide what's a good, thin API for your component and it will never be enough for some usages. Styles are that much more subjective and even vary with design trends over the years!

It might be possible for very, very simple components like text inputs but then again, those are also the simplest to code directly in your framework, so you could wonder, why bother with an inferior programming paradigm in the first place?

The sweet spot for web components really seems tiny.


In the instance of Predix (I peripherally worked on that during my time at GE) and likely EA and every other large Web Component ecosystem you're thinking of, that's desired behavior. The real want is a design system such that things look consistent, but as design systems are CSS only, they aren't smart enough for interactions that require JS. So then the need for a design system becomes a need for components of some kind that include the design. You're looking for components with more adaptable design, but that's just not the intention of these ecosystems. If done with that goal, yes CSS vars take you a little bit of the way, but I think we'll see more power coming to help out soon with Shadow Parts/Theme, CSS Modules, and Scoped Stylesheets. But really, just styling a background? If the component author just left the background: none, you could do whatever you wanted from the outside. It just takes planning - even without the Shadow DOM you still need to plan for proper themeing.


"styling a background" is just an example - I admit it is a bad one (glad I don't work in frontend anymore). I will read about CSS Modules and the other stuff you mentioned. Thank you.


Sure thing! Those things are def up and coming, and I'll admit I haven't looked into them so much yet, but they are being designed to solve this very problem. I don't think that Web Components are the tool to solve every problem, but I've been a fan for a while (so much so that I'm writing a book)


As others have already answered styling into Components is still hard, but there are answers coming soon with part/theme and Scoped Stylesheets.

Also, ZephJS, the Web Components library I am championing, has the ability to inherit from another ZephJS element which allows one to add to or even completely replace the styles for the new element without any special css magic. So if I want to style <acme-text-field> I simply inherit from it in my new <my-text-field> and I can style however I want.

https://gist.github.com/arei/8083a6270e704b830c68a2020f3e5e3...


ZephJS looks cool, will try it soon. Thank you!


Web Components are an anti-pattern


Please expand on this point?


Web components will never take off because they are HTML-first and rely on DOM apis.

The reason React is so popular and the reason it dethroned Angular, Backbone, etc. is because it is JavaScript-first. In other words, it gives you the power of a proper programming language to build UIs.


Web components are awesome I've been using them in production using StencilJS for a pretty large app for about a year now. Even though browser support is widely available there are still a few gotchas with web components, specially Shadow DOM. Not all community tools have caught up as well. For example you can't use Stripe v3 with Shadow DOM. Most analytics tools also cannot access the Shadow DOM. We had to remove Shadow DOM from all our components that were using it. In my opinion Web Components are definitely the future but there's still some catching up to do before we can claim it can replace frameworks.


You might be interested in https://github.com/bennypowers/stripe-elements Stripe v3 with Shadow DOM.


Thanks I had actually seen this while looking into a workaround for us. However I thought that LitHTML elements only worked with other LitHTML elements since you need the correct bundler for it. StencilJS projects don't have any bundling system.


LitHTML and LitElement don't need a specific bundler, they work with whatever tools (or not) you'd like. You might want to get them another look!


I think that the author misses the point.

The question is how can we build better frontend apps and not should we use frameworks or not. In the end there are only tools for different purposes.

Context and history are important to fully grasp WebComponents.

WebComponents arose when there was jQuery and decoupling of CSS, HTML and JS.

If you look back 10 years, there was no real separation of concern and Web purists like today always disliked the idea of mixing CSS in JS.

Then came NodeJS and frontend build tools started to provide better tools (GruntJS etc.) for compile time checks. Encapsulating CSS in JS for example solved the problem of overuse of id selectors, greedy class selectors and namespace collisions - domains that WebComponents tries to solve with Shadow DOM etc.

Todays frontend frameworks in combination with the underlying build tools provide a lot of the abstraction that WebComponents want to give developers. So I would rather say that WC are another tool which can be used by modern frameworks.

It is like saying air pollution can be solved by driving slower on highways when there are only combustion engines. Why should teslas be punished for the wrong reasons? Same goes for WebComponents. Good idea, great abstraction but context is important.


A couple of days ago I saw a project here called pika which is any npm package it seems running in the browser, it's interesting to have the web components + pika where we can bring in different modules from npm and combine that with the power of web components then there really is no need for other frameworks but.. it brings that problem we used to have with JQuery which is lack of standards.. it seems we keep on going around in circles but web components are a lot faster and easier then React or Preact.. and the routing thing just makes everything fat for the bundles... then you have to worry about bundle splitting... the main/core bundle... pika is a good one because it takes the bundling off the bat and makes everything easier without the routing.. I now wish for a standard with web components and pika and doing the polyfilling... and ... material framework... and.. some coding standards just so we don't get a mix of Jquery and react and preact and a lot more in one single page load.


I don’t understand the push to make userland component abstractions into native primitives. It’s perfectly fine for the browser to just implement low level primitives for frameworks like React to build on top of. It allows the framework to develop much faster.

Web components kind of miss a lot of the reasons why React has taken off. Encapsulation is one thing but it’s the declarative way of handling state, effects, and the DOM that make it powerful. Web components would need a framework on top of it to make it usable by developers building anything significant.


They aren't trying to solve the same problems. The main problem they solve, that no other userland framework solves, is that I can now share a collection of my rich JavaScript components with every single web developer in the world regardless of the technology they build web apps with.


I can imagine a world where this would be useful, being able to drop something in as easy as a <select/> element seems fine.

It seems useful for UI primitives, like a dialog, tooltip etc, that the browsers might not implement as native elements themselves. But as a building block for creating entire applications? I don’t think so.

Which means they’re always going to need to hook into the framework that’s rendering them, either to connect state, managing effects, or for styling.

I just don’t see sharing a component regardless of framework as a major problem worth solving right now. Buy into a framework and community like React and you can just drop components into your app. It’s not framework-agnostic but it works.


I would rather have browser provide rich components then rely on third party.


That's one of the huge benefits of web components -- third parties can iterate quickly to find useful patterns, then browsers can just standardize the best/most popular ones. The old way of discussing ad nauseam in committee then implementing straight in the browser gave much less useful elements. (And it's much less straightforward to convert a popular React component into something browsers could implement natively.)


> hird parties can iterate quickly to find useful patterns, then browsers can just standardize the best/most popular ones.

I'm looking at hundreds of date pickers, carousels, autocompletes, customizable selects, data tables, modals (e.g. for media previews). They've been around for as long as there have been browsers (so, thrity years or so).

Can you point at any standardisation effort around any of these commonly repeated patterns?

input type="date" and input type="color" are only now barely making it into the browser.


This article, the HN comments here, as well as comments on /r/javascript, are helping to solidify my view that way too many frontend developers don't know enough about what they're talking about.

I really don't get the disdain against Web Components and their related APIs. Why even fewer people are excited about custom elements alone sort of baffles me.

WC's aren't intended to replace frameworks and libraries. It's there to provide some universal primitives for writing components, and a lot of components aren't actually complex enough to warrant all the heavy lifting that comes with things like React and Vue. Those tools are great, but I also really love the idea that I can write useful components without having to import a bunch of extras(eventually the polyfills will be obsolete).

The innerHTML function can be slow if your code is sloppy and you're applying it to the wrong problem. Yes, you might need a data-aware renderer like the one in React, but often times you might not. For a lot of simple things, you can render elements without it by using createElement(), append(), insertBefore(), insertAdjacentElement(), cloneNode(), etc. They're not hard to use, but they're not pretty like a templating language, and they're not going to surround you in bubble wrap. I'm not saying that those tools scale for bigger projects, but there are plenty of small things you could write using Web Component technology. It has its place.

If you do things like call innerHTML multiple times in a loop, when you really could concatenate your HTML and call innerHTML once, is fundamentally going to perform badly, but web developers seem to write that kind of terribly-performing code in all sorts of cases and when it runs like crap they just assume that they need to import a library that will use tricks to cover up their lousy code. It reminds me of how folks will write a pile of garbage with Rails, switch to Phoenix because their Rails app is slow, and then claim that Rails sucks at performance. That's not to say that Phoenix doesn't have clear performance advantages, but the claim that Rails is slow often comes from a place of ignorance. A lot of jobs warrant useful tools like Vue, but then again, maybe your code just isn't very good. It's really embarrassing how many of us don't write code to be efficient, opting to always stand on the shoulders of giants who do the hard work to make our lousy code appear to run fast.


CSS is still a pain in Web Components. Constructable stylesheets solve that problem, but they're still in the "Worth Prototyping" stage for Firefox.

https://mozilla.github.io/standards-positions/


I argued for a similar case last year[1], however the missing piece right now is updating state in a clean way. Web Components definitely won't replace current front-end frameworks, but combined with ES Modules the web is getting to a good place for resuable primitives. :)

[1] https://andrewrabon.com/the-case-for-react-like-web-componen...


Be sure to checkout lit-html and LitElement (https://lit-html.polymer-project.org & https://lit-element.polymer-project.org)...what you've written about here already exists!


Also give StencilJS a look. It's a compiler instead of a framework or library. The end result is pure vanilla components https://stenciljs.com/


It's insane to me that everything Polymer was got reduced to LitElement which is basically a complete copy of React without React and without the immeasurable support of typescript, VSCode support IN the view and debugging directly in the TSX.



Yeah, I didn't really understand why there was a need for an overhaul like that. I honestly was hoping that there'd be a better story for databinding, types, etc. I just gave up and went back to React.


Polymer was trying to do too much (to be a framework), and the quality was average at best.

LitElement is able to focus on providing the best base class to build a Web Component. I think it is almost there.


The lit-element package comes with typescript decorators.


As expected, no mention of server-side rendering.


This was exactly the reason I’ve abandoned them. As mentioned in other comments, they look like a good way to create a design/component system in them, because of the interop with any frontend JS framework (who doesn’t want that?!). So you deal with clunky CSS sharing and theming capabilities and there might be some solutions on the horizon. But now you want to build a static website with it (landing page, docs, blog…) and you can’t pre-render them, because there is no declarative Shadow DOM element https://github.com/w3c/webcomponents/blob/gh-pages/proposals... (rejected https://github.com/whatwg/dom/issues/510). Yeah, you can pre-render them without the Shadow DOM. Then if you want to make those chunks of HTML into WCT on load (sort of rehydration), it will trigger repaints, as you have to remove the chunk of HTML, put it into WCT and parse everything again. Or you don’t put it into Shadow Root, to prevent repaint - but at that point, if your components can work this way, why even use WCT?


You can server side render a `video` element just the same way you would a `custom-element`. We've been doing it for years and there's no reason to think anything about that has changed. If you're looking to deep SSR which is arguable as far as benefit, check out approaches like https://github.com/ionic-team/stencil-ssr-starter


I think the difference is that the browser already contains the shadow dom needed to render the video tag. But for a custom tag it would need to fetch, parse and execute your component code before it can begin to render.


That's an interesting read. I'm thinking on whether the real question is what is the declarative difference between the video tag, which by normal application lets everyone feel find about that content hidden by the shadow DOM vs the APIs we're developing for our custom elements. There seems to be an important piece of learning, not just for SSR, but for custom element development in general, that I think we can build off of.


Server-side rendering should be JavaScript free and done in battle tested framework (TM) since the early 2000's, plenty to chose from.


Being native to the browser, how fast is it compared to React? It is 10x faster because it's native? Is it on par, with room for browsers to improve it's performance even further?

I'm all for something that's native to the browser.

Right now you write a `<p>` tag for a paragraph element. No question about it. Imagine if you needed to use a P-tag library just to render a paragraph tag? Of course not right, you would just use the native browser `<p>` tag. I think that React is a P-tag library in essence.

I would go all-in for a native version of "frontend framework".


I totally agree - we need "one framework to rule them all". I don't want to learn another 10 technologies we won't use anymore in 5-10 years.


I wonder why HTML never got includes.

It would be so nice to just write:

    <include src="footer.html">
On Hacker News, for the first pageview, this would load the whole "Guidelines | FAQ | Support ..." section. On all other pageloads, the browser would already have it in the cache. So it does not have to be loaded again.

Building complex websites would become so much nicer. Because each part of a page would be an include.


There are html "includes" in Chrome, used as such:

<link rel="import" href="/path/to/file.html">

But alas, Google was not able to convince other browser vendors to adopt them, and they will be removed from Chrome 75.


If you are looking for just a simple load some html and replace this where my <include> tag is kind of thing you are right, nothing does that because it’s more complicated then that... what about the styles of the included html? What about the behaviors (JavaScript) for it. How does that translate with the include?

But, if you use Web Components, organize your code, and plan ahead, this is very doable today with Web Components. You just create say a <reddit-footer> component complete with style and behavior, and then drop that into your page html along with an import of the component definition. It’s clean and simple and the encapsulation of all your footer needs in one place is really nice.

ZephJS, the library I am promoting, or another Web Component engine, makes this even easier and allows your components to be bundle yup really nicely. ZephJS, for example, offers a cli bundler command that does this (via rollup) and it makes for a really clean component experience. https://gist.github.com/arei/8083a6270e704b830c68a2020f3e5e3...

B


    It’s clean and simple
How so? What is the Web Components equivalent of <include src="footer.html">?


As an example HN here on might structure things like this:

<script src="./hn-components.js"></script> <hn-header></hn-header> ... all the main body content ... <hn-footer></hn-footer>

To answer your direct question, the WC equivalent of <include> is the <script> tag. The <script> loads the component definition and all the resources related to them (See ZephJS for how this is super easy to do: https://gist.github.com/arei/8083a6270e704b830c68a2020f3e5e3...)

<hn-header> and <hn-footer> are defined in the script. They carry with them all the content, layout, and behavior for those parts of the site. This provides a nice clean separation between the page and the header and footer pieces. Changing the header or footer becomes just changing those parts. This is absolutely easier then using react or angular for the equivalent kind of things. Does it provide all that react/angular does, of course not. But it is infinitely cleaner then using either. Especially with ZephJS (gratuitous plug).


    the WC equivalent of <include> is the <script> tag
I beg to differ. My <include src="footer.html"> would insert the html in the footer.html file. While <script src="components.js"></script> will execute javascript. Then the javascript has to somehow prepare magic so that <hn-footer> will be replaced by some html.

The link to the library you gave does not help here. Because I am thinking about browser technology here. What has to go into components.js (without using a library) to make <hn-footer> be replaced with the html in footer.html?


Because that would cause cascade of tens or even hundreds of http requests just to download the html.

On the other hand new JS modules work like that, this is less of a problem on http2 and also can be mitigated by tooling.


Frameset / iframe?


You are right. IFrame creates an almost but not totally isolated page-environment. So in a sense IFrames are 'web-components".

So what can Web-components offer over that? A simpler way of including them on a page with a single tag. Well, you must load the js-file too but a single js-file could contain multiple web-components I assume.

The whole (?) point of components is isolating the interface from implementation, encapsulation, which WebComponents does nicely by providing a standard way of writing methods of the underlying ES6 class.

We could say that WebComponents are smarter IFrames with a cleaner way to declare their interface.

Another great thing about WebComponents is extending existing tags which makes it easy to prototype improvements to existing tags. For instance I wonder if IFrame could be made better by creating a web-component that extends them?


I think a lot of you are missing the point of Web Components here. They're not going to replace React et. al for huge frontend applications. But they are a great solution to drop in for a lot of projects where you need things like:

- Sliders

- Lazy loading images

- Complex select dropdowns

Rather than having to import a js file, css file, and use some weird wrapper around the existing DOM we have, we can import one file and be done with it.


I agree, your examples seem to be prime use cases of Web Components. The original post though makes the claim that WCs are ready to replace your entire framework.


You are only thinking of one frontend, React allows a multitude of renderers, even the command line [0].

It has great tooling, awesome community, and it's pushed the boundaries of how we thought frontend development.

https://github.com/Yomguithereal/react-blessed


Ploymer was a crapshow and HTML import a nightmare for load times. Unless some sort of topology bundling is provided for web components I'm out. We tried to do generic components for multiple frameworks based in webcomponets and it was an utter failure in practice especially for low band networks.


Even from the beginning of Polymer and it's use of HTML Imports there were tools for bundling them and they worked great! It's even easier to find the right tool for you now that ES Modules deliver the power of web components with the help of your favorite Rollup or Webpack configs and plugins...

https://open-wc.org/building/


To be fair, HTML imports is deprecated and won't be standardised. The recommended way to package web components now is with ES modules, and they can be bundled (with eg. Rollup or Webpack.)


That is great, but I am still 100% sceptical of a web component intergration with any given framework. Is the integration point opinounated? Is it reactive, callbacks? Two way bindings? What does the application lifecycle look like? Would it be just opiononated sets of components? I just don't know... If I'm wrapping web components to meet our design patterns then why bother at all? I feel like the entire web component concept from an API level is a great concept but just not there for real world at scale consumption. I may just be not optimistic about it all.


It seems that it's not about binding but that devs need to take of it themselves. On the other hand, I guess you first need to generic interface to bind on and then it's possible to take care of bindings.

That said, I think nobody needs any framework any more if some automatic binding mechanism would get standardized. At least for apps that routinely instantiate and destroy components would profit from that a lot.


Allow me to float ZephJS at you as an example of a Web Component framework with a bundling tool to do what you describe. Simplifies everything about building Web Components.

Introduction: https://gist.github.com/arei/8083a6270e704b830c68a2020f3e5e3...

Bundling specifically: https://github.com/awesomeeng/zephjs/blob/master/docs/Compon...


This looks pretty cool, thanks for sharing.


I don't get the hate for web components. I think they are amazing. A number of times I just wanted a damn date picker, not a framework that changes how I'm making my website! Web components provide exactly that.


I agree. But there's always "hatred" for anything new which requires people yet again to learn new ways. I understand that. But there's nothing more difficult to stop than an idea whose time has come. I think that was from a Funkadelic LP-cover :-)


One thing that is particularly important to take into account when comparing web components to framework is that they can and should work together. If indeed "web components" replace your "framework" it will most likely be because a new framework that takes advantage of web components and all that the web is now replaces your old framework. Already libraries that combine popular concepts like hooks from React with web components (https://github.com/matthewp/haunted) are pointing the way to a more powerful future for both site that need just that little extra something via a stand alone web component or a whole family of components wedded to a framework into a rich application. That being said, don't get confused by people on either side being overly defensive of their place in the web ecosystem things are they are now will change. Techniques will grow and merge and there will be something else that is "the thing" before too long. Web components will likely be as much a part of that as the elements who's shoulders they stand on (e.g. <select/> and <video/>). That's the power of the web.


True. One more thing about web-components is that they are a standard. Vue, React, JQuery are not.


No. WCs can only replace one aspect of React or Vue. You still need a better way to manipulate the dom and react to data changes than pure vanilla.


I wish the ideas of the Elm Architecture (or React/Redux) could be brought to the browser. Primarily, an atomic single source of truth (serializable data) for window.document and a way to connect that state to the DOM through pure functions so that we can avoid local component state that then has to be orchestrated with references, event buses, etc.


At least for current Web Component API, no.

Html is good because it's declarative, but it's not good since it lack abstraction. So React combine JSX template and lambda as declarative component. Means you have parametrized template and loop etc.

Vanilla and jQuery is not so good because it's not reactive by default, which means you're not always describing things you want, instead you have to update something. Eventually you will forget some. It's called imperative.

Current Web Components spec include attribute changed hooks but it's far from React since most of the APIs are imperative.

But why declarity matters? Because it turns out front-end world is totally different from request-response backend programming. Because in front-end you're dealing with continuous sequence of signals instead of one off requests. Declarative style makes you describe the relation between model, views and derived values, not how to update or maintain those relations.


It's not about implementation details, it's about programming paradigm. In the case of React, it's

- Declarative, functional API to write reuseable UI.

- REAL reusable business logic with React Hooks.

- REAL universal data fetching with React Suspense.

- REAL error boundary with Error Boundary.

- Learn once, write everywhere!

Do Web Components have the above benefits (yet) ?


Of course not. But many smaller apps don't need all of those.

Think about HTML how it started it was very rudimentary. At that point there was very many better "frameworks" for creating GUIs and applications. Yet HTML was in many cases good enough and since it was so simple it was able to evolve.


I see a header and a footer and a big blank page. Whatever the author is using to replace his front end currently doesn't work on my iPad Air.

But in answer to the question, no. I doubt it. I tried building a site using polymer when if first came out. It was harder than the in house thing I'd previously been using and after about a year, the spec had moved on and my site looked like this author's blog: a big white page and some JavaScript errors.

I'm not the sort of person who enjoys rewriting my app every year to suit the whims of the framework it's on top of, so my plan is to emit boring HTML until something equally stable yet better comes along.


I've written a couple of smaller and larger apps in Angular 1 and 2, Vue, React, Polymer and recently trying out lit-element and it solves pretty much all my needs. I like the typescript decorators for properties and elements and that is the only reason for which I need Webpack. Redux, the part of it I need which is updating from a central store, I replaced with about 20 lines of javascript.

Because of how good web components in their current state are my very personal opinion is that the other frameworks I have written code in solve yesterday's problems and are very likely to become the future jQuerys.


Given that they were introduced in 2011, and in regards to their usage you hear... well crickets

I think we can safely say that web components have failed.

It doesn’t look similar to React at all, and still suffers from the same issues that jQuery does.


> Given that they were introduced in 2011, and in regards to their usage you hear... well crickets

> I think we can safely say that web components have failed.

> It doesn’t look similar to React at all, and still suffers from the same issues that jQuery does.

jQuery? I think your just making up nonsense there.

Fully ten percent of the web is using web components at this typing, and it's continued growth is steady as more and more libraries and frameworks, excepting those least able to easily leverage them, bring them into the their own projects. YouTube, ING, McDonald's, and other adopters are some pretty loud crickets.


Nope, no nonsense, but the issue has already been repeated in a bunch of comments here, so I don’t really need to any more.

> Fully ten percent

Citation needed. I’m sure it could be true, but it seems a high number for something that I’ve literally heard about for the first time today.


Repeating what? The same outdated, misrepresented arguments mainly relied on by react fandom? It's simple, lot's of options out there. If comfort and loyalty clearly takes precedence over best solutions, you've already made the decision. The problem isn't that web components failed, or you can't pass objects via props, or that you think you need polymer, or their not browser supported, or they actually adapt in most existing Frameworks. The problem is turf, and react loves its turf. Just point out that arguing from a position of 5 year old specs, adoption, and knowledge isn't, IMO, very wise. Rather a self inflicted lost opportunity.


I think this is an excellent thorough presentation of WebComponents. One think I didn't quite understand was the first example about which it is said:

"I have created a web component which lazily loads an image once it is fully visible in the browser's viewport"

Once the image is "fully visible", what's the point of "loading it"? Doesn't it go the other way first you load it then it becomes visible?


Web Components are an ideal complement to pure statically typed languages like Elm, where it's a bit of a hassle to implement simple, isolated components.

An example would be: a text paragraph which has "read more" button, when clicked, expands. Or an info popup with a "close" button. No need to put its state in your model and forward its messages.


The shadow dom is just JavaScript, HTML and CSS. For any significantly sized component I would want a framework to wrangle all that.


I don't really think end-devs are the target audience for Web Components. I see two users that will benefit:

* Framework/library authors that now have a higher-level and hopefully more performant primitives to build on.

* Widget library authors that can now design component libraries that can used by any framework.


That's the case when a title is enough to see the author has no idea what he's talking about, that's convenient!


No.

But they could make frameworks like Bootstrap much easier to use.

CSS is the top. WC are the bottom.

React, Angular, Vue and company are the "between".


It's a good development but this article is misleading and ignorant. Web Components cannot replace web frameworks like ReactJs, Angular or Vue. At least not yet. Im not sure if this guy have used any of these frameworks before.


CMS static site builder based off of Web components https://github.com/elmsln/HAXcms


wasm and wasi will eventually take over enabling higher level languages such as C#, Java and Python to be used at frontend (Blazor project is an example).

As Mr. Bernhardt says: JavaScript had to be bad for the evolution to happen. (https://www.destroyallsoftware.com/talks/the-birth-and-death...)


The page renders as a big white nothing in Edge and IE.

Works in Firefox.

I wonder does it use web components the article is about?


When i download static html from a webserver, it just draws it straight to the screen


When you write something like this please include a date of publication.




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

Search: