Hacker News new | past | comments | ask | show | jobs | submit login
The Failed Promise of Web Components (verou.me)
367 points by lemonberry 10 months ago | hide | past | favorite | 229 comments



This post is needlessly snarky, but I don't disagree with the basic premise.

Here's what killed web components: lack of native databinding on the web. That's the reason the standard is useless without JS. Any modular, dynamic, modern UI requires databinding, which means it's going to bring in a framework anyway, which means that self-contained widgets are all going to bring in their own frameworks, which means that instead of one large framework on the page you have five or six, all of them stitched together through rickety HTML-attribute APIs and custom value-parsing strategies because HTML attributes are just strings.

I fail to grasp why databinding hasn't made it into a web standard yet. The web has a long tradition of feeling out features in the JS world before adopting the successful ones into the platform. jQuery turned into querySelector() and fetch(), CommonJS modules blazed the trail that led to ES modules, etc. And this next paradigm is more than ready to get standardized. Not only would it make the dream of web components possible, it would eliminate the need for a whole lot of the JavaScript out there and even make UIs faster, since reactivity logic would be implemented natively.

It's such an obvious, ubiquitous improvement to the web that I can only assume there's some fundamental implementation roadblock I'm missing.


I'm a strong proponent of separation of duties on the web (style and visuals in CSS, layout in HTML, anything interactive in JS). Enabling data binding in HTML would only serve to blur those lines.

With some minimal JS, you can update each web component already. Is writing nameField.innerText = response.name really that difficult? What problem does it solve to make a standard for it? As for (de)serialization, JS has built-in support for JSON and XML. HTML attributes are everything but rickety in my opinion, as any decent parser will allow you to access them as if they are a normal dictionary. Put JSON in them if you really want to encode complex data in attributes, although you probably shouldn't.

I strongly believe the abhorrent overuse of React and other such libraries on the web is the sole reason our computers have gotten hundreds of times faster but the web is only slightly as quick. I don't see a place in web standards for a React-style functional design because of the specific rules each of these libraries have.


> anything interactive in JS

Except this barrier has never existed. Every HTML input is interactive: text fields, checkboxes, radio buttons. They not only remember their value, but your cursor position within them and the segment of text you've highlighted. The browser knows how far each scrollable element is scrolled, which element is in focus as you tab through the page. Forms have validation state, and can be interacted with to send an HTTP request. These days you can even do autocomplete with nothing but HTML: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/da...

The magic of HTML has never been about static layout, but about having a declarative language for building out an interface (not just a static view, but an interface). This idea that it should be nothing but a dumb view-layer is a new one, popularized by the very frameworks you're railing against. Data binding is a way to stay in that declarative space, while dramatically expanding what use-cases can be covered within it. JavaScript (in the browser) was, and always should have remained, a trapdoor for working around HTML's shortcomings. It's a Turing-complete language for doing things that can't be done any other way. Anything that can be neatly siphoned off from that more complex imperative world, should be. For the sake of complexity, for the sake of accessibility, for the sake of performance, and for the sake of compatibility.


I built lots of HTML form UIs in the early 2000s. They were garbage. Many modern web UIs are on par with native apps, so much so that folks are now using web technologies to build actual native apps.

With 150 years of evolution (at current W3C standards pace) you might get an HTML spec that is capable of expressing the behavior that users expect from present-day applications. Until then we have React et al.


> Many modern web UIs are on par with native apps

I strongly disagree.

Form/<input> fields are one of the areas that a native app can slaughter HTML, even if using a WebView within an app. For example, just showing the correct keyboard layout is a nightmare, and heaven help you if you need to do something slightly custom. Another example: browsers do funky shit with scrolling and zooming on input focus. Try using the best HTML code-editor from a tablet: the editing experience sucks.

Another example is swiping, where browsers like Safari Mobile (and the old Edge) decide to navigate back/forward if the user happens to swipe from the edge by mistake - killing page state. Overriding pinch-zoom for say a photo app is doable, but sometimes ends up with invalid UI states (especially if you mix in viewport sizing changes due to orientation/ua-zoom/virtual keyboard show/tab bar show).

Disclaimer: I have spent many man-months working only on making user friendly custom <input>s in HTML, and the experience blows chunks. I have developed a custom Web UI that required too many compromises in UX.


> For example, just showing the correct keyboard layout is a nightmare

It’s literally just an attribute on the input element?


Agree with you. Not sure what this page doesn’t cover https://developer.mozilla.org/en-US/docs/Web/HTML/Element/in...


How many native applications are written in electron? It’s a lot. VS Code is electron and replaced my usage of actual visual studio. I still have it installed, I just don’t use it anymore.


> Anything that can be neatly siphoned off from that more complex imperative world, should be.

No it really shouldn't. Just look at JS. It's a complete mess. And HTML would get there in a short time if they were to adopt "anything that can be neatly siphoned". The problem is that data binding is actually quite complex. I have seen data binding done 10 different ways in different languages and they all had their flaws. It will be very difficult indeed to come up with such a standard that is actually being used universally.

If it is not, what sense does it make to add it to the standard? But for it to be used a lot, it would actually need to solve most problems in most businesses for the forseeable future.

Given the fact that the Web apparently still hasn't figured out quite how UI development is supposed to work (judging by the 1 new language feature, 10 new frameworks, 100 new libraries developed each day), it will be a very poor idea to start baking half baked stuff into a standard.


Web Components are a total mess and impossible to build anything of significance with. I can't even imagine how anyone would get anything done with them. It's like an Angular developer, an artist, and a mid-2010s neural net walked into a bar and sketched out a spec by taking shots and passing it clockwise.

Separation of languages is a silly way to separate things. You're building components: logic, structure and style are coupled. SwiftUI adopts the React model, and it succeeds because of it. One can build an app in React/SwiftUI in about 1/2 the time spent "separating concerns", and build systems still extract things out to be clean and performant, there's no sacrifice being made there. CSS is a shitshow and a total mess especially on large teams.

React has nothing to do with how performant an app is and if anything speeds them up compared to anything previously, you may be confusing the power and ease with which it enables development as getting some drunk on building larger apps, but that's only because of how effective it is. Twitter is a good example, great performance. It's way more about the team than the tool, though certainly it will get easier over time to have the defaults be better at optimization for smaller teams who are ambitious.

Most of the super bloated websites I see are basically news sites and other less-techy sites that are stuffed with ad tracking and have no tree shaking. The majority of React apps build with Webpack which supports tree shaking and lazy loading out of the box, plus React makes it possible to pre-render your entire app and deliver it as HTML that hydrates.


Weird, because we're using web components at my workplace to build complex web applications. We use Lit-Element as a base class and have come up with a top-down functional state pattern for data that removes the need for two-way binding. If a sub-component needs to update its state due to DOM interaction, it just fires off an event with info about that DOM interaction, and the data store for that component (another web component) does the necessary state modification, then fires off a "state-changed" event that tells all associated components to update their state from the "master" store (one line of code). All of the data elements use pure functions to do state modification, so doing complex operations is simply a matter of composing the appropriate functions. I've not used react myself other than playing with a few demos, but another developer on my team says the pattern is very similar to how react stores work, and the core modules that drive it are like 100 lines of code.


Lit-Element puts lipstick on the low level pig, but React excels in many ways beyond it. Consistency between props (vs attributes), can render server side, awesome side effect system that makes it world class at hmr.

I think WebComponents have left a horrible taste in the mouth because they came well after React and others existed, didn’t take any inspiration or provide any abstractions that would help, did basically everything worse and seemingly without any discussion with real world devs, and then were hyped and pushed on everyone for years while they basically lacked all necessary features. Now, years later they have evolved and added libraries on top to smooth over all the weirdness, and if you squint they look similar, but the web would have been a better place if they had just provided some VDOM abstractions, style containment in a simple way, and so on rather than master-planned a High Modernist dystopia and then slowly painted over it until it resembled something like the organic cities that already existed.


I guess maybe you had a different experience than I did, because I never had web components "pushed" at me in any way. It was always a technology I was keeping my eye on but was hesitant to invest in until the browser support was there, and now that the browser support arrived I've seen a grand total of ONE web-component-focused talk at the web dev conferences I've attended, and that one was given by our project lead.


Yes, every word


I've tried LitElement (still using it in a small project), and wanted to like it; but the whole experience was so cumbersome compared to something like React.

1) Classes for writing components. Yuck. React's function component feels much more elegant.

2) @property decorator. Double yuck! I want a reactive way of updating my component's state without having to declare this piece of state as a property accessible by the outside world.

3) this.requestUpdate(). Triple yuck compared to something like React's setState or useState hook.

4) In order to create children components, I need to create more customElement-decorated classes? Yuck again!


I have never used SwiftUI so I can't comment on it. However, separation of concerns doesn't need to take extra development time. Inlining all CSS and JS is like dropping the MVC model because creating all the necessary classes is taking too much time; focusing on short term gains only lead to a mediocre end result, one that nobody wants to maintain five years down the line.

Good React is fine for large applications, but not for websites. Even in applications a few lines of Javascript and a rendering backend can replace entire JS frameworks. Try disabling Javascript for a day and you can see how many pages just become a white screen because whatever is replacing the browser's renderer isn't loading.

> Twitter is a good example, great performance.

I agree that it's a great example, but it performs horribly for me. I use their website on my phone and videos rarely play back properly, content jumps around while navigating, empty screens and loading bars are everywhere. Sometime I just have to reload because the Twitter website decided it doesn't want to load images anymore. Nitter links, on the other hand, load instantly, including image and video content, because of its minimalist approach.

Server side rendering is a welcome improvement because it means the developer doesn't offload the website's calculations to their visitors. I'm fine with whatever framework people pick on the server, as long as my browser doesn't get its rendering engine replaced by the fancy framework for the week.


I think the irony here is that MVC in its original form has largely fallen out of fashion the last few years. And it is precisely because physically separating all of the functionality into a model/view/controller files doesn't actually make development easier. This makes sense right? Logically it's all coupled, so separating the pieces, even if they are functionally responsible for different things, doesn't really produce a system that is easier to maintain.

