
The broken promise of Web Components - dmitriid
https://dmitriid.com/blog/2017/03/the-broken-promise-of-web-components/
======
acdha
The assertions about the DOM are long on hyperbole but rely on e.g. benchmarks
from a decade ago and broad hyperbole like:

“This was cumbersome. This was limiting. You could not prototype easily and
quickly. You could not easily escape the limitations of UI libraries. etc.
etc. etc.”

It would have been far more interesting to look at whether the broadest claims
were even true, or why people ran into problems using various libraries. Every
time I've done a test, React is significantly slower than using standard
JavaScript + DOM but that's the wrong question to ask when you really care
about whether it's a) fast enough and b) helping you write code faster,
reducing maintenance or sharing costs, etc.

All I got from this is that using React makes life easier than calling the DOM
APIs directly every time, which is technically true but doesn't say anything
about e.g. how WebComponents compare when using abstraction following the best
practices of software developers since something like the 1950s.

The “easy-peasy” example is:

    
    
        ['Hello', 'world'].map((text) => {
            return <p><span>{text}</span></p>
        })
    

The alternative given is:

    
    
        ['Hello', 'world'].forEach(text => {
        	const p = document.createElement('p')
        	const span = document.createElement('span')
        	span.textContent(text)
        	p.appendChild(span)
    	
        	MyComponent.appendChild(p)
        })
    

Since the first example requires 140KB of React code plus a ton of setup code
to get to that it's either careless or dishonest to compare the two without
acknowledging the possibility of using a helper function or two to simplify
the second one, as JavaScript developers have been doing routinely for
multiple decades.

Again, not a slam on React, just this kind of unhelpful advocacy. It'd be a
lot more interesting to compare real examples with multiple libraries and talk
about how the different choices impact debugging, performance, isolation, etc.

~~~
jondubois
Yes, it's like with JavaScript itself, it had some issues in the past, all the
big issues were resolved but the stigma is still there.

I can't see any fundamental reason why generating the DOM with React would be
faster than generating the DOM with Web Components - They're doing the same
thing; it's a matter of time before they even out (if they haven't already).

I think that Web Components would end up faster ultimately due to native
browser support (more room to optimise).

~~~
kbenson
> Yes, it's like with JavaScript itself, it had some issues in the past, all
> the big issues were resolved but the stigma is still there.

Honest question, because I use Javascript just infrequently enough to have to
look this up every time (and it's possible the reported solutions are old), is
there a good concise universal way (or two, at most) to determine the type of
the variable I may have? It seems it's always a tossup between typeof,
instanceof, == null and == undefined, and to my eyes that's _way too many_.

~~~
comex
A somewhat more succinct option could be to coerce to Object and then use
instanceof: 'Object(x) instanceof String'. Or you could use
Object.getPrototypeOf, which coerces to Object automatically these days. But
null and undefined are special: calling Object on them returns {}, and calling
Object.getPrototypeOf on them throws.

If the type you're testing for is not one of the builtin literal types, you
can just use instanceof.

~~~
kbenson
"Object(foo) instanceof Class" does seem to be the most definitive, but
unfortunately seems to require specific testing against a literal that must
exist or it throws, and doesn't work for null/undefined. That at least brings
the things I need to know to check the type of something down to three, two of
which are singular special cases (if somewhat common ones), so that's _better_
and possibly _adequate_ , if not what I would consider _good_. Then again, I'm
not sure I'm capable of thinking it could achieve good while there exists both
an undefined and null in the language. It still boggles my mind that it has
both.

~~~
comex
To clarify, by "literal that must exist or it throws" you mean that you don't
know whether the class you're testing for exists? Testing against an invalid
class would be an error in most languages…

I guess an alternative is foo.constructor and foo.constructor.name, which will
give you a string if you want that.

~~~
kbenson
Since many different js libraries may be loaded from many different sources, I
could envision a situation where some utility functions may want to support
different inputs depending on what's passed in, and what's passed in might
depend on what's loaded, and what's loaded can change at runtime.

That's why many dynamic languages allow access to the type through a string
representation.

------
ImJasonH
> you can substitute your favorite library: Inferno, Preact, Vue, snabbdom,
> virtual-dom (or non-js libraries and frameworks like Elm, Om, etc.).
> Similarly, replace Polymer with Vaadin, or X-Tag, or…

It's gotten to the point where if you list JS frameworks, you can slip in 2-3
that don't exist and I don't think anybody would notice.

~~~
pc2g4d
I only recognized... I guess 3 of these. A bunch of them could be total
nonsense and I have no idea.

~~~
dmitriid
Some of them I knew or I thought I knew. They came up when I was "researching"
for the article :)