Look at the new default "razor pages" web project for .NET core. While it it is a little bit fancier, it basically brings back the same mental model that PHP has been using for decades. That is, cram all of the logic into a single file, and use a "service locator" pattern (I know it's actually DI under the hood) to "inject" extra functionality. In this way it is easy to trace where all of the pieces are coming from. Why abstract your `UserRegistrationView` to accept any `UserRegistrationModel` from a `UserRegistrationController` in a "decoupled" manner when the reality is that only one of any of that actually needs to exist ever? Might as well have the orchestration right next to the use-case!

The above applies to (what I believe to be) a significant majority of use-cases. At least the interesting ones.


MVC - because spending 50% Of your time looking for the other file with the almost identical name is fun... wait now we need the view... nope back to the controller again... why can’t these files be next to each other...

It’s ironic that this is done in the name of “Separation of concerns“ -

You know what separates concerns: having everything that affects this component - in one place. That’s true separation of concerns.

I’ve worked in multiple frameworks in multiple languages and nothing does it better than modern react (especially with webhooks).


Could you give a few examples of those languages and frameworks just to understand what you are comparing React to?


Here’s a decent list through time for JavaScript frameworks: http://todomvc.com/

For my own experience with things that were specifically MVC or MVVM:

In C#: Asp.net MVC, WPF (with/without Prism)

In Typescript: Knockout, Angular 2.0+ (I guess it wasn’t mvc really - I disliked it for other reasons)

React (with hooks) on the other hand is the embodiment of a pure Functional Programming UI.

I can literally write a component with a single import and a single function.

For every reason functional patterns beats OOP patterns, react beats mvc - and achieves true separation of concerns (feature aligned concerns).


Thanks, that helps.


> I think the irony here is that MVC in its original form has largely fallen out of fashion the last few years.

Not really — unless React is the only library you use.. MVC is still the best pattern. If you are an iOS developer you may already be familiar with MVC in Cocoa. Most UI frameworks, including ASP.NET Core, JSP and JSF (Java based frameworks), Ruby on Rails, and Django (Python) are all based on MVC. That's no accident. These disparate platforms — mobile and Web — all converged on MVC because it is the best architectural pattern for developing user interfaces.


There’s a whole ecosystem of alternatives that have sprung up I have a feeling you haven’t tried (not MVVM or anything like that). Without appealing to any of them you aren’t convincing.

Even within the frontend world and not in React you have all sorts of new state systems and structures that are in my opinion far more intuitive, less code, less cross cutting concerns, easier to change and grow more naturally. The gist of it is either a global state store with cursors and namespaces (I like this less than most) or a global state system with state split out (see Recoil) or an entirely tree based reactive state system (see mobx-state-tree or mobx-store) or even just nesting reducers or any simple nesting state container (pure react, zustand). I’ve recently put together gqless[0] with a state system similar to recoil but simpler (sort of like use-atom). It’s wonderful.

Your data is a tree/graph, you app is a tree, your file system is a tree, everything matches. You just slot in state with corresponding actions and at the level of the view hierarchy where it first becomes relevant (router at top, view controllers are spread in the middle layers however needed, and leafs get their own state as needed). And all data level things stay up in the graph, which I guess you could argue is an M sitting above it all, the VC are blurred together with more C at the top of the tree and pure V at the leafs. Even styling is all encapsulated where it’s used. Each piece is a lego block that can be moved around. And yes, it works, and works well, even without all the handlebars of Rails.

Wouldn’t dream of going back. It’s perhaps not a mature enough ecosystem for most to navigate their way to getting a good DX on a stack like that. Many pieces have rough edges if you don’t know what to avoid, it’s not like these huge mature frameworks that keep you away from scary stuff but also box you into a rigid structure. But of course it means you can do all sorts of things unimaginable in MVC land.


Most of the frameworks you mention above are 5+ years old. Back when jQuery was the THE THING to know.

In any case, my critique is not levied against MVC the pattern, rather, how it is manifest. One can logically follow MVC without the physical separation of concerns (files). It's a continuum: You start by defining your state, view, and orchestration all in the same place. Should any one piece of the above suddenly need to be reused elsewhere, you then abstract as necessary.

I was pushing back against the idea that "inlining" CSS/JS with HTML is poor practice. What React achieves, because it demands you inline JS (and CSS if you want) with the HTML, is a simple, declarative development paradigm. It's like reading a function. No procedural ad-hoc `let el = document.querySelector('#id')` garbage getting in the way. The behavior is with the component, not around the component. In many ways, this is how OOP was supposed to work.


Writing inline styles != rendering inline styles, look at “atomic style extraction” which with a compile step gives you far better results: automatic dead code elimination, automatic partial loading that’s tied directly to your usage, and no more jumping between the thing you’re styling and the the thing itself.

The nitpicks you have on Twitter are on specific behaviors (video and jumping and slow fetch) that have nothing to do with React. The site itself is lightweight and runs fast.


I've built several complex apps (which I suppose are "of significance") with web components. I just used a framework (Polymer in my case) to abstract away the web components API.


React is a nightmare when it comes to performance or energy efficiency...

Downloading 500kb of js and processing this is just a nogo. The best advice to anyone interested in page speed, dont use this crap.

https://youtu.be/plt-iH_47GE


My website which is entirely built in react (and uses Gatsby).

Takes 4kb to full page render (1 file - static only - JavaScript disabled).

That’s smaller than most any html+css especially if using some css library.

Of course once that is loaded and if JavaScript is enabled, then it will start to load interactive stuff and prefetch (which is around 100kb - but I have a lot of interactive stuff - including a zork style adventure Easter egg in the site header).


Check the time to interactive. Rehydration creates a massive cpu increase.

https://developers.google.com/web/updates/2019/02/rendering-...


In lighthouse, I see a score of 100 performance and time to interactive at 1.8secs.

This is comparable to hacker news home page (which is purely static), but my first contentful paint was slightly faster (probably because my site is slightly smaller).

Both sites were about 4 times faster (TTI) than google home page and typescript home page.


I’d be interested in checking out your site. I normally only have a 2G connection on my phone, I’d love to be able to read something that’s NOT HN. This site is the only site I know that takes less than 5-10 mins to load, if it loads at all.


Ok, here it is https://ricklove.me

Here is a post that explains some of the content that is interesting: https://ricklove.me/cool-stuff

Let me know how it does on a slow connection.


It took 30s to 60s to fully load, but the content was available very quickly. The most entertaining thing was the stripe example. I didn’t realize it was supposed to load the card form, so I hit subscribe and it caused an error (because the card form wasn’t loaded yet) but the app handled it appropriately. It would be better if the subscribe button were disabled before the component loaded (which took at least a minute), but it’s still pretty good.

Overall, it was a very refreshing experience.


Ah, makes sense on the stripe component.

I did notice that for some components I need to show a loading indicator while they are loading async (for a slow connection).

Thanks for letting me know!


I'm quite sad that hunter2 isn't in your passwords.txt


Good idea :) I’ll add that.

I guess I’ll know if someone finds the Bitcoin.

Update: I added a few more nerd lore passwords - thanks for the idea!


That is really a great website. Why didn't you built that site with HTML?

Just check the stats here: https://perf-track.web.app/react


It’s not a static site.

Type “dir” in the header (or other activities in the “cool-stuff” post).

Moreover, I can build anything I want very quickly - with great engineering - and still get performance comparable to a static site.


> Downloading 500kb of js and processing this is just a nogo.

React + react-dom is under 40kb minified gzipped. The other 460kb are your responsibility.


The reality shows totally different numbers https://perf-track.web.app/react


Use Gatsby and generate a static site w/ React? At least React is faster than Angular, which I strongly prefer.


Better, generate a static site without frameworks.


> Twitter is a good example, great performance

This statement alone invalidates your arguments, because evidently you never once tried opening Twitter on an underpowered machine, be that desktop or a phone.


> I strongly believe the abhorrent overuse of React and other such libraries on the web is the sole reason our computers have gotten hundreds of times faster but the web is only slightly as quick.

If browsers provided data binding and reactivity out of the box, frameworks and applications would be much faster and lighter.


Web browsers provide many features out of the box but frameworks rarely use them. Web components are one thing; HTML templates are another. Streaming video is being decoded by Javascript even though every browser supports H.264, input elements such as calendar controls are rewritten, animations are done in JS instead of smooth CSS transitions, drag and drop support is manually rewritten in JS...

Whenever a feature gets added to standard HTML, web frameworks and "polyfills" keep implementing their own versions because the standards don't fit them and they don't want to rewrite (or keep their own implementation as a mere fallback).

Even if a data binding framework would be standardized today, it would take years for browsers to catch up and gain critical mass. There'd only be more polyfills and Javascript to help support people running IE11 or whatever.

I'm glad many JS features have been implemented natively in HTML5, but this specific case feels overkill to me. HTML templates have been introduced and then ignored by frameworks already and I doubt any framework would switch over to a new data binding API if it became a standard today.


> Streaming video is being decoded by Javascript even though every browser supports H.264

Maybe in some experimental project, but I've never seen this in any video site.

> input elements such as calendar controls are rewritten

Yes, because the native browser widgets are totally insufficient and can't be styled.

> animations are done in JS instead of smooth CSS transitions

JS animation can be super fast (see GSAP) and it seems you're talking about jQuery.animate() which I agree was terrible. But these days most people use CSS animations.

> drag and drop support is manually rewritten in JS

Again, because the browser does not have a proper drag and drop API to do it. I know because I've had to implement drag and drop many times. From vanilla, to jQuery, to React... for mouse and touch UIs.

Here's another huge thing lacking in the browser world: touch gestures.


> Yes, because the native browser widgets are totally insufficient and can't be styled.

I don't want them to be styled, thank you very much.

> JS animation can be super fast (see GSAP) and it seems you're talking about jQuery.animate() which I agree was terrible. But these days most people use CSS animations.

GSAP is giving me stuttery animation when I scroll through their website on my phone, presumably because it's constantly updating the DOM to keep control of the animation. It's not as bad as the state of JS animation was 10 years ago, but I can think of very few use cases where such a library would actually be necessary instead of using pre-calculated CSS transitions and such.

> Again, because the browser does not have a proper drag and drop API to do it.

I haven't had that much trouble when I had to use the HTML5 DnD API. Well, not more than with the frameworks I've seen; touch screen DnD support sucks on all platforms I've tried.


>input elements such as calendar controls are rewritten

Popular browsers such as Firefox and Safari don't have native date controls: https://caniuse.com/input-datetime


Looks like Firefox now supports `date` and `time`.


> animations are done in JS instead of smooth CSS transitions, drag and drop support is manually rewritten in JS...

I mean... maybe in some legacy plugins that budget-shops drop into a Wordpress site without thinking. This stuff doesn't really happen anymore in real projects; there's not much point.

> Whenever a feature gets added to standard HTML, web frameworks and "polyfills" keep implementing their own versions because the standards don't fit them and they don't want to rewrite (or keep their own implementation as a mere fallback).

I think you misunderstand what polyfills are. Polyfills exist as an implementation of the standard, before the standard has been fully supported. They get stripped out when possible. In no way are they "their own version" of the standard.

> Even if a data binding framework would be standardized today, it would take years for browsers to catch up and gain critical mass.

It definitely wouldn't. All major browsers get silent auto-updates now, and Chromium alone has over 75% of the market share now that Edge is based on it. Google was the one pushing web components in the first place, and today Firefox and Safari would face pressure to keep up lest they lose ground when more sites become "just for Chrome". The silver lining of the browser monoculture is that features get implemented quickly.

> There'd only be more polyfills and Javascript to help support people running IE11 or whatever.

Possibly. But in today's world polyfills are less and less necessary (see my previous statement). Most companies these days just write off IE and outdated browsers as not worth bothering with. And for all those other browsers, there would be a dramatic drop in the amount of Javascript.

> HTML templates have been introduced and then ignored by frameworks already

HTML templates are the prime example of how useless the web component standard is in its current form: they literally just hold DOM nodes. Those DOM nodes can't appear on the page without being cloned by JavaScript. They gain no special functionality. They just sit there. Templates without databinding are hardly better than an HTML string.


> I think you misunderstand what polyfills are. [..] They get stripped out when possible. In no way are they "their own version" of the standard.

That's the idea, but many projects never actually remove the polyfills once browsers catch up to a given standard. In theory they solve the problem, but in practice I'm still ending up downloading polyfills on Firefox and Chrome because Safari doesn't support a particular API. Sure, the code barely executes, but the bandwidth is wasted regardless.

> It definitely wouldn't. All major browsers get silent auto-updates now [..]

Tell that to mobile Safari. Updates are packed into OS updates and features regularly take ages to be implemented. One day we'll get WebP and notification support. One day...

> Templates without databinding are hardly better than an HTML string.

Templates without databinding provide everything you need to render a component; structured elements that can be filled out with code. With class names and query selectors they can be filled and rendered very quickly with little code and no need for a framework.

Using the API properly can ensure that inserted text is never seen as code, making it free of the injection attacks that HTML string replacing often exposes. Content and structure are clearly separated and provide no challenges for the browser to parse. Generated components are always well-formed, which string replacement also doesn't guarantee, modification of contents is no different from regular DOM updates.


Please learn how to properly quote things, all of your replies are showing up as part of what you quoted


Markdown's double newline never fails to trip me up. Sorry.


The major desktop UI toolkits don't agree. They all have data-binding for controls.

And we still separate concerns on the desktop. The model/view/viewmodel paradigm is pretty good.


If, as you say, css is style and visuals, layout is html, and interaction is JS, isn't there a missing data layer? I'm not sure I exactly agree with the categories you name, but I think there's very much an argument that if HTML is layout, then it isn't content or data, and the content/data (and its connection to html/JS) would then be a missing 4th piece.


Care to explain for what reasons you are a strong proponent of this? Is it religious?


Because I think separation of concerns is a better model than throwing everything together because the browser will make sense of it anyway.

It's the same reason I prefer a structured MVC project over a PHP file with the contents echo'd in with <?= ?> statements. Both get the job done in the end, but one is clear about where what responsibilities lie.


To be frank, I think in large part this is due to React.