------
Touche
This article is trash. In retrospect it was a huge waste to coin the term "web
component", by doing so the expectation is that web components eliminate all
need for 3rd party JS libraries, which as the article points out, they don't.
Instead "web components" is a set of low-level libraries that provide bits and
pieces of stuff needed to make components.

The article makes the usual criticism that web components doesn't have a
databinding spec. It's true, it's a short coming. But the lack of a
databinding spec doesn't make Shadow DOM any less useful. The two are
unrelated.

The author really likes JSX, but didn't bother to google "jsx web components";
if he had he might have come across this:
[https://skatejs.gitbooks.io/skatejs/content/](https://skatejs.gitbooks.io/skatejs/content/)

There are some real things to criticize about web components. Shadow DOM makes
it hard to theme your app. Custom elements has some warts in regards to the
way that some events are composed. But the article doesnt make these
criticisms.

~~~
floatboth
Yep, the criticisms are just bad. "Attributes are strings", seriously? Uh, DOM
elements in the browser have these things called JavaScript attributes…

> Shadow DOM makes it hard to theme your app.

Polymer uses CSS custom properties for this and it's not even hard, it's
pretty cool, it's like you're making a CSS API for theming <your-element>.

~~~
jakelazaroff
> Uh, DOM elements in the browser have these things called JavaScript
> attributes…

Could you please link to a reference? I've never heard of JavaScript
attributes and I can't find any reference on MDN.

~~~
e111077
I think that person is talking about the HTMLElement interface is essentially
a JS object and how you can set properties on it. e.g.

    
    
      element.foo = 123;
    

vs

    
    
      element.setAttribute('foo', '123');

~~~
floatboth
Exactly. I accidentally wrote "attributes" instead of "properties" :D

------
diminish
My team is using web components, polymer 1, 2, React, Vue and Riot in 3
strategic projects.

I have a bigger rant about web components, and polymer and interesting enough,
I believe - none except one - of the article owner's comments matter much.

Here's another rant and what currently sucks at web components (for us)

1\. Still no adequate browser support coverage (OP's point) \- Google polymer
team keeps the mood up, is excited and does great things but we're still
waiting

\-- for Firefox to support it, (which declined to implement html imports). I
kind of think Mozilla is sabotaging the efforts for some political reason
after reading their comments.

\-- for Safari 10.2 to support it natively

\-- for Edge to care.

Unless all the browsers support the v1 spec, we end up being just another JS
framework and the Polyfill webcomponent-lite.js itself becomes a framework in
competition with vue, react, riot, and others.

2\. Web components (especially) polymer ones are not a good citizen inside an
HTML page next to others.

\-- Due to component scoping (which is ok), style scoping in the main document
css (custom style) (which is weird) and DOM and shadow dom, you end up feeling
hopeless at some point.

\-- I just want to use the paper-toggle and I end up downloading 100s of
files.

3\. The opposite of "it just works" ( as someone wrote somewhere, kind of,
like you invented the opposite of it just works.)

\- Polymer, and the paper, iron and other libraries are cool, but they somehow
fail silently and often. It's hard to figure out what went wrong.

4\. Polymer team is trying to replicate the cool other JS tech and tools, and
it just lags behind. (ES6 in polymer 2.0, the still beta app router, bower,
gulp and OMG.js ....)

5\. The iron, and then paper, and other elements are too heavily
interdependent and no other leaner library or collection appears in sight.

\- A lot of nested imports

\- and the hopeless the wait for HTTP/2 and the future web of 2020s.

I will write later what can be done.

~~~
dmitriid
One of the main problems I have is that, well, if buy into Polymer, that's
what you buy into: yet another vendor lock in. Otherwise you wouldn't even be
able to write a simple Todo List: [https://github.com/PolymerLabs/todo-
list/blob/master/app/ind...](https://github.com/PolymerLabs/todo-
list/blob/master/app/index.html) (all the {{}}'s etc.)

And then... They are really not different from React/Angular/<add your own> :)

~~~
spankalee
It's completely different. With Web Components you can start migrating away by
using components just not written in Polymer.

How is that anything like React or Angular that really don't let you interop
with other libraries out of the box?

~~~
danabramov
Could you clarify what you mean by "don't let you interop"? React gives you a
DOM node so you can render anything into it, including an Angular component, a
jQuery plugin, or a web component. How is that not interop?

------
EdSharkey
Web Components are damned awkward because they extend the damned awkwardness
of the DOM rather than address it.

DOMNodes are these hot data structures when they're linked into the DOM tree.
Writing (and even sometimes _reading_ ) from DOMNodes can cause whole page
reflows or paints to occur, sometimes synchronously. The advice to "touch the
DOM as little as possible" stems from the fact that the DOM has so many
performance pitfalls.

The DOM is so damned awkward that it's faster to maintain a virtual DOM tree,
diff changes to it on the next tick with those of the previous, and then only
modify the real DOM tree with those changes like React does. Couple that to
the fact that React's DOM update strategy is tuned for speed and they can
hide/handle most weird DOM object creation/insertion rules, and overall you
wind up with a less awkward system.

If I compose my page entirely out of Web Components, the chief benefit I see
is good looking markup representative of what's on the page.

If I were to have designed a component system from DOM, I would have added a
lightweight iframe-like tag that could be instantiated from a
script/css/markup template package. Performance-wise, I thought that having a
nested element's box be laid out and painted independently from the parent
page could mitigate some of the global ripple effects of touching the DOM. Of
course, this lite iframe's box itself would need to live in the parent page
and its dimensions would have to factor into the page flow, and that could
have global effects. I suspect there could be clever JavaScript or event
system additions that would help limit the reflow and paint damage there.

~~~
Touche
> The DOM is so damned awkward that it's faster to maintain a virtual DOM
> tree, diff changes to it on the next tick with those of the previous, and
> then only modify the real DOM tree with those changes like React does.

Sorry, but it's not. I don't know what it is that you think React does, but it
makes those same awkward DOM API calls. React is an abstraction layer and
abstraction has a price. Having React call .appendChild is not faster than you
calling .appendChild yourself.

~~~
jakelazaroff
The strength of using a virtual DOM as an abstraction isn't that you get
around making DOM API calls, but that you can easily batch and sequence them
to eke out the best performance. To use your .appendChild example: if you
iteratively call .appendChild the browser has to reflow every time that
happens, whereas if you know you have a bunch of elements to add you can use
another strategy (like document fragments) to do that manipulation all at
once.

Yeah, you can do this all on your own, but you get it with React for free.
Abstraction does not necessarily have a price.

~~~
Touche
I wasn't judging virtual DOM has wholly good or wholly bad, just pointing out
the often incorrect belief that some how React does a magical thing that you
are unable to do yourself. Batching, etc. is no different. The advantage in
the abstraction is that it makes it a bit easier to maintain, not that its
faster.

------
weego
I mean who cares, really. 90% of developers will spend time building reusable
components that will be used exactly once, and and some people will open
source some stuff that wedges in every suggestion and pull so it is 5 times
the complexity any one person ever needs and then we will talk about the
failed promise of web components.

~~~
jakelazaroff
I don't think the thesis of the article is that it hinders reusability, though
— it's that anything built on the DOM presents significant limitations
compared to what we can do with JavaScript.

The example of passing dynamic styles to a web component is a good one: since
attributes have to be strings, you have to handle serialization somewhere
rather than have it Just Work, like it does with most modern JavaScript
frameworks.

~~~
dmitriid
It's also the main problem React faces when trying to incorporate/integrate
with Web Components. React Components can be arbitrarily complex and accept
arbitrarily complex properties.

Web Components work ok as "leaf" nodes: then it's just a component with string
props/attributes.

The inverse is nigh impossible: Web Components can only deal with strings, so
you would end up with yet another incompatible wrapper à la Polymer if you
want to do anything remotely complex.

~~~
spankalee
> React Components can be arbitrarily complex and accept arbitrarily complex
> properties.

Web Components can be arbitrarily complex and accept arbitrarily complex
properties or children.

Did you even try Web Components before spewing falsehoods?

~~~
jakelazaroff
The W3C editor's draft for custom elements clearly states that attributes are
sequences of DOMString:
[https://w3c.github.io/webcomponents/spec/custom/#concept-
cus...](https://w3c.github.io/webcomponents/spec/custom/#concept-custom-
element-definition-observed-attributes)

~~~
spankalee
So? Properties are objects and children are nodes.

~~~
dmitriid
So, basically, "we push everything to JS and we have the curse of the empty
body tag where everything is rendered with JS" turned into "we push everything
to JS and we have the curse of the empty body tag where everything is rendered
with JS ... but with WebComponents! So it's cool now!"

------
romaniv
Couple years ago I gave some thought about how to handle reusable JS in a sane
fashion. Actually, a lot of thought. The end result was something that
superficially sounds like Web Components, but it quite different underneath. I
guess a good name for it would be "Web Behaviors".

It's not a framework or a library, but rather a set of rules and practices of
how to do things. It will sounds somewhat weird, but I'll list them anyway.
Maybe someone will find it useful:

\- Overall mental model: libraries don't implement components, but rather
change the behavior of certain elements on the page.

\- No library keeps state in JavaScript variables. DOM is your model.

\- All configuration is also done through DOM with liberal use of CSS
selectors to reference things.

\- No library has any direct dependencies on any other.

\- Things that need to react to changes should (if at all possible) use
timers. If that's not possible, they should register global event handlers,
rather than attach them to individual components.

While this might horrify some people, it actually forced me to come up with
rather nice, abstract behaviors that capture many common features I had to
commonly implement. Also, this plays well with the notion of progressive
enhancement. I recommend everyone to try it on some new web-based project of
low to moderate complexity. Ir really does simplify a lot things.

~~~
bcherny
Do you have some code samples you could link? On the face of it, this is the
exact opposite of what React, Vue, Angular, Ember, Backbone, etc. do.

~~~
romaniv
A demo of sorts:

[http://quickenloans.github.io/Behaviors.js/](http://quickenloans.github.io/Behaviors.js/)

The code will look extremely non-idiomatic to most frontend engineers. Treat
it as a thought experiment (which it is). The important thing isn't the
particular implementation, but the ideas I outlined above. There are other,
often simpler, ways to implement the same concepts.

One property of these libraries that might not be immediately obvious is that
they "automatically" adapt to changes on the page. So you can add an element
with a behavior via AJAX or dev tools and it will actually work. This is why
using timers and global events is a part of that list.

Another thing is that none of these libraries have an API or modify the global
JS namespace. This is part of the thought experiment not directly related to
the main concepts. It drives some of the complexity.

Edit: Fixed the link.

~~~
bcherny
Link does not work, care to double check it?

~~~
romaniv
Fixed it.

------
robdodson
For anyone interested, I wrote up a response: [https://robdodson.me/regarding-
the-broken-promise-of-web-com...](https://robdodson.me/regarding-the-broken-
promise-of-web-components/)

Kinda used it as an attempt to address some bigger questions around Web
Components I've seen come up a bunch. Curious what you all think.

~~~
dmitriid
I've updated the article to include a link to you response

------
c-smile
Just in case, architecture of components in Sciter. Could be interesting for
some.

Assignment and composition - by CSS, and only by CSS, Sciter's specific
_prototype_ property:

    
    
       .myComponent {
         prototype: MyComponent url(components/my.tis);
         color: red; 
         ...
       }
    

where MyComponent is the name of script class in components/my.tis script
file. That MyComponent looks like as

    
    
       class MyComponent : Element 
       {
         function attached() {
           // called when DOM element gets this class
           // a.k.a. DOM constructor
    
           // content initialization, if needed: 
           this.$content( <button.prev/> 
                          <button.next/> );
         } 
         function detached() {
           // called when DOM element looses this class
           // a.k.a. DOM destructor
         } 
    
         function method() {
            // some public method  
         } 
         property prop(v) {
            // some public property
            get { ... }  
            set { ... }
         } 
    
         event mousedown (evt) {
            // default mousedown event handler
         } 
         event mouseup (evt) {
            // default mouseup event handler
         } 
    
         event click $(button.next) {
            // click on its button.next
         } 
         event click $(button.prev) {
            // click on its button.prev
         } 
    
         // etc
       }
    

To use such component:

1\. include CSS where the binding is defined (prototype above) 2\. In markup
to define matching element:

    
    
       <div.myComponent />  
    

Nothing too complicated and pretty effective. Could be done even 18 years ago:
[http://www.w3.org/TR/1999/WD-
becss-19990804#behavior](http://www.w3.org/TR/1999/WD-becss-19990804#behavior)

~~~
dmitriid
Yeah. Sciter's ideas would be awesome :(

------
interlocutor
This entire article is invalidated by the fact that React's DSL (or the TSX
variant, to be precise) can be used to implement Web Components!

Take a look:
[https://github.com/wisercoder/uibuilder](https://github.com/wisercoder/uibuilder)

------
pfzero
I think your native web components example is wrong, or more probably
outdated.

Here's an example with the latest wc spec: [https://developer.mozilla.org/en-
US/docs/Web/HTML/Element/sl...](https://developer.mozilla.org/en-
US/docs/Web/HTML/Element/slot)

But as far as I understand from the spec, sadly, you would still need a
separate DSL that would leverage iterations, conditionals and other templating
operations on top of web components.

~~~
dmitriid
Yeah, I got it from Polymer's docs. If I don't forget, I'll update the article

------
nickthemagicman
The author of this article really gets web components wrong. You don't use JS
for everything. Web components have a built in DSL.

The below from the article is ridiculous and HORRIBLY INNACURATE:

    
    
      ['Hello', 'world'].forEach(('text') => {
    	const p = document.createElement('p')
    	const span = document.createElement('span')
    	span.textContent(text)
    	p.appendChild(span)
    
      MyComponent.appendChild(p)
      })`
    

In RiotJs you would build a web component this way:

    
    
      <text-breaker-upper>
       <p each={this.input_str as out_text}>
         <span>{out_text}</span>
       </p>
    
        <script>
           this.input_str = input.split(" ");
        </script>
      </text-breaker-upper>
    

Then you declare it ON THE PAGE.

    
    
      <text-breaker-upper
          input_str="Hello World">
      <text-breaker-upper>
    

Web components much more intuitive, reusable, better separation of concerns,
less bloat, and more elegant than React..no bastardization mixing of JSX, CSS,
and JS, and how the web (and any sane technology) was meant to be.

The sooner this JS front end framework B.S. wasteland nightmare is behind us,
the gournd salted on where it stood, and we laugh at JS like we laugh at
COBOL.... the better in my opinion.

~~~
woah
Looks like Riot.js is just another frontend library that has a templating
pseudo-language like so many others. Maybe they use the words "web component"
on their site or something? Looks like they parse their templates out of the
DOM and then do what any frontend framework does. Strange that you get so
emotional about whether your templating language is shoehorned into some DOM
nodes that get thrown away and replaced once the framework reads them. This is
not the web components that the article is talking about and it is not
interoperable.

~~~
nickthemagicman
This and Polymer are the precursor to built in browser web components that the
author claims React is superior to.

------
pikeymick
When done correctly web components aren't just about extensibility. They are
also about encapsulation, debugging, testing, *ing, and then reusability.

~~~
dmitriid
All of these are much better solved by literally everything else :)

~~~
pikeymick
Literally everything else is not a useful example.

~~~
dmitriid
I wonder if there's a JavaScript framework called "literally else"... :)

------
jondubois
React has a bigger community, more hype, more tooling around it, better native
mobile support and better support for automated testing.

But if I had to pick my favourite, I'd have to go with Polymer because:

\- It's simpler (fewer dependencies).

\- Declaring styling and layout is cleaner (it's easier to visualise a
component's appearance and to modify it during debugging because layout and
styling are kept separate from a component's behavior logic). When it comes to
debugging, styling/layout issues almost always happen independently from
behaviour issues so it makes sense to keep them separate in the source.

\- It works better with browsers' native development tools.

\- No need for a compile step (and associated complexity that comes with it as
your app grows).

It's not fair to pretend that React bypasses the DOM entirely. Ultimately,
when the user clicks on a button, they are interacting with a DOM element, so
the event still has to pass through the DOM layer. The DOM is still the API
whether you like it or not.

------
jakelazaroff
I think we're approaching a point at which browsers will need to make some
sort of break with the current DOM in order to provide the types of rich
experiences engineers and users want. There's simply too much baggage with the
current implementation, and this article highlights a lot of it: attribute
values limited to strings, a global namespace for CSS, etc.

This is happening at other levels of the web with the HTTP/1 —> HTTPS/2
transition. We're patching over shortcomings in the DOM right now with
JavaScript, but it's easy to see the appeal of a native solution to some of
these issues that doesn't require a facade over the actual thing that people
interact with.

~~~
wrs
It saddens me that the software industry has been flailing around for at least
15 years trying to resolve the tension between having zero-install +
standardized framework and having a rich UI toolkit that can do "real" apps
without making developers crazy. The answer seems to be this weird cycle of
layering reinvention atop reinvention because nobody can just blow up the
whole stack and rethink it with any market success.

Using the DOM + scripting pattern with a DOM more suited to "rich app"
development has been tried multiple times as plugins (FLEX and Silverlight
come to mind). But the gravitational pull of zero-install + standards crushed
them. We also have in progress what is essentially a reinvention of the JVM
idea (WebAssembly) but without the UI layer to go with it. That may be
successful in its narrow niche, or it may try to overreach into the UI layer
and fail like all the others…too soon to tell.

~~~
nercht12
What would be the language to use? JavaScript won early, so it's been the de-
facto choice every since to the point where browsers probably don't even run
other scripting languages with the script tag. The first major hurdle in
changing all of this would be getting everyone to agree on what to use.
Different languages are suited for different jobs. HTML is perfectly fine for
static UI, which is what most sites need it to do. What would a better
language or set of tools for the web even look like?

------
fauigerzigerk
This whole tangled mess of JavaScript, HTML, CSS and custom expression
languages screams Lisp.

~~~
iLemming
Yup, I'm reading this and thinking "oh my, Clojurescript is SOOOOO much nicer"
than jsx and dom js api and whatever becomes "trendy" tomorrow.

------
sebringj
Web Components have turned into a dead end for me. Instead, I like what
Facebook has done in that they have proven the declarative approach can
translate to native and even VR in a very intuitive and approachable way. As
far as I'm concerned this is the future for awhile as I've been having a
breezy easy time doing native with React and have never experienced a simpler
way to develop anything. I have also programmed in Vue but for some reason
still prefer React. Possibly because it seems there is more community support,
usage and toolage and of course it supports more types of devices, aside from
being baised.

------
staltz
Important context (Twitter thread) for this article, by the same author a few
days before publishing it:
[https://twitter.com/dmitriid/status/841172534586429441](https://twitter.com/dmitriid/status/841172534586429441)

------
k__
I don't think Web Components are a "framework replacement", they are an
addition.

Stuff like Bootstrap needs them to enrich their "top down" approach with CSS
and HTML so you don't have to mess around with either their source OR CSS
classes and "their" HTML structure everywhere to get the components right. You
add their CSS & (Web Component) JS at the top and use their custom components
as the "leafs" of your sites. I wrote about it here:
[https://dev.to/kayis/web-components-for-your-custom-
elements](https://dev.to/kayis/web-components-for-your-custom-elements)

The other frameworks like React, Angular, Cycle or Ember will then become the
Data-flow layer of the app.

~~~
meowlicious
>The other frameworks like React, Angular, Cycle or Ember will then become the
Data-flow layer of the app.

None of these frameworks like dom being changed from underneath them, you will
run into all sort of weirdness.

~~~
k__
I think this depends on the complexity of the components you implement as web-
components.

I mean, in React, the whole app is basically a component. It wouldn't make any
sense to replicate this with Web Components.

But yes, I read a few times that the React devs don't consider React a "data
flow framework", so they decide when to re-render and stuff. Cycle is more in
line with this thinking.

------
gedy
> In 2017 React fulfills all the promises of Web Components

Not really - React needs a large run time, and it's really not a good fit for
an existing app where you need a true component you can pop in and use within
a Java or Rails app.

~~~
dmitriid
You can use slimmer runtimes: Inferno, React, snabbdom, virtual-dom...

Web Components also need a runtime as soon as you need anything sufficiently
complex. Such a simple example as a ToDo List cannot run without Polymer's
weird data-binding implementation: [https://github.com/PolymerLabs/todo-
list](https://github.com/PolymerLabs/todo-list)

------
spankalee
This article is just awful.

There seem to be two main criticisms here:

1\. Web Components don't provide a DSL for creating DOM trees. This is true,
because Web Components don't provide a DSL for creating DOM trees! That's and
entirely separate concern that can be addressed by a library[1] or by a
future, more-ergonomic tree construction API in the DOM.

2\. The author doesn't like Polymer's templates. Which is, nearly as unrelated
to Web Components as the first complaint, because it's also the same as the
first complaint. Polymer's template system allows you to create DOM trees, and
automatically wire together properties and events. That's it. You can do this
without using custom elements at all.

You can also use any number of ways to construct trees: JSX, DSLs, HTML
templates and cloning, string templates, etc. It's no different from any other
framework including React.

And then he repeats Sebastian Markbåge's, creator of React, tired complaint
that Web Components can only consume string data. This is FUD, pure and
simple. Web Components are Elements, and Elements are Objects with properties.
Every Web Components framework relies on this for data-binding or setting
"props".

And... that's it. That's basically the extent of the critique.

The author could have actually tried to compare React and Web Components and
he would have seen that:

1\. The component models are very similar, there are analogs for most
lifecycle events.

2\. Web Components don't prescribe state management or dataflow, and there are
indeed functional, unidirectional, immutable (by convention), Web Components
libraries and patterns out there.

3\. Shadow DOM fixes nearly everything that css-modules address in a native
and performant way.

Web Components aren't a be-all-end-all standard. They are a few fixes to the
platform that should have been there from the beginning, namely that you
should be able to extend the HTML vocabulary (Custom Elements), you should be
able to encapsulate some DOM and styling (Shadow DOM, which most browsers
already had for their own UIs), and that you should be able to ship and parse
_potential_ DOM (<template>). That's it. Everything else is either a library
responsibility and/or TDB. Web Components are a foundation to make it easier
to create frameworks, libraries, and an base-level interop story that answers
some, but not all, critical, simple questions:

How do I write a widget? : Extend HTMLElement How do I keep other scripts and
styles from interfering with my widget's internals? : Put the internals in a
ShadowRoot. How do I scope my own styles? : Put them in a ShadowRoot How do I
instantiate my widget: Use a tag in markup, call createElement(), or call it's
constructor.

Anyone coming to the web platform as a new developer now doesn't have to sift
though 100 frameworks and contradictory tutorials for such simple questions,
the platform provides answers, as it should have from the beginning.

[1]: See Hyperscript as a React-like example
[https://github.com/hyperhype/hyperscript](https://github.com/hyperhype/hyperscript)

~~~
woah
What does Hyperscript have to do with web components?

~~~
spankalee
Exactly.

The complaint in the article is that Web Components don't _also_ add a nice
API fro creating DOM trees.

This is true, but not relevant. The ideas of a component model and tree
creation DSL are orthogonal.

Hyperscript (the JS library) is a nice API for creating DOM trees, that's
similar to React's createElement(). You can use it with or without Web
Components.

------
startupdiscuss
[Typo flagged and fixed]

~~~
dmitriid
Done! Thank you!

------
trm42
It starts to sound like browsers should support JSX natively...

~~~
AshleysBrain
Template strings look like a better way to do JSX, imo: why can't
html`<p>Hello world</p>` be made to return the DOM element for the p tag?

~~~
dmitriid
JSX appeared before template strings where even an idea (I think :) ).

The thing though, JSX doesn't return DOM elements. It's a very thin DSL on top
of React.createElement calls. Since it's Javascript all the way down, you get
a number of benefits:

\- you are not constrained by limitations such as "attributes can only be
strings" or "children can only be DOM Elements". It's all Javascript
expressions

\- React knows the return value. It can do efficient diff'ing against its
internal DOM representations and only update the actual DOM as needed (same
goes for other virtual dom implementations such as snabbdom, virtual-dom etc.)