I'm not an authority in this area, but I seem to recall that because React uses a synthetic event system, it won't interoperate with Web Component bindings and emitted events. (I know React doesn't work well with Webcomponents, the part I'm unsure of is whether it's specifically due to this).

React also doesn't have an easy means of turning React components into Web Components for publishing and consuming. (Preact does though, they put a lot of work into it).

Svelte, Vue, and (I believe) Angular can all emit web components.

In Vue, you can use the framework's standard data-binding and event capture syntax to interact with custom web components. You wouldn't be able to tell the difference between a Vue component and a Web Component you imported from a package.

(I can't speak for Angular, maybe someone could chime in here.)

To me, it represents a huge failure on the part of the developer community not to make publishing web components the standard.

It seems silly to write a wildly popular component/component-library, and vendor-lock it to a single framework. Why not just publish a web component version as well?

https://cli.vuejs.org/guide/build-targets.html#web-component

https://preactjs.com/guide/v10/web-components/

https://dev.to/silvio/how-to-create-a-web-components-in-svel...

https://angular.io/guide/elements


> To me, it represents a huge failure on the part of the developer community not to make publishing web components the standard

The problem is that if you're writing a Vue app, and you import a web component that was written in Preact, you're now loading both Vue and Preact onto your page. That means your app will take twice as long to load. That is a huge downside to weigh against the inconvenience of having to find a version of that widget that's built specifically for your framework, or even just building one yourself. The compatibility layer doesn't matter if nobody's going to use it.

> To be frank, I think in large part this is due to React

I'm not sure. I think React saw that the web components model was broken and didn't waste the effort trying to stick to it, and built their own separate React world that wasn't broken and that's why they've been so successful. It's a shame and an indictment of the web platform, but I think from their perspective it was the right decision.

The real shame would be if React's mindshare is the thing now holding us back from finally solving this at a platform level. I can only speculate about that, but it doesn't seem out of the question.


The point about the shipping the framework as a dependency is a good one. In the grand scheme of things it's not the end of the world but shipping multiple framework runtimes is definitely not ideal.

Svelte is the outlier here, where the end-product is fully compiled to standard API's without a runtime. Maybe we'll see more frameworks adopt this approach in the future.


StencilJS does this too. It also has a wrapper to create React components. I really recommend it


I completely forgot about Stencil from the Ionic team.

Definitely agreed. If you want an example of Web Components working cross-framework, look at Ionic and Stencil tbh.


The webcomponents supporters seem hell bent on placing the blame somewhere other than webcomponents themselves. In the “truckload of dependencies” they fail to ask why those dependencies are really there, and in that required JS they fail to ask why its really needed. The webcomponents model isn’t just broken, its thoroughly broken, and I actually hold the opinion that it was never even a good idea, because it’s simply the wrong abstraction layer to be extending on.


> In the “truckload of dependencies” they fail to ask why those dependencies are really there, and in that required JS they fail to ask why its really needed

Yes, this is what I meant when I said the post is too snarky, but I don't think it's fair to take that as representative of all "webcomponents supporters". That JS exists to fill a gap left by the platform, and it's a gap that should be filled by the platform, but it's also a gap that isn't filled by the platform.

> I actually hold the opinion that it was never even a good idea, because it’s simply the wrong abstraction layer to be extending on

I disagree. HTML is a profoundly intuitive and accessible standard which reaches far outside the normal bounds of software developers. This is evidenced by the thriving diversity the web has experienced (before everything moved to closed platforms, that is). For static content it already provides an exceptional balance between expressiveness and accessibility, and the dream of web components was to bring that over to apps as well. And I really do think that idea is still a good one.


I mean, we're using web components to build large web apps at my workplace, and in my experience 95% of the dependencies of web components are... other web components. Which makes sense for anything more complex than a simple button. The whole point of web components is to create portable, reusable code that can be encapsulated within an HTML tag, so if I'm writing an app that needs buttons, inputs, date pickers, etc, obviously I'm going to import components for those things where native controls don't meet my needs. I don't understand why "it has dependencies" is a valid criticism.


> in my experience 95% of the dependencies of web components are... other web components

Sure, and in a single project at a single company that's probably fine. You've all agreed to standardize on a single version of Lit-Element and compile the whole project at once, so no worries.

But if the goal is to make Web Components standard units of UI across the web, such that you can grab a `color-picker` component and a `webcam-video` component and put them together into your `video-color-filter` component... well, if color-picker depends on vue and webcam-video depends on lit and you write video-color-filter in LWC, your project now depends on three web component libraries.


Given that React is the exception in regards to WebComponents support.....


> That means your app will take twice as long to load

Preact is like 3k minzipped. Just loading it will not make your app take twice as long to load.


Preact is one of the very smallest frameworks. A full-fledged Vue bundle is ten times that size, and Angular is another 2x Vue's size. When I said "twice as long" I meant on average: taking some framework X and adding another framework Y.


"To me, it represents a huge failure on the part of the developer community not to make publishing web components the standard."

How does "blaming the customer" help here?

It's not the first time that a standard doesn't fit the people it was created for...


Didn't mean to come off that way if I did -- I'm not trying to point fingers or put blame on anyone. But the fact that as a community, the ecosystem is fractured between major frameworks and there's not a solid interoperable standard is a bit sad.

Everyone is worse off for it. It may be that a spec/implementation does not exist which can satisfy these needs but it would be beneficial for all.


> Here's what killed web components

Wait, what? Web browsers have only recently implemented standards underlying Web Components, such as Shadow DOM. Microsoft has only recently announced the end-of-life of IE11, which doesn't support Web Components. Web Components have only just gotten started!

> lack of native databinding on the web ... it's going to bring in a framework anyway

Here's a lib for data binding Web Components using JSX: https://github.com/wisercoder/uibuilder This is a 200-line lib, hardly a "framework".


> I can only assume there's some fundamental implementation roadblock I'm missing.

Current low level DOM API has something that fancy reactive data binding techniques will never have: ability to efficiently be used for an extremely wide range of data binding techniques and philosophies.

You go ahead and require implement something like virtual DOM as a standard, then what is everyone who doesn't want virtual DOM, or even this particular flavor of virtual DOM supposed to do? Virtual DOM designs are high level and not extensible. That is not something we need to be forced onto us for decades to come.

That might be hard to understand if you like React and its virtual DOM, and assume something like that will be made the standard, and will remain in fashion forever. How about: Angular v1 bindings are now the standard built into the DOM. How do you feel about that? That's how standardized virtual DOM will feel like in 10-20 years even to those who like it today. No matter what kind of data binding design you choose, React, Angular, some variation of observables or what, it will suck for a lot of people, and increasingly so as time goes by and fashions change.

Data binding is a solved problem on the frontend. It's just solved by libraries in many different ways depending on the developer's preferences. There is nothing wrong with that. The long term cost to centralizing all this diversity into a single opinionated high level API blessed by W3C is completely unacceptable. The low level API is working just fine today.


Data binding needs to be added to the JS standard. I am all for "separation of concerns" but I think we need to admit that HTML/CSS/JS has become a de facto tightly coupled standard of modern applications. I don't like it. I would much rather use JavaFX or somethjng else, but Web apps are here to stay. And like it or not, having to import external libraries to do something as simple as data binding is unacceptable.

JavaFX bindings are a joy to work with and everything "just works". You have FXML for Mark up, you have controllers for logic, and you have the freedom to create your own beans or database classes or use Spring or whatever you want to do. JavaFX is arguably an external library, but since it is packaged with Java I would say it is closer to being part of the standard library (certainly more so than React is part of JS).

There needs to be a dead simple way to tie the properties of a Web component to a JSON object. That's all it would need for now. I could develop some great small-medium Web apps without a single line of external JS with that alone. No more event triggers followed by queries followed by DOM manipulation. I just want to update a JSON object, and have that immediately reflected on the UI, for both built in and custom components.


Lit-html (not LitElement) would seem to fit the bill.

I build very large and complex apps for my clients using lit-html and vanilla web components.

Mostly just stay in the light dom unless there's a reason to hide in the shadow.


> Here's what killed web components: lack of native databinding on the web.

We have one, and it's called DOM, and XSLT to expand XML data into full fledged documents.

It's just browsermakers collectively conspired to sabotage declarative features to push their numerous JS based "bicycle reinventions."

We also had XForms, but this is an even longer story.


We had XUL at one stage which is I think what you’re talking about. It just never took off. I think you’re pointing out that the premise itself is flawed given the clunky nature of html, which could be why ...


I'm pointing out that HTML as it exists right now doesn't solve the big problems around this. I still think it could be extended to do so, but what's important here is that it hasn't been.


> HTML as it exists right now

Is there any other kind?

Seriously wondering if there’s something specific you had in mind ...

My take is that it’s a harder solution space than can be solved gracefully with a single technology. It’s always easier to take a more convoluted approach. I think what confuses us is the visual nature of these apps; we think we should be able to describe them visually, and maybe you can, but it’s seldom worth the time and effort.


Totally agree with you. I'll add to that a lack of native reactivity.

The observable proposal has existed for years. It's still in stage 1 and was last presented in to the TC39 in 2017 [1].

There seems to be an almost total disconnect between the needs of web developers and what the TC39 is working on. Data binding and reactivity are two important points, but also the need of optional static types which should be obvious by looking at the meteoric success of TypeScript. This is nothing new, it has been discussed since ES4 times 10+ years ago.

[1] https://github.com/tc39/proposals/blob/master/stage-1-propos...


Isn't observable superseded by Proxy?

Most (all?) of what is enabled by observable should be possible with Proxy, right?


I guess Observable as in RxJS Observable (or the likes). Similar to Promise which is now part of the standard.


Good point although Proxy is pretty low level (for the JS world) and you still need to implement a lot of stuff yourself.

I would have expected something more akin to RXJS, MobX, or even the Svelte reactivity system.


> Here's what killed web components: lack of native databinding on the web.

I tend to agree with this broad idea. Although I don't think it's because it was left out or someone didn't do it. I think it's because it's REALLY HARD™. This is certainly the problem that React/Vue/etc are trying to solve. But I think web components never lived up to the promise because as an industry we simply haven't solved that problem yet. OOP possibly came as close as we've come. The various JS frontend frameworks have also been a decent attempt, but I just don't think it's good enough yet.

If I had to guess I'd say that FRP, functional programming's take on it, has the best chance at succeeding here. But I don't think it's quite there yet either. And even if it was, you still also have to confront the fact that the HTML/CSS split doesn't completely live up to the goal of the style being completely independent from the markup.


The issue with taking a FRP approach for any native solution, is that it would be fairly at-odds with the web as it works now. In particular: I don't know how you'd do that within just HTML, without any JavaScript. The style used by the likes of Angular and Vue, on the other hand, would be a much more natural fit for the web platform, for better or worse.

> This is certainly the problem that React/Vue/etc are trying to solve. But I think web components never lived up to the promise because as an industry we simply haven't solved that problem yet...The various JS frontend frameworks have also been a decent attempt, but I just don't think it's good enough yet.

I think the territory has been thoroughly explored at this point, and simply taking one of the established approaches and implementing it in C++ would be the right way forward. Now, back when web components were really making waves the landscape was different. This new wave of reactive frameworks was still fairly immature, and maybe in hindsight that's why they didn't standardize databinding at that time: it wasn't yet obvious what to standardize on, exactly. But I think in 2020 we're now past that point.


> Here's what killed web components: lack of native databinding on the web

"Modern Frameworks like React/Vue/Angular and Web Components are built to solve different problems. Web Components provide strong encapsulation for reusable components, while Frameworks provides a declarative library that keeps the DOM in sync with your data. The two goals are complementary. As a developer, you are free to use a Framework in your Web Components, or to use Web Components in your Framework, or both."

https://reactjs.org/docs/web-components.html

I have a side project for selling reusable HTML blocks/sections, some people advised me to convert it into Web Components since it can be reused between different Frameworks (React, Vue, Angular, etc) at the same time.

After reading this discussion, I think we should build a native components for each Framework.


Related to this, it annoys me that Polymer is sometimes described as not a framework, as if it's just a set of polyfills/shims.

Of course it's a framework, it provides a data-binding system that is incompatible with other frameworks, and which isn't simply a polyfill.


Exactly. The best piece of supporting evidence for my original point is that even Google themselves, in all of their Web Components marketing, used Polymer for everything. To the point where some people didn't really even understand the distinction between the two! That was a giant admission that this stuff is useless without databinding.


The web components under the hood would still need a way to program themselves in response to that data, so a templating language would need to be baked in along with data binding.

Secondary languages are a bad idea, so hopefully this templating language would be something like jsx/ejs.

The proposal really is to bake applications support in to the browser. That seems right to me. The browser is more and more an os, and it should support rich applications out of the box.

React is derivative of windows application development, so there is precedent for something like it to be baked in to an OS.


Lit-HTML is a templating system that's baked into Lit-Element, which is basically the successor to the Polymer framework. It simply uses JS template strings, with a few little niceties in the binding syntax to allow for things like setting properties rather than attributes, adding/removing boolean attributes, and defining event handlers inline. It lacks two-way data binding, but we use "data" elements as a centralized data store. That store provides a master state object that's passed down to every component on the page - though frequently it's just a sub-tree of state that gets passed down. If a component receives some input and needs to update its state, it fires off an event with the updated value, which has a corresponding handler in the data element. That handler taps into a functional pipeline we've built to handle function composition, passes the information down the appropriate pipeline, and the master state is updated appropriately. At that point the data element fires a "state-changed" even that basically everything listens for, and whoever cares can then update their own little bit of state from the master store (typically one line of code).


We do very similar things.

Works great.


> I fail to grasp why databinding hasn't made it into a web standard yet.

I agree! And this is something we plan to address in a future version of https://braid.news!

One problem with standardizing this now is that we don't have a standard for "data that changes." Braid is adding that to HTTP so that you can subscribe to a changing URL. Once that works, we just need a standard way to bind a UI widget to the URL.


It's not snarky. It's good natured, and justifiedly awesome and elegantly mocking the bullshit of these ridiculous JS afficianadas/os. I was hinting the hype in 2014 with shadow v0 and the promise has been broken.


> custom value-parsing strategies because HTML attributes are just strings

HTMLElement have properties too, and custom elements can accept any non-string data via properties instead of attributes.


I love her description of using a dependency-laden component:

> Using a custom element from the directory often needs to be preceded by a ritual of npm flugelhorn, import clownshoes, build quux, all completely unapologetically because “here is my truckload of dependencies, yeah, what”. Many steps are even omitted, likely because they are “obvious”. Often, you wade through the maze only to find the component doesn’t work anymore, or is not fit for your purpose.

That is so true. The "unapologetically" thing is important. I see this all the time. There's often a fair bit of 'tude, where I am looked at with condescension, for not knowing something "obvious."

The fig tree pic is perfect.

EDIT: Removed phrase that was possibly corrosive to the narrative.


I see this too and is very frustrating in modern Web learning.

It might take 8 files and 15 dependencies to make one example work. Only 3 files are partially provided. 5 dependencies are deprecated or no longer supported.

The informative websites aren't designed to help you learn, they are designed to help the helper: get views, get cred, get employed, get ad revenue, get an ego boost.


> BTW: This lady has a Masters from MIT. She def knows her way around things.

Moreso than that, Lea is near the end of a Ph.D. in David Karger's group, an expert on CSS, and overall amazing researcher and developer for the web.


[flagged]


I don't think people are "backing her up" because of sexism. I saw it more as: "She knows her shit. Dear devs, pay attention"

And yes, Lea is pretty awesome.


Yup. All too often I see posts just like this from someone who self taught themselves javascript two years ago and after building a few personal projects, thinks they're an expert on it.


> It's sad to see the sexism in the need to preemptively back her up.

You have GOT to be kidding me. Tell me that this was a joke.


> There's often a fair bit of 'tude, where I am looked at with condescension, for not knowing something "obvious."

This is a huge red flag for systems design to me. Whenever and whereever I've seen this abundance of assumed implicit knowledge instead of documented or introspectable configuration, the systems have invariably been excessively difficult and/or time-consuming to troubleshoot once in operations. This is overlooked and hand-waved away when the system is the new shiny, but once it becomes productionalized "legacy", it becomes a huge headache to leadership that appears to them as constant instability sucking up everyone's time on fire fighting instead of innovating more new shiny.

Here's to hoping better dependency management like from the Nix folks makes it into the mainstream platforms.


> Here's to hoping better dependency management like from the Nix folks makes it into the mainstream platforms.

Apple's SPM is off to a good start (It's the one I use). Carthage is too primitive, and CocoaPods is...CocoaPods.


There are some lightweight approaches to web components. For example µce is extremely small and provides web components with no build step [1]. If you use the author's once-defined 140 byte library, you can also avoid having to bundle everything per component [2].

For those not quite ready to throw away frameworks, heresy [3] might be more up their alley, or if you're not as set on production readiness yet, check out my own barleytea.js [4] which is written in a little over 300 SLOC and has zero dependencies or necessary build steps.

I guess my point is, there is a good variety of microframeworks out there striving to meet this need.

[1] https://github.com/WebReflection/uce [2] https://github.com/WebReflection/once-defined [3] https://github.com/WebReflection/heresy [4] https://andrewfulrich.gitlab.io/barleytea/


This is everywhere in programming. Just trying to setup vim involved learning an insane amount of information that is scatter documented with every person recommending different ways to accomplish the same task. You feel stupid for not knowing one tiny part.


Setup vim? You literally type `vim`

You can customize it to your hearts content, but that's absolutely not necessary to use it proficiently.

Plenty of software tools work out of the box, are turnkey, etc.


> BTW: This lady has a Masters from MIT. She def knows her way around things.

I agree with all of what you said until you bought up this unnecessary credential wrapper. It leaves a bad taste - statements like this. I don't know why. Going to MIT is doesn't make you an automatic genius nor does it mean that they know their way around things. It bothers me.


Cool. I'll remove it. Not necessary for the narrative.


Thanks for being receptive.


Probably a more relevant fact is she's on the CSS Working Group, meaning she has a voice on the CSS spec.[0] She has an important and influential voice in this space. Lea Verou is an expert on frontend and has been for years. I have her book and really enjoy it, it's like a coffee table CSS book with gorgeous pictures and mindbending techniques.

https://en.wikipedia.org/wiki/Lea_Verou


Contrasting anecdote - the credential signalling was useful to provide context, else on JS topics it's rational to assume there is a fair to middling chance the writer really doesn't have a grasp of the wider industry body of knowledge, which quite evidently is fairly common for JS topic writers.

I value the additional factual information over removing useful information to try and avoid upsetting anyone at all. I wish more people realised how much real value is lost when everything is filtered.


> It leaves a bad taste - statements like this. I don't know why.

Probably because those statements are logical fallacies, this one specifically is known as argumentum ad verecundiam in Latin, or "an appeal to authority."

The fact that the arguer holds a prestigious title (or wears a fancy crown) cannot prove or disprove any given statement.

The inability of humans to think logically has bothered people for thousands of years, read up on Aristotle for more info.


Just to set the record straight, here's why I mentioned it:

I like her writing style. She writes in a pithy vernacular that belies her educational credentials.

She writes like a cranky old man (takes one to know one). I think we need more writing like that, as opposed to the usual buzzword bouillabaisse that makes up a significant chunk of the tech WordSphere.

When someone writes like that, it can be easy to dismiss (I know this). I didn't know about her, or her creds, and was pleasantly surprised, when I read them, so I figured I'd share my pleasure and surprise.

I encourage highly-skilled, -experienced, -educated, -whatever folks to write in an accessible fashion; preferably, with warmth, humor and approachability. The world needs as much of that as possible.

I could really care less whether or not she is a woman. It probably means a lot more to her, than it does to me. I enjoyed her work, and my enjoyment was improved, when I learned her background, and expressed my pleasure.

I mean, why the heck do we always have to find things wrong with everything? Can't we just say "This is cool. I'd like to hold it up as an example of what I like."?


I empathize with you in strongest way possible. I think we all should stop being offended so damn much.

I don’t know why I felt the way I did but you’re right - take it easy, we need to be a bit more flexible and allow for room of interpretation. Sorry I felt that way in my initial comment.

I think the offending word was “def”.

> This lady has a Masters from MIT. She probably knows her way around things

Sounds much better and less authoritative :) I know what you meant in the general sense.

Side note about the author's credibility: Some of the writing from this article is stolen without credit: https://twitter.com/brucel/status/1305820902903382016

The whole flugelhorn sentence.


The whole sentence? I couldn't even find a part of it other than the sentiment and "flugelhorn"

Seems like a coincidence especially since bashing on all the steps required for modern web development isn't a new idea.


Absolutely, it's time to just ignore the hecklers. They are subtracting from the value that the producers create! When the dead mass of hecklers and pc twitter twatters gets too high our civilisation will fall behind or fail because of it. Healing the pc overgrowth crisis is becoming important for our future prosperity and possibly survival.


This is just the reality of the current JS world and just how it continues to get done for practical and profressional reasons.

The dream is having small self-contained web components and can just drop in to your site (the whole whole anti-JS stuff is a whole other beast and IMO unrelated to practical shortterm goals of getting web components at the browser.

What the components end up doing is still heavily dependent on a JS component building world that was built with a framework in mind and native web component integration as a future ideal implementation system. But otherwise there is no getting away from components being tied together in a wider system with heavy JS dependencies.

Basically nothing has failed. Other than maybe React and Vue et al turned out to be more practical for the above reasons and full native web components are an afterthought. They've been sufficiently simulated where it's not a big deal.


)


I completely agree with the author that WCs fail to push more behaviors into HTML. As she describes, you really want to be able to import the WC's script and then have new useful HTML tags.

I use LitElement pretty extensively, which is a wrapper around WCs, and I like it quite a bit - but it's only a minor improvement in my mind compared to React, and that improvement is just reducing the abstractions from the DOM API. It's still a mega codebase.

I've also tried multiple times to just work with vanilla WCs, and it's sensible only up to a very limited point. If you got a JSX/lit-html module involved it would go further, but at that point it's pretty past "vanilla." And even then, you're not in the realm of "just using HTML."

Author lays a lot of that on the developers having a proclivity for JS, and that may be true, but I've been trying to figure out if this is just complexity in the stack that hasn't yet be solved. UIs are complex, you have lots of stateful interactions between them, and I'm really not sure what the right solution would be for a "do lots via HTML" goal.


My impression is that JS has led WCs for the simple fact that JS is easier to polyfill/prollyfill/ponyfill and there's a lot more infrastructure today for JS modules and JS bundling. Web Components have been a lot of trying to assemble the cart behind you while riding the (JS) horse, simply because web standards are so slow. (I'm not sure if that analogy entirely works, though in my head it adds the unsightly picture that at least some of the material you have to build the cart with is manure, and WCs being built more than partly from JS manure does sound accurate.)

ES2015 modules are about at the point that caniuse statistics show them as nearly viable for production work, with HTTP/2 (or 3) deployment being possibly the last puzzle piece for a global lessened reliance on bundling for performance reasons. (Though not for simplicity of usage reasons: it's still useful to be able to drop an entire third party bundle all at once on a file host and use the thing as a single import.)

Meanwhile, CSS Modules are still something prollyfilled by JS bundlers and there still isn't an official spec yet?! And "HTML Modules" is so barely on the drawing board that it would be optimistic to call what JS bundlers are doing there as anything resembling a "prollyfill" (we're to "wishfill", I guess?). (And most JS WCs are using virtual DOMs or JS-native template tools instead of HTML templates anyway.)


The important thing about web components is that we _can_ import the component's script and then have new useful HTML tags.

You can drop this on a page and it _just works_:

    <script type="module" src="https://unpkg.com/chessboard-element?module"></script>
    <chess-board></chess-board>
And this is built with LitElement.

Live demo: https://jsbin.com/kicelemara/2/edit?html,output

Having dependencies doesn't change the external interface to an element, or prevent it from being drop-in. Dependencies are very often good, because they are well tested implementations of a common need, rather than ad hoc implementations that may be brittle or duplicative.


Yes, thank you. I don't know why "they have dependencies" is a valid criticism. Literally any complex thing where the developer didn't write 100% of the code has dependencies. Most of the dependencies for the web components we use at work are... other web components, which is EXACTLY THE POINT of web components: reusability, portability, encapsulation.

I'll agree with a few of her points, but as far as this point goes, I have to wonder what components she's trying to use here. And if she wants to see the full markup of the shop demo, all she has to do is use "inspect element" on it rather than "view source."


Would it help if we made a standard for communication between web components, so whatever tools they use internally, you can wire them into your code or to each other?

Web components are abstraction boundaries, and you have to define boundaries carefully or you still end up with a big ball of mud, now with extra layers of indirection to make your life even worse.


We have those standards: properties, attributes, events, children, CSS custom properties and ::part(). It all works quite well already.


Yes, but I'm unsure what a well-designed execution of that would look like.


> Can we fix this?

Sure, by returning to basics.

Let's assume that Web Component is a DOM element with a code associated with it + lifecycle events.

Here is how Components are done in Sciter ( https://sciter.com )

1. CSS has got `prototype` property:

   div.my-component { prototype: MyComponent url(script/components.js); } 
where MyComponent is the name of class in JS, url (optional) is an URL where this MyComponent can be found.

2. In script that custom component is usually represented by ES6 class (+ decorators)

    class MyComponent extends Element {
       // lifecycle event/method
       componentDidMount() {  }
       // lifecycle event/method 
       componentWillUnmount() {  }

       // component specific methods
       foo() { }
       bar() { }

       // event handlers - decorated functions
       @event("mousedown")
         onMouseDown(evt) { }

       @event("click", "button#submit")
         onSubmit(evt, button) { }
      
       @event("change", "input.name")
         onNameChange(evt, input) { }
    }
and that's it. Sciter lives with this schema more than 10 years - proven to be very convenient and flexible.

Yet simple: one property `prototype` + simple wiring of lifecycle events.


This is literally what a custom element is. Assuming your @event decorator is built upon the EventTarget interface:

  class MyComponent extends HTMLElement {
    // lifecycle event/method
    connectedCallback() {}
    
    // lifecycle event/method
    disconnectedCallback() {}
    
    @event("mousedown")
    onMouseDown(evt) { }
    
    @event("click", "button#submit")
    onSubmit(evt, button) { }
      
    @event("change", "input.name")
    onNameChange(evt, input) { }
  }

That said, custom elements don't cost $310 for an indie license. Instead, they are free and available in every web browser.


> @event decorator is built upon the EventTarget

In Sciter it is not. @event there is not calling Element.addEventListener but declares event handlers as static table associated with class.

Essentially components are attached to DOM elements by calling Object.setPrototypeOf(element, MyComponent) - no memory allocation is happening (modulo code in componentDidMount) - very fast and lightweight.

Yet, in your sample, you've missed the call of customElements.define(), that alone is limiting use cases quite a lot.

> custom elements don't cost $310 for an indie license.

Sciter is free, as browsers too, components in SDK, hundreds of them, are free too. You will need to pay $310 only if you need source code of Sciter Engine itself.

Sciter is like a browser in that respect, try to request source of MS Edge or Google Chrome for any money - good luck with that.


The web components in Chrome and Edge are both implemented in the open source Chromium project. So, it is free for all to read, use and modify as they wish (in accordance with the terms of the license https://chromium.googlesource.com/chromium/src/+/master/LICE...)


Here is running campaign to Open Source Sciter: https://www.kickstarter.com/projects/c-smile/open-source-sci...

By donating there you can help to make it happen, your move?

That will be real Open Source. Edge and Chrome are not Open Source, they are users of it.


Holding open source hostage to a $100,000 goal doesn't sound like "real" open source to me either. And you're still going to offer it under either GPL or paid commercial licenses. Chromium is released under a BSD license which is a lot more permissive.

It's totally fine to make money but when people have valid critiques you shouldn't turn around and try shaming competitors about something that you're not even doing.


Yes, it is BSD, but who pays for Chromium development?

By financing that BSD project that organization is buying the right to define Web standards by its own.

BSD is just a business model for them : you wine her, you dine her, you buy her. Such an Open Source, eh?


after doing a bit of vue I wanted this :)


The good thing about this mechanism is that you just need CSS in order to declare your components.

The script will run only if you have elements with matching selectors. So you may have component libraries. Browser will instantiate only used components.


Fully agree with the author.

My biggest complaint about web components is that I don’t see a lot of advantages over using React, Svelte, or some other JS library. The author hints at this: if I’m already committing to a big JS build process, why wouldn’t I reach for one of these more ergonomic JS tools? Warm fuzzies for trying to use open standards isn’t enough to convince most people to switch away from more popular JS solutions.


The benefit isn't warm fuzzies - it's interoperability: with other components, tools, the browser and devtools, other developers.

If you build an app with web components, even if you're using one specific helper library to do it, it makes it possible, easy even, to incrementally migrate to other libraries. You can migrate top-down, bottom-up, or even middle-out to other helper libraries and have a continuously working app. You can import and use another web component built with another library without being constrained to just the framework you chose.

You can even build an app with all web components, later decide you really don't like them and want to use only a framework and still easily incrementally migrate top down and not break the app.

This makes web components the much safer choice for large and long lived projects, and more flexible for projects of all sizes.


One huge advantage is that you can isolate a web component in its own shadow DOM, which means it has CSS that's independent from the rest of the page. If you're making something for other people to embed in their code, even if you're on the same project, you can save them from breaking it by styling it by mistake.

You can also close the shadow DOM to stop people easily inspecting it, but I must admit I haven't actually figured out a reason to do that yet.


That is the same if you use e.g. styled components with React, where every component is self-contained and doesn't leak the styles. The mechanism is different, but the end result is the same, and oh it's a game changer IMHO.


The difference is that web components provide browser supports low level APIs which frameworks can use to make isolated components.

Sure, you can get the same effect in React. But that only works if everyone on your page is playing by the same rules and using React.

I can drop a web component into some legacy page which is full of old school jQuery and global CSS styles and my component will be isolated and work. Try the same trick with React in that situation and it will likely conflict terribly and get stomped by the old legacy code.


But why should developers have to use a framework like React to do something the browser could provide for them? Not everyone is writing a JS application. Some just need to add some custom HTML, CSS and little bit of JS.


I don't think the GP was arguing against that. If you're already committed to an existing build process building new components as web components doesn't really have many advantages vs a component built in react. It's just adding needless complexity.


Web components can be built separately to the rest of an application as standalone components and included by adding a <script> tag, and then using them is as straightforward as using an HTML tag. You need a build process for the component (or the author of the component does..) but you don't need one for the website you're using it in. You can do that with a React component as well but you don't get the benefits of things like styled components if you do. You do with web components.


you can make your component's css "not leak" if you name all it's classes with random uuid and scope all selectors accordingly, exactly what styled components does. But "not leaking css" is a nicer way of saying that you can't customize it.


There used to be something similar to do this called "scoped styles", but they were removed in favor of WebComponents. We could have had this without all of the Shadow DOM baggage.

Though maybe it's coming back now? https://github.com/w3c/csswg-drafts/issues/3547


(Disclaimer: author and editor of the modern custom elements spec here.)

The specific "failed promise" that I see is largely this positioning of web components vs. frameworks.

How web components was originally envisioned was as leaf-node or light-DOM-using components, of the sort HTML already has. For example, <dialog>, <details>, <input type=range>, etc. Web components was supposed to give you the tools to create your own components of this sort, such as <tabpanel->, <toast->, <carousel->, <switch->, etc. In particular:

* Custom elements gives you the ability to just drop in tags, like you do with vanilla HTML, and those tags can react to lifecycle events like being added/moved/attributes changed, automatically. The browser mediates between those occurrences and the web component's code.

* Shadow DOM lets you encapsulate the inner details of your component, while using slots to reproject content into it. So e.g. <switch-> could have its innards entirely in shadow DOM, just like <input type=range>. While <tabpanel-> would be given children by the web developer using it, with some of those children being special (like <summary> is special for <details>), but some parts hidden in the shadow DOM and not provided by the web developer (like the disclosure triangle and behavior for <details>). More on this in https://glazkov.com/2011/01/14/what-the-heck-is-shadow-dom/

From this perspective, the lack of data-binding (cited in a sibling thread) is not a big deal. There's no data binding for <input>, or <details>, etc. You just use normal DOM children and attributes to supply the data, perhaps with a framework to do that via binding or React-style re-rendering or whatever.

Instead, we've seen people use web components as a React competitor. They want to write their whole app in web components, starting from a <my-app> component on down. It turns out the system is flexible enough to do this, but it wasn't designed that way from the beginning, and doing this doesn't play to its strengths. You end up just creating new frameworks, which are slightly smaller and potentially a bit faster than other frameworks because they can rely on native code for some of their lower-level building blocks like style encapsulation. But you're not living up to the promise of reusable components which behave like built-in elements.

Edited to add: I do understand where developers are coming from in this regard. Using web components for leaf/reusable components and React/Vue/whatever for app-specific components is probably twice as many component models as most app developers want to deal with. I'm not sure how to deal with that tension.


Agree with this 100%. It's called Web Components since it's best used for writing individual components that be dropped into larger apps. I did a side project with LitElement recently, and just could not find the value add over React. That's when I realized that was never the intention anyways.

I think the desire to make Web Components a React competitor also comes in part from the movement towards 100% static sites, i.e. no server HTML generation. So if I'm building a shopping app, I would never create an HTML file with the following with proper declarative HTML:

<shop-app> <shop-item name="Nike Air Force 1" price="85" currency="dollars"></shop-item> <shop-item name="Nike Lebron 18" price="130" currency="dollars"></shop-item> <shop-item name="Nike Kobe 8" price="145" currency="dollars"></shop-item> </shop-app>

Then, you can add interactivity with JS events or a JS framework. Instead, you'll just see:

<shop-app></shop-app>

where the data to render the child elements is dependent on an AJAX request that gets the initial data. Creating standalone, declarative, and well-scoped components is just not necessary in this case, since everything is done in JS anyways.


My thoughts exactly. For some reason people tend to think that a web component should stand on its own from high level. But that's just not how HTML works. Something like <shop-app></shop-app> should be seen as an anti-pattern IMO.

I see web components as a compositional approach for dealing with complexity.

Something else that is extremely powerful that people seem to forget is that you can add a src attribute to your web component that links to JSON data, or HTML fragements on a server. It can give you a lot of caching and concurrency opportunities, browser engines are extremely efficient dealing with this. For most people an src attribute feels really obvious for an img tag, but apparently less so in other contexts.


As somone who builds large apps via web components, I couldn't disagree more.

I'm able to compose components into higher order screens and get an enormous amount of reusability across projects.

I have a set of components, screens, etc... that I've built up over time and I can mix and match them and whip out an app extraordinarily fast.

Additionally, there are some great design systems and component libraries like Ionic built on top that make this even easier.

I can write a component for a client, and they can use it anywhere in their ecosystem, regardless of technology.


In what way does <shop-app> not deal with complexity through composition? It is a component, composed of other components, which in turn are composed of further components.

At what arbitrary level of complexity should we stop composing?


At the level where the overhead from it exceeds the benefits of componentizing. It's a subjective judgment, sure, but that doesn't make it any less real.

In particular, if something is never going to be re-used, what's the point of componentizing it?


In some contexts, decomposition into easily workable scope of complexity.


Because then you don't have to pass a huge framework library down the wire along with all of your custom code? Look at it the other way, if you don't get a big advantage over web components by using React, Svelte, etc then why would you use them? Web components are natively supported by modern browsers. Using a fairly simple base class like Lit-Element to provide some template niceties and lifecycle hooks gives us all the extras we need. We've figured out a really nice top-down functional state pattern for data that eliminates the need for two-way binding and requires very little "framework" level code - it's probably like 100 lines if you take out whitespace and comments.


> Using a fairly simple base class like Lit-Element to provide some template niceties and lifecycle hooks gives us all the extras we need. We've figured out a really nice top-down functional state pattern for data that eliminates the need for two-way binding and requires very little "framework" level code - it's probably like 100 lines if you take out whitespace and comments.

I'm also a fan of LE, which I'm using to build my current side-project.

However, the data doesn't back up this claim. A component built with LitElement gets about 19 KB added to it when bundled:

https://webcomponents.dev/blog/all-the-ways-to-make-a-web-co...


This article is tailored to attract the web components haters. IMO it does not foster a constructive thread of discussion, and some of the critique just as easily applies to the JavaScript ecosystem overall.

Web components have some distance to go before they are ideal for all of their envisioned use cases. In particular, I am awaiting declarative shadow roots, declarative custom elements and template instantiation ("data binding").

That said, the work that has been done so far on them is impressive. Web components by and large have survived the needless antagonism they have received from some corners and proved themselves in production scenarios from companies big and small. If you have interacted with a Salesforce application, you have used web components. If you have visited Github, you have used web components. If you watch videos on YouTube, you have used web components.

The ground truth is that web components are solving problems and making headway. They only stand to get better as new capabilities begin to land. I'm excited for what the future holds.


I do work in Salesforce, and I find Lightning Web Components easier to use and understand than the popular frameworks. Yes they require JavaScript, but the alternatives don't?


> This article is tailored to attract the web components haters. IMO it does not foster a constructive thread of discussion, and some of the critique just as easily applies to the JavaScript ecosystem overall.

I think you missed reading to the very end! She concludes on a hopeful note that we can do a better job with Web Components, with a few specific proposals on what a better future could hold.


The death of HTML imports killed web components for me.

With HTML imports, you would import a HTML file. In that file would be css, html and the js to make the component. Then you’d use HTML as usual in your main file.

Finally you could create custom components easily while keeping yourself dealing primarily with HTML.

Instead, you were forced to use bizarre js import systems. And at that point you were in JS land. Firefox’s decision not to support HTMLImports in favour of waiting to see what happens with JS killed it.


What's the point though to bake that into HTML if you need tons of JavaScript to make it happen anyway? You can just as well use the flexibility of JavaScript to build up component graphs. HTML, or rather SGML, has an established method of syntactically composing fragments using SGML entities that is well integrated into the process of editing HTML using plain text editors, not to speak of extending the vocabulary with new elements and their content models in powerful ways. Introducing elements into markup using script rather than declarative means only serves to complicate parsing, with questionable benefits.


Because with HTML you would use HTML to structure your elements. Javascript was never designed to structure element s we get things like JSX, to compensate, adding further complexity. HTML Imports was an attempt to keep with the existing platform.


> In that file would be css, html and the js to make the component.

You can do that. Here's an example Web Component that contains the css, html and javascript:

https://github.com/wisercoder/uibuilder/blob/master/WebCompo...


I'm talking about how you import that into your main HTML file.


I recently stumbled across "shoelace", which at a glance seems like an example of what the article is hoping for. It's a thoughtfully designed library of UI web components.

https://shoelace.style/


Thanks for the link. This library unfortunately highlights further challenges with Web Components like mixing custom WCs with native form elements. To use Shoelace form elements at all, you'll end up writing a bunch of JavaScript.

> Shoelace forms don't make use of action and method attributes and they don't submit the same was as native forms. To handle submission, you need to listen for the slSubmit event as shown in the example below and make an XHR request with the resulting form data.

> https://shoelace.style/components/form


This is fixable, using the form-associated custom elements feature that's specified in HTML. (Introduction: https://html.spec.whatwg.org/multipage/custom-elements.html#...)

However, that's only currently shipping in Chrome, despite the other browsers being positive on it.

Similar capability gaps that we're working to close are accessibility (https://html.spec.whatwg.org/multipage/custom-elements.html#..., same situation, everyone likes it, only Chrome ships so far) and focusability (https://github.com/w3c/webcomponents/issues/762, still figuring out what the solution should be).


That’s great, thanks for the links.


> To use Shoelace form elements at all, you'll end up writing a bunch of JavaScript.

Shoelace author here. This is somewhat true (I wouldn’t call it “a bunch” though), and it will be until form-associated custom elements are standard. However, I’d argue that most form validation and submission is done with JavaScript these days. I can’t think of the last time I saw a post request submitted from a form in the wild. (Not that it doesn’t happen, but it seems to be quite rare now.)


Thanks for the reply! Shoelace does look great, and I recognize doing the form submission this way is a requirement currently. Hopefully the links above about allowing custom WebComponents to act as native form elements will further enable Shoelace.


Shoelace is awesome! Also it is built with Stencil, which is a tool that generates web components from a development experience React and Angular devs would find familiar.

One of the benefits of Stencil is that it can generate Angular, React, and Vue-specific bindings. This smooths over any issues React has in working with WC's and provides a first-class React experience.

Stencil was built to power Ionic Framework which is arguably one of the most popular web component UI libraries. Fun fact: there are many thousands of app store apps built with web components! (data: https://appfigures.com/top-sdks/development/apps). This underscores a fact about WCs: their proliferation is largely happening behind the scenes and unnoticed by many in the web world.


... and it suffers from the same oversight every other web component library (polymer, mdl) suffers from:

- I can't swipe left/right between the tabs

- I can't pull the menu out from the left by swiping the entire page right

Two of the most basic touch navigation metaphors aren't supported. To be fair, Polymer and MDL don't support the above either. But this is why HTML5 apps are still not up to par with native apps. I really want to see a web component library with full touch functionality -- tab swiping, pinch zoom on images, pull to refresh on lists and card lists.

https://shoelace.style/components/tab-panel


> it suffers from the same oversight every other web component library (polymer, mdl) suffers from:

> - I can't swipe left/right between the tabs

> - I can't pull the menu out from the left by swiping the entire page right

Most native apps don't do either of those two things either... at least on iOS. I can't speak to how Android apps behave these days.

Maybe these are your favorite interaction modes, but it really has nothing to do with whether X is "up to par with native apps."

I'm certain these things could be implemented. Clearly they weren't considered desirable by the authors of Shoelace.

What really holds HTML5 apps back is the fact that Apple consistently drags their heels on adopting push notifications for web. It only has to be available for apps that have been added to the home screen, so all the users who complain about getting nagged for notifications as they browse the web would still be perfectly happy not to be getting nagged. Without notification support, the number of companies who seriously invest in HTML5 apps (instead of native apps) is nearly zero, which really hinders investment in HTML5 frameworks targeting mobile app development (not frameworks just targeting mobile website development).

Clearly, Apple benefits from pushing app developers into the App Store where they can require those developers to give them a cut of the profits.


> I'm certain these things could be implemented.

Pulling a menu out from the left certainly cannot be implemented on iOS Safari Mobile, because it doesn’t support https://caniuse.com/css-overscroll-behavior

Supporting swipe left/right fails hard on iOS Mobile Safari because the browser wants to history navigate back/forward if you misplace your finger, and it is easy to inadvertently refresh the page unless you are very careful not to. I don’t think there is any effective workaround.


> Pulling a menu out from the left certainly cannot be implemented on iOS Safari Mobile

Well HTML5 apps will never be a good experience on iOS then. On Android you can do almost anything UI-wise with Chrome, which paves the way to HTML5 installable apps.


My hot take: hamburger menus are a really bad UX paradigm in almost all cases, and bottom tab bars are much better.

So, I disagree entirely: iOS can easily support fantastic HTML5 mobile apps... if push notifications ever become available.

From what I remember, Google started switching to bottom tab bars a couple of years ago, even on Android. But, when you have a bunch of features, it's much easier on the developer (not the end user) to just stuff them in a hamburger menu and say "eh, good enough..."

Link that seems relevant, but I've really only skimmed it: https://uxplanet.org/tab-bars-are-the-new-hamburger-menus-91...


> bottom tab bars are much better

The last time I looked they were incredibly fragile to implement on mobile device browsers. Mobile Safari had borkage: rotation or tab addition/deletion changing the page height such that you occasionally lose the bottom bar; input focus loses the bottom bar or leaves the bottom bar occluding elements (position sticky doesn’t recalc when page scrolls). Problems with strange interactions with the browsers own bottom bar. Both have problems when the page is zoomed, which seems to happen sometimes even if explicitly disabled e.g. input focus?

I could make something that looked like it worked, but when actually manually testing it hard, there were show-stopping problems.


To be clear, I'm talking about HTML5 mobile apps. Apps that you add to your home screen from the web, where none of the Safari chrome is visible to interfere with things. You rarely encounter this kind of thing precisely because notifications aren't supported, as I've been saying. Chat apps? Most users want notifications. Forum apps (like Reddit)? Most users want notifications. Calendar apps? Shopping apps? Podcast apps? Weather apps? Almost every user wants to have the option of notifications for these apps. Video games? Most companies want notifications to drive user re-engagement... even if a lot of users don't allow games to spam them with notifications. Virtually every kind of app benefits from or completely requires being able to alert you that things have happened.

There's very little reason for good tools to exist right now, when notifications don't, and this seems intentional on Apple's part. Great tooling could definitely exist for HTML5 mobile apps to make it a good experience to build great apps that way... except for the lack of notification support on iOS. Historically, the Google Play Store is so lax about things that there's no reason not to just submit apps there. You don't even have to give Google a 30% cut on a lot of things, if you provide your own payment mechanisms. So, making HTML5 mobile apps for an Android audience has never been that appealing. But, that might be changing soon. On iOS, there have always been a lot of motivating reasons for companies to release apps as HTML5 Mobile Apps, but the lack of notifications just completely stops the idea flat.

For HTML5 mobile websites, a hamburger menu is often an unfortunate reality, but I think having the most frequently used links always clickable at the top of the page is better than stuffing absolutely everything into the hamburger menu. HN does a great job with this.


Side note -- I do wish iOS would get ahead with Bluetooth and WebRTC support, both of which I use heavily on my (private) HTML5 apps.

Push notifications would be necessary for a complete feature set too, although I don't really use them for my private apps since I disable almost all push notifications on my phone.


Its clear Apple wants to force people to native apps where they can extort, err charge, 30% (of the revenue, much larger share of the profit).

So these features almost certainly won't be delivered, in a working state, until they are irrelevant to making useful apps which could move money out of the ios appstore.


https://caniuse.com/?search=webrtc

I think WebRTC is supported on iOS? Maybe it's missing some important features? I'm not personally familiar with what's going on there.

Web Bluetooth doesn't seem to be going anywhere fast, for better or worse.


> Most native apps don't do either of those two things either... at least on iOS. I can't speak to how Android apps behave these days.

I use Android.

- The Facebook app lets you swipe left-right between sections of the app

- Gmail, Slack, Drive all let you pull menus out of the left.

These are just some obvious examples but MANY apps support navigation in this way.


> Gmail, Slack, Drive all let you pull menus out of the left.

At least on iOS, this only works from the left edge of the screen. You can't "swipe the entire page right", only the left edge. But perhaps I'm misunderstanding what you meant there.

Safari on iOS uses swiping from the left edge to let you swipe back to the previous page, so websites couldn't reliably implement that feature this way.

I wonder if any of the popular Android browsers also use the left edge to let you swipe to previous pages?

Websites could certainly let you swipe left to right over any part of the page to pull out the menu, which is what I thought you were talking about, but that's not what mobile apps commonly do.


I work around it by using sms notifications.

Not ideal, but when I describe pros/cons of PWA vs App store, and the only downside is sms notifications, they have so far always been willing to make the sacrifice.


I don't think I've ever used an app I wouldn't have preferred as a web app


I could see arguments for keeping that sort of behavior out of a base library. I've never had to implement a menu that swipes out like that, but I could see it being a complex behavior to get right.

if you need that use case, it seems easy enough to implement


TIL of <dialog> which can get by with very little JS. But why is Safari refusing to implement it and why did Firefox put it behind a feature flag for years?


I think the reason Firefox hasn't exposed it completely yet is to deal with accessibility issues.


Man I remember reading about web components some years ago after reading up on Poylmer Dart. It seemed like they were destined to become a common standard for building web apps soon(tm) but I guess frameworks like React blew up a lot quicker.


They are a common standard for building web apps.

Dart itself hasn't kept up with web standards in general, but that's another story.


> I’m not sure if this is a design issue, or a documentation issue. Perhaps for many of these web components, there are easier ways to use them. Perhaps there are vanilla web components out there that I just can’t find. Perhaps I’m looking in the wrong place and there is another directory somewhere with different goals and a different target audience.

I did a deep dive into web components for a client recently. I tried to see if we could translate an entire Angular component library into Web Components we could share with the entire org and they could use them regardless of wrapping framework. I ran into the same discoverability issues the author did. After finding a new package, I'd spend some time with it, hit its limitations and then by magically finding the right article I'd find an entirely different project. In total I ended up sampling: plain JS web components, Svelte, Stencil, lit-element, Angular -> WC, and probably a few more. None ever really seemed to work, and the jank I encountered in them all via slotting seemed to preclude using them-- I could never get rid of a very noticeable Flash of Un-styled Content.

The end goal the author talks about sounds really nice, a simple script tag to get more HTML. I think in practice though, that end goal isn't so rosy. If your web page is just web components + html/css then perhaps it's performant enough . But if you're working on a truly massive application (think design collaboration tools, etc), then probably you'll just want to keep it all in the framework, you're already paying a size penalty, might as well not pay a complexity penalty as well.

If we can get a simple, useful, and popular web component library as an accepted standard, I think it will be useful to a certain sliver of developer who needs more power than HTML/CSS but doesn't want to learn lots of JS, but I think that will be a sliver of developers, not many. For the rest, I can imagine single-file-per-component compilation based frameworks like Svelte will obviate the need for web components. Remember, html is for the authors, not the consumers of web pages, and if your app is suitably large enough you'll probably need complexity managed in several ways (global state, UI components, data fetching, etc) and in that sense a framework will likely serve you better.


> "I just wanted something that is small and works like a normal HTML element"

My first stop when looking for a web component is always https://component.kitchen/elix because of their commitment to the Gold Standard (https://github.com/webcomponents/gold-standard/wiki), which is basically to imitate native elements wherever possible.


> The other day I was looking for a simple, dependency free, tabs component. You know, the canonical example of something that is easy to do with Web Components, the example 50% of tutorials mention. I didn’t even care what it looked like, it was for a testing interface. I just wanted something that is small and works like a normal HTML element. Yet, it proved so hard I ended up writing my own!

I was looking for some examples of the better approach the author seems to want, but didn't find them.

Found some in the article linked near the bottom:

https://www.smashingmagazine.com/2017/02/designing-html-apis...

The author gives an example of a list-type component. It can be initialized in one of two ways:

- JS-first: an empty list element is added and a JS initializer populates the children from data

- HTML-first: the full markup for the list is added, including children, and the JS works in the background to build the right internal data representation

The rest of the article gives specific, actionable advice on building HTML-first components. For this reason, I think it's a better article to start with.


I wasn’t aware that web components were promising advanced interactivity on the web without JS still doing the heavy lifting.

I watched those early google talks too and he’s right that doesn’t seem like what they were promising earlier.

I think OP confused including components using native HTML style tags would somehow also help solve the giant disparity in what you can accomplish with pure html/css and with JS added on top.

The stuff about JS being dependency and framework heavy seem thrown in but is a bit of a different problem and often comes with the territory with any complex JS.

If Web components weren't ever really going to promise a new JS free future (other than being a clean way to maintain complex layouts and import isolated/reusable chunks of UI) then those ancillary arguments about the JS ecosystem are a different and somewhat unrelated problem.

This is mostly about the others misguided idealism that doesnt sync with the IRL demands on frontend development for interactivity and complex state management vs the very limited offerings of pure HTML.


I’m personally super excited for lit-html’s future in web components. It feels much simpler.


Web Components were crafted for jQuery world.

    $("#datepicker").datepicker()
Custom elements resolves problem we had with XHR HTML response, it instantiates automatically. Problem solved. Widgets were popular and easily broken by CSS, solved by Shadow DOM.


Shadow DOM does not solve any real life problem.

sDOM is spherical horse in a vacuum, my pardon.


I'd appreciate any details from anonymous downvoters.

Any sample that can be done by sDOM and is not feasible without it and associated machinery?


I always saw WCs as the leaves to the root that CSS frameworks already offer.

You can drop in Bootstrap and the whole page looks nice, but the moment you want to use the GUI elements that consist of multiple HTML tags, things get ugly.

WC would offer a way to merge these into one element.

Then you could drop your JS framework of choice in the middle and be done with it.

React isn't cool anymore? Well, at least you can take Bootstrap and its WCs with you. I had the impression CSS frameworks had a longer half-life than their JS counterparts anyway.

I don't really care about all that HTML module stuff or JS requirements. Sure would be cool if things were different, but from a practical POV it doesn't seem THAT important to me.


If there was a way to write JS within the component, I think that they could have taken off - just see how well components are in React, Vue et al.

And to get that to happen, all you would need is the ability to refer to `this` within the component. Aside for that, treat the JS within the component as a module, ability to access global vars, but within scope.

But instead, you are expected to put the relevant JS in the code that creates the component (in the parent document), which means that reusability and is a pipe dream, and components are really not componentized.


You don't need to add anything to the global JS object to create a web component. It can be completely isolated and untouchable from the document's scope, except for registering a html name for the component, so that you can reference it from DOM/HTML.


I'm not sure what you mean?

All my components are totally encapsulated, and each module is self registering.

All I have to do is import "path/some-component.js" and I can then use <some-component> in any markup I want.


It’s hard to tell from the comments here, but the author actually ends her article on a hopeful note and offers concrete proposals on how we could fix the shortcomings of Web Components and fulfill its promise:

– No dependencies beyond one <script> tag

– Syntax and API in line with conventions of built-in HTML elements

– Accessible by default via ARIA

– Themeable via ::part(), selective inheritance, and custom properties

– Only one component of each type in the directory

Which proposals would be beneficial is up for debate (esp. the last one IMO) but they’re worth highlighting and discussing.


What's so embarrassing is that the HTML/CSS/Javascript mess does roughly the job Visual Basic did. But worse.


Is that true? If I download Visual Basic right now, could I make a sensible visual app vs React?

I’m tempted to see if the truth is really out there.


No, Visual Basic 6 can only place controls by X/Y position, has no databinding and no VDOM or way to create controls other than placing them in the designer or manually creating and destroying them in code.

It's pretty terrible unless you want to make UIs with a fixed size and set of controls.


So then I’ll keep the question open. What is the dopest UI framework across any language with great paradigms, design language, developer experience, and of course, dope results?

Right now I’ll say the best iOS/android apps put web to shame. Is Flutter and SwiftUI where we should be looking? The question is specific to semi complex apps (typical crud), not websites.


Yep. Web development is mostly about putting square pegs into round holes, over and over again.


>who revel in complex APIs, overengineered build processes and dependency graphs that look like the roots of a banyan tree.

I keep thinking I'm just being old and cranky whenever I go through "modern" projects and my eyes cross at the overengineering and complexly. Does this mean other people are starting to see this aswell?


If you work in the Salesforce ecosystem, you know they are doubling down on their use of web components in their "modern" development process. This has lead to a very poorly designed ecosystem. It's infuriating they continue to double down on a system that the rest of us are rightfully abandoning.


What is a well designed component given current limitations of HTML spec?

There is no way around it. The author makes really good points but offers no solution. Just complains.

Would love to know more how we can do this better if there is a way.


I wrote a response to this article, Lea was kind enough to respond to it by the way: https://medium.com/swlh/the-failed-criticism-of-web-componen...


For the past 10 years or so, every time I read one of those articles on the state of modern web development, I'm thankful that I've dodged that bullet. Coming from the desktop world, it feels like the amount of complexity exposed to the end users of all those frameworks is quite insane compared to what they're getting from them.


Hi, please take a look at my FOS library. I tried to do exactly what the article describes a web component should do - extends HTML providing new elements that can be used without any further "programming".

https://github.com/victorqribeiro/fos


I'm using lit-element for a project it's much more usable than writing components from scratch. The growth of complexity on the client side is really quite staggering and thanks to browser stagnation I doubt it will get better any time soon. A platform that should be low code is really maximum over code!



Looks like many people were desperately trying for the post to trend which it din't until this one, not sure if this is breaking any HN guidelines, maybe moderator can chime in.


I wrote the response. Maybe someone will submit it another three times and then it will finally catch on…


Something about this website makes mobile chrome scroll at low fps.


It would have helped a lot if JS had a working modules systems on the web.

> What hope do those who can’t write JS have? Using a custom element from the directory often needs to be preceded by a ritual of npm flugelhorn, import clownshoes, build quux, all completely unapologetically because “here is my truckload of dependencies, yeah, what”.

JS has been in a dark & ugly spot, & WebComponents feeling janky & weird is probably 50% the fact that JS is this dark twisting maze where each project has it's own very unique assumptions about how to turn authored JS into usable, deployable JS. We're still hoping, praying that import-maps eventually give us modular javascript code that we can deploy, without having to push it through a handful of compile/build tools: https://github.com/Fyrd/caniuse/issues/4810

By compare, Big Framework land often adopts some suggested normative best paths people can work with (ex, create-react-app bundling build/test/&c tools). Alas, the language itself is still, a decade latter, trying to proceed to useable modules on the web.

The other major point of this article tends towards a JS vs HTML problem, another area I am very sympathetic to & have hopes for.

> Far more people can write HTML than JS. Even for those who do eventually write JS, it often comes after spending years writing HTML & CSS. [...] If components are designed in a way that requires JS, this excludes thousands of people from using them.

There are ongoing efforts with HTML Modules ( https://www.chromestatus.com/feature/4854408103854080 ) to try to make, among other things, bringing in WebComponents much easier, and Declarative Custom Elements ( https://blog.usejournal.com/w3c-declarative-custom-elements-... ) to make building modules much more HTML-centric & declarative versus today where most of the authoring of a custom element has to be done in JS.

There are very real problems, there is too much js, the js module system is still in a 1/2 complete state on the web, & these very much dog Web Components. But the future is exciting, & I continue to have hope that a much better, much more web native way of building emerges on the web platform. Lea talks a lot to how scattershot the last decade of work has been, how inconsistent, but given the other ecosystem constraints I'm not fully surprised, & I'm delighted that we are spending so long building & experimenting & learning, that for many of us, the hunger is very real. Also missing, the big adopters of WebComponents have been pretty silent, their thought-leadership seems missing: Youtube, Github. There are visible people from these worlds talking about WebComponents, but to my knowledge the real experience of WebComponents at scale from the very successful adopters remains a story not told.


Another "big issue" (for me as I develop first on FF) is that Firefox developers refused to implement HTML import. That'd simplify much of using web-components. I include it and the browser can automatically use HTTP2 to load all the components quickly.

It'd be interesting to see how much web-components could be pushed using only CSS via things like the "space toggle" trick (https://github.com/propjockey/css-sweeper). Though I guess that couldn't emit events and the like.


The JS module system is actually better suited for this.

And ultimately HTML imports don't solve any of the cross-package import issues that JS modules are still trying to solve.


Perhaps, but as a web developer html imports let me pull in and use web-components without writing any Javascript. Give an HTML editor to a 15 year old, some links to a decent web-component library and they're off to the races without mastering JS.


Exactly this. Why should JS be required for something the browser could handle when we're talking about HTML?


Hell, you'd think it'd be a bigger thing among the noscript/privacy world to be able to do more things without JS.


Unfortunately, web components always require JS to work. However, they can hide the JS from the user. Though I suspect that it'd be fairly easy to "whitelist" web-component CDN libraries and disable other JS still.


caniuse statistics say that ES2015 module support has reached something like 92% of browsers:

https://caniuse.com/es6-module


The goal keeps moving though. If I need to process TypeScript files into JS to load them in the browser, why stop at modules and not just go ahead and link and tree shake and all that too?

Maybe things will settle down and browsers will actually run the code that web developers are writing, but the way things are going I don’t see that ever happening. Likely we’ll end up coding in any language and downloading WASM.


people do have other expectations like typescript. but whether we can meet the expectation of "this code should be a module that i can use or you can use or they can use" is much closer to the obvious "what-it-says-on-the-tin" definition of modules. and currently, without a lot of rewriting the module & it's dependencies, that goal is effectively impossible.

i'm not worried about fancy or more. i'm worried about the base case. and right now the base case is a no-go. it doesn't work. es6-modules have not brought modular modules to the web. it has failed to do it's most important goal.

can people with no tools, with no type-script, are they capable of using modules? if they require a bunch of tools to do so, i feel like the answer is that the web does not have modules. systems like import-maps begin to give consumers of libraries ways to assemble dependencies in a way that they can take off the shelf modules & plug them together on the web. until we see something like this, some way of sharing modules, the web platform does may have the language feature, but it has none of the benefits of modules that software-developers require to build systems atop even-mildly complex module graphs.


> can people with no tools, with no type-script, are they capable of using modules?

With a "modern framework"? Probably not. At least not with current documentation.

With everyone's classic "framework" Vanilla JS? Yes, absolutely. There's nothing stopping anyone. It's rather easy, and I've done it for small projects at this point.

There's one subtle change to the SCRIPT tag (type="module"), and new syntax to learn (if you haven't already learned it from Typescript or Babel), but that's it.

Sharing modules "just works" if you use what has always worked in SCRIPT tags: URLs. You don't need "import-maps" if you have URLs you trust (and "cool URLs don't change"), and Deno is exploring that as well as the way forward for "server side" applications as well that you can build complex dependency graphs solely on top of URLs.

Sure, "modern frameworks" are built on top of a house of cards of CommonJS (and sometimes still ancient AMD/UMD/weirder) dependencies, Node-style "bare" imports (imports by package name only, imports without file extensions, etc), npm package.json configuration and file meta (contributing to Node-style bare import complexity), and other issues. It would be a amazing if we could just rip the legacy code band-aid off and presto every "modern framework" would be ES2015 module native and just an `import framework from 'https://myawesome.framework.example/myawesome.js'` away. Deno has even pointed out that we can automate more of that (than we currently do) and move the "bunch of tools" to the the servers that serve the URLs, there could be a service out there for `import { React, Vue, etc } from 'https://oldworldnodetomodernmodules.example/modern-framework...'` doing all the hard "tool" work and bringing "people with no tools" to the same table, if that were something we cared about doing. (Just as web hosts like unpkg have helped a lot of SCRIPT tag only people able to use npm dependencies for years now.) (ETA: But again, that's useful for old code with legacy dependencies; new code could be entirely written with URLs as the "package manager" no sweat. URLs are just as capable of most of the complexity we put up with from npm.)


> The goal keeps moving though.

I think the goal posts have stayed the same:

1) Module support in browsers. (Now ~92% per caniuse.)

2) Optional: Wide support for HTTP/2 in browsers. (Now ~95% per caniuse.)

3) Optional: Wide support for HTTP/2 in servers. I don't have good statistics on this one, but things feel "close" to ready.

(2) and (3) are desirous for performance, and we've known that all along as modules balloon the number of HTTP requests.

Maybe you also want to count super option (4) "smart HTTP ES module push preloading", but that seems unnecessary gilding to me.

> If I need to process TypeScript files into JS to load them in the browser, why stop at modules and not just go ahead and link and tree shake and all that too?

If you are outputting modules you shouldn't have to "link"; admittedly performance is still a concern, but that's what HTTP/2 (and/or HTTP/3) are supposed to help with.

If you are outputting modules rather than "linking"/"packing" you shouldn't have much to tree-shake and the browser will naturally tree shake in terms of simply not requesting modules outside of the execution path.

Just because you have a build step doesn't mean you have to "build all the things", and it shouldn't be a surprise and should be obvious that a type-checking-and-stripping only run of Typescript is faster than a Typescript+Webpack+Rollup+Terser or whatever stack.

> Maybe things will settle down and browsers will actually run the code that web developers are writing, but the way things are going I don’t see that ever happening.

That's an orthogonal issue, though. Does it matter that the browser is running code "exactly as authored"? Even then, Typescript outputting ES2015+ modules is more often than not just stripping types. The distance between ES2015+ and Typescript today is often minuscule. Typescript has been pretty focused on sticking to TC39 Stage 3 so even features that aren't currently supported by browsers are most often tomorrow's features (not "next decade's features").

Plus, Typescript even gives you the option today of moving all your type checks to JSDoc comments and running as a type-checker only and you can feed the JS directly to browser as is, if that really is a concern that you think the browser should be using the same files that you are writing. (But again, does that really matter? And also, that isn't stopping you from using ES2015+ modules today. It doesn't matter if you are using a Typescript build step or not.)


this deserves a good write up, because it's complicated.

it's not that hard to write a es6-module. it's pretty easy, and you can ask for it, and it'll work, behave like a ecmascript module in an ok way.

but. but if that module has other modules that it wants to pull in, the author of that module has to hardcode a bunch of assumptions about how & where that module that it depends on is. the module, in short, is not modular, because there's no way for users of that module to help it find the modules it depends on.

the best example of a work-around for this absolutely tragically-impotent pretty-much-useless es6-module system is dynamic rewrite engines like unpkg.com javascript cdn, which, on their home page mentions the ?module query parameter you can ask for. this will dynamically resolve & re-write all the dependencies of a module, to point to other unpkg.com modules. let me re-iterate: it has to re-write each module you ask for in a way where all of that module's depenencies are now also resolved unpkg modules, who themselves will also be rewritten such that their dependencies are also solved, & so on & so on, until the whole tree of modules is all rewritten to use unpkg modules. each module has to be rewritten such that there's now some kind of way to import dependencies. es6-modules provides no means to do that. each module has to resolve it's dependencies fully, ahead of time. so modules here are not actually modular: each host is left to copy, resolve, & modify the original module & make it their copy of the module, resolving dependencies however the consumer can figure out.

this is completely hosed & absolutely unbearable. modules are not modular. es6-modules are ok syntax, are ok language, but they are categorically useless on the web. it's truly tragic; es6-modules stopped while being only 33% of the way done. for what it's worth, import-maps is the only work anyone has suggested to resume progress & let modules work in any kind of inter-operable manner, & i have heard no good protest against it: i sincerely wish it would advance much much faster & be released so we can stop being stuck with terrible, unusable, non-modular modules on the web.


Hey, nice article on Declarative Shadow DOM today (that's what i meant but said wrong, on Declarative Custom Elements),

https://web.dev/declarative-shadow-dom/

To an improving enhancing JS & Web!!! Hopefully we get HTML Modules too, & together we can make far far far far more WebComponents in the DOM, & need much less JS!




Applications are open for YC Winter 2022

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

Search: