Readit News logoReadit News
djrenren · 2 years ago
I've found webcomponents to be really good at encapsulating anything that doesn't directly query application state.

Specifically there are two type of components that really thrive as web components (as opposed to react):

1. Highly interactive components - Components that implement complex interaction management (but sort of agnostic to application state) are ideal web components. You don't need to mess around with `useEffect` or `useMemo`. You get really tight control of rendering and state updates.

2. Highly internally stateful components - Components that track a lot of state that doesn't escape the component, work great as web component. You get strong encapsulation without a framework requirement.

React conflates two concepts that I think are better when separated: templates, and components. Templates provide a "re-render the world" approach, and components encapsulate state and interaction patterns. Conflating these two things causes the standard useEffect and useMemo headaches. It also means that any consumer of your component, must also use your templating system (react's render function).

The `lit` library does this separation extremely well, allowing you to implement components using templates if you want, or not. And consumers do not care how the internals are implemented.

paulddraper · 2 years ago
> React conflates two concepts that I think are better when separated: templates, and components.

Whether a React code base conflates them depends on the code base, but the more familiar terminology is container vs presentation. [1]

[1] https://www.patterns.dev/react/presentational-container-patt...

djrenren · 2 years ago
You can absolutely follow a discipline like this which recreates this separation in a framework that lacks it
willio58 · 2 years ago
I completely agree. Recently I listened to a podcast where Brad Frost talked about web components being useful for design systems, as you can make a button in a web component and have that defined no matter what JS framework the dev team (or teams) want to use company-wide.

One issue I see though and I almost feel dumb for saying it, I don't like how web component code looks. Using innerHTML feels really weird when your team is so used to using JSX for react components for example. I don't think this would stop me from researching web components more but does anyone feel similarly or have a solution or obvious answer for me in this area?

zaphar · 2 years ago
You don't have to use innerHtml. The ShadowRoot pretty much acts like a document. So you can also use appendChild. Combined with a template element you can completely avoid innheHtml. You could even use jsx to create the template element I suppose.

That said I think this is mostly a non-issue.

itronitron · 2 years ago
For me, it feels weird to have four file types I need to manage in order to define a UI, instead of just one.
nbe · 2 years ago
lit [1] provides declarative templates for web components for example.

[1] https://lit.dev/

troupo · 2 years ago
> You don't need to mess around with `useEffect` or `useMemo`. You get really tight control of rendering and state updates.

You don't need those in React either. Whatever you do in Web Components can probably (most likely) be done in React.

After all, Web Components are a solidified 2010-era design. The reason React has hooks now because people have moved on, and are exploring other ways of building stuff. The only mistake React did was to keep reactivity on component level (hence all the hooks and their weird rules) when most people moved on to more granular reactivity. Hell, even Angular did.

djrenren · 2 years ago
> You don't need those in React either.

I mean... sometimes you do, that's why they exist. But yeah, most of the time you don't.

> Whatever you do in Web Components can probably (most likely) be done in React.

Of course! React is a good and powerful framework. But everything you do in React can be done in Angular 1.0 or even backbone.js. As always with frameworks it's about the productivity / performance ratio for your team (or for libraries, the ratio for your consumers).

> After all, Web Components are a solidified 2010-era design.

A lot of the web components related APIs are being actively developed including constructable stylesheets, shadow DOM APIs and more. Regardless, the era of design is not a great point in either the "pro" or "con" column, and is usually an ambiguous shorthand for the actual quality being critiqued.

djrenren · 2 years ago
Forgot to mention, the knock-on effect of this thought process is that if you want to adopt web components, you still need a templating approach. And you'll find that most of your code is templates, and only a few are really components.
jongjong · 2 years ago
I find that they can work very well with state but since state is typically passed via attributes (downstream), it means that components can only share state with each other via strings. I found this to be an advantage, not a drawback because simple interfaces are at the core of my coding philosophy and strings make it infeasible to pass complex instances or functions to other components.
djrenren · 2 years ago
Well, this is only sort of true. When you’re writing HTML you’re restricted to attributes but custom elements are JavaScript objects and are free to respond to property updates on the object. Relying solely on strings is a limitation of your templating engine.

For example lit-html templates support syntax like:

<my-element .someProp=${new Foo()}></my-element>

dbingham · 2 years ago
One of the linked articles [1] makes an interesting claim that feels like a reach to me, but I'd be interested in hearing HN's take on it:

> At this point React is legacy technology, like Angular. Lots of people are still using it, but nobody can quite remember why. The decision-makers in organisations who chose to build everything with React have long since left. People starting new projects who still decide to build on React are doing it largely out of habit.

I'm going to withhold my own thoughts about that quote, cause I'm curious what everyone else thinks.

Wrt. Web Components, I played around with Web Components about half a decade ago and they felt promising but not ready for prime time yet. They were pretty messy and felt like they did a poor job of encapsulation. (At least at the time.) I haven't looked at them recently, but the code examples in these articles look much better (and cleaner) than what I remember.

[1] https://adactio.com/journal/20618

menssen · 2 years ago
"Lots of people are still using it, but nobody can quite remember why."

I can remember why. This, and every other article I've ever read arguing to replace React with Web Components, completely misunderstands the point of React. It isn't about JSX. It isn't about encapsulation. It isn't about reusability.

It is about enabling a design pattern where *the user interface is a pure functional transformation of the application state.*

I kind of feel like people get tripped up by the fact that "virtual DOM" and "shadow DOM" sort of sound similar. They have literally nothing to do with each other. The React "virtual DOM" allows you to *completely re-output the entire user interface* on every state change, which is not possible with any other design pattern, and is not possible without a framework, because actually re-rendering the entire tree on every state change isn't performative (or usable).

Anybody who is advocating an alternative to React needs to do one of two things:

(A) Make a convincing argument that a different design pattern is better. Some things we've tried, which most people think are worse:

1. Using the DOM as your data model (jQuery)

2. Manually writing virtual representations of every view (Backbone)

3. Auto-magically two-way binding some data structure with the DOM (Angular 1)

4. Observables (Ember, maybe Angular 2+?)

(B) Advocate a framework other than React that uses the same pattern as React, but improves the usability. I think the two places there is the most room for improvements are:

1. Animations

2. useEffect() in general

I have not seen anybody successfully do either A or B.

Recommended reading: https://acko.net/blog/get-in-zoomer-we-re-saving-react/

WorldMaker · 2 years ago
> 4. Observables (Ember, maybe Angular 2+?)

Don't forget Knockout which was the OG. You can also make the case that Svelte, Vue, and Qwik all are different takes on Observables (at least as much as Angular 2+ is) all with more or less magic and more or fewer escape hatches from Observable best practices to imperative(-looking) code.

I got a "What if we did Knockout but with with the compile-time benefits of TSX and Pure RxJS Observables?" itch a couple months back and have made some wild progress on it. I certainly don't think it is ready yet to advocate as an alternative to React, but it's probably in an interesting A4+B2 tangent on your map right here, and I find that interesting.

breadwinner · 2 years ago
> It is about enabling a design pattern where the user interface is a pure functional transformation of the application state.

This is only true for read-only components.

There is no "pure functional" when you introduce state and interactivity. See here: https://mckoder.medium.com/why-react-is-not-functional-b1ed1...

tshaddox · 2 years ago
I too remember building interactive web sites with jQuery. It was never fun creating, for instance, an interactive list view where each item can be modified in client state and new items can be added. This was the problem for which React provided a major "Aha!" moment.
techpression · 2 years ago
I would say SolidJS does everything better than React while keeping with the same general mindset. React spent way too much time worrying about DX to the point that now DX is really bad. Fine grained granularity is such a breath of fresh air to work with after the very large and very heavy brush that is the React “render the world every time anything changes” method (yes they try to be smart about it, but so far haven’t succeeded, the next compiler might solve it, but then we’re back to a black box of incomprehensible code soup to debug).
MrPatan · 2 years ago
Preach. Angular 2+, btw, can (and should) be used the same way. V=f(S) is the only sane way to live.

Just don't change application state from a component lifecycle function and you're golden.

pcthrowaway · 2 years ago
> (B) Advocate a framework other than React that uses the same pattern as React, but improves the usability. I think the two places there is the most room for improvements are:

> 1. Animations

> 2. useEffect() in general

I'm not normally one to "shill" a web framework, and I still mainly use (and love) React, but I'm curious if you've tried Svelte, because it definitely manages animations better than React, and has a different idea of state that's more ergonomic for many use cases (though I won't go so far as to say it's definitively "better" than useEffect)

wayfinder · 2 years ago
I have to disagree.

It can't be that that design pattern because React did not invent it. Every server-side templating library is a pure functional transformation of application state. I can tell you that many people also ported that design pattern to JS.

What tripped library writers up is once they applied that pattern to JS, there is no way to actually define the transformation because to do that, you either write a template or the code-equivalent (i.e. using DOM as your data model). And that's where JSX came in.

Also, I think you have patterns completely confused.

Backbone is NOT in the same class as jQuery or React. Backbone is more like Redux, mobx, or React hooks because it's a data model library. In Backbone, you define "models" and "collections" -- basically, you use Backbone to store your application data in memory.

Backbone did have a views component to it but it actually could not generate any HTML. Look at this example from their docs:

  var Bookmark = Backbone.View.extend({
    template: _.template(...),
    render: function() {
      this.$el.html(this.template(this.model.attributes));
      return this;
    }
  });
It literally has jQuery and underscore.js! Backbone had no templating/HTML generation ability so when you used Backbone, you combined the fat Backbone classes with whatever horrific HTML-generation method you used to create a huge monster.

You can actually use Backbone.js with React since they are not in the same class. You would not, of course, because mobx is basically the same style of data modeling as Backbone.js but with almost no boilerplate.

gitaarik · 2 years ago
The reason React uses a virtual DOM is because when React started, there were no (advanced) HTML templates yet. And it made it easy to setup listeners on elements, instead of manually adding it with `addEventListener()` and possibly remove them again with `removeEventListener()`. So the virtual DOM was really a game changer.

But Lit templates solve these problems in a more browser integrated way, without the need of a virtual DOM. How you manage the state is free to your choice, that is also not something exclusive to React and your favorite pattern can also be used with Lit. I wrote a tiny state management library (LitState [0]) which makes it very easy for multiple components to share the same state and stay in sync. I personally find it much more convenient and cleaner than any other state library I've used before. And it integrates very nicely with Lit.

[0]: https://github.com/gitaarik/lit-state

TheHiddenSun · 2 years ago
Solid.js comes to mind

- not a framework, but a library

- can do fine gained state updates without unnecessary re-renderings (reactivity)

- uses dom instead of vdom to produce best in class SPA performance

- uses jsx like react

Performance claim / proof: https://krausest.github.io/js-framework-benchmark/

QuadmasterXLII · 2 years ago
With modern browsers, "completely re-output the entire user interface on every state change" is kinda viable. I recently wrote a trebuchet simulator app (hastingsgreer.github.io/jstreb) without a framework. instead I wrote a "rebuild UI" function that I call on every new state, and the user experience is super snappy
Vinnl · 2 years ago
To add to that, one of the (largely justified) criticisms of React is that it, or at least the way it is commonly used, can have negative performance impact, and thus negatively impacts user experience. However, user experience is broader than just performance, and critically also includes that the application has as few bugs as possible and works well in the first place, and I feel that the model you describe greatly helps there, and it makes unit testing and strict static typing feasible to boot.

(Admittedly, these benefits haven't been thoroughly researched, as far as I'm aware, so it still mostly relies on gut feeling and experience.)

breadwinner · 2 years ago
> Make a convincing argument that a different design pattern is better.

Simple Model-View-Controller pattern works well for JavaScript, just as it does for ASP.NET Core, JSP and JSF, Ruby on Rails, Django and so on.

Want proof? Browse this code:

https://github.com/wisercoder/eureka/tree/master/webapp/Clie...

This is the application: https://github.com/wisercoder/eureka

tyingq · 2 years ago
Fair, though you can find plenty of stuff on the internet using React, but where the app/page itself performs abysmally. Meaning maybe there is some merit in approaches that are easier for lesser skilled teams to deliver in.
pests · 2 years ago
useEffect is overused. People use it to compute derived values when that is not its intended use.

How many times have you seen the equivelent to a fullname = firstName + lastName inside a useEffect? Its outstanding. :(

wayfinder · 2 years ago
As someone who does remember why because they've been building sites since the 90s, it's because the React team created a preprocessor (JSX) to let you embed HTML tags in JavaScript. This fixed the problem that other languages like Java, Python, etc. don't have because those languages has assemblies/packages so they can put HTML templates in separate files and load them in your app. There is zero standard way to do that in JS and every custom way you invent looks like trash.

Doing something like this.shadow.innerHTML = `your HTML` with web components is terrible. document.createElement() is terrible. $('div').appendChild() is terrible. <script language="html" name="my-template"><!-- --></script> is terrible. HTML(Div(Strong(text))) is terrible*. Storing templates as JSON and writing a one-off loader is terrible. <div style="display:none">template</div> is terrible. I've done it every possible way and they are all terrible.

JSX fixed all that.

The biggest previous attempt at something like JSX was E4X where you could embed XML straight into JS, which was kinda nice except it added the entirety of XML and its complexity. I creamed when it came out but then I tried it and it was not it. (E4X ended up surviving a little longer in Adobe Flash though.)

E4X: https://en.wikipedia.org/wiki/ECMAScript_for_XML

*This is what JSX compiles to behind the scenes.

zelphirkalt · 2 years ago
Interesting. Yet I find that React HTML—that is not actually HTML, but a look-alike, a dialect if you want—to be exactly what I dislike about React. That is because it still encourages people to put JS in their HTML in their JS in their ... And we are almost back to crazy PHP land of "I treat HTML as a string and blend everything together into one big lump.", instead of using a templating engine, that treats HTML in separate files, or making use of a DSL, that treats HTML as structured data, say for example SXML. Also there are issues with that custom HTML-look-alike preprocessor, because you cannot write class="...", because then somehow it gets syntactically confused, because "class" is now a keyword in JS.

This all feels rather half-baked. Why can't the parser/prprocessor distinguish between that "class" and "class" in JS source code? We can have reusable HTML snippets (some may call components) with normal templating engines easily. Look at something like Jinja2 and how to reuse blocks and macros. Yes, some React component can encapsulate its own interactive behavior. That is only because we are already writing JS though, so we can already write frontend logic. But do we actually want that? Coupling state and behavior? I think we might not. Writing a script that gets served only on those rendered templates, where it is needed is not so hard either, when using a normal templating engine.

vitaflo · 2 years ago
100% agree. Like you I’ve been building sites since the mid 90s and always was pulling my hair out at all the convoluted ways we would attempt to handle HTML in these JS frameworks. As someone who knows HTML and CSS and vanilla JS, as soon as I saw React all I could think of when I saw JSX was “finally!”.

Yeah it’s another framework with its own quirks but it lets me think about the UI in the same way I’ve thought about it for 25 years. For someone like me that’s a godsend.

breadwinner · 2 years ago
What if you could have the best of both worlds? What if you could use JSX templates and use standards-based web components? You can.

Here's an example of using a web component in a JSX template (look for zx-listeditor): https://github.com/wisercoder/uibuilder/blob/master/WebCompo...

Here's how the web component is implemented, also using JSX: https://github.com/wisercoder/uibuilder/blob/master/WebCompo...

marcosdumay · 2 years ago
> <div style="display:none">template</div>

It's new and has no significance for the history. But I think it's relevant to point out that <template id="myhtml"><div></div></template> isn't horrible.

And that those articles about web components are doing a really bad job of using constant strings instead of this.shaddow.innerHTML = getElementById("myhtml").innerHTML.

WorldMaker · 2 years ago
> HTML(Div(Strong(text))) is terrible*

> This is what JSX compiles to behind the scenes.

Oh, it is much worse than that. By classic default it is:

    React.createElement('div', { /* props and attributes ... */ },
      React.createElement('strong', { /* ... */ }, text))
Recent updates and other JSX frameworks simplified the name of `React.createElement` to just `jsx` or `h`. I've seen projects that manually write `h` calls like that everywhere, and it is indeed terrible.

(Source: I've just completed a bunch of crazy TSX work and got pretty familiar with the compiled forms.)

nostrademons · 2 years ago
I liked the templates-as-JSON approach much more than JSX. HTML is terribly verbose, doesn't fit well with the rest of Javascript, doesn't let you use JS language features like destructuring or iteration on the component tree, and doesn't let you factor out common properties into their own data structure. Would much rather see:

    { tag: 'div', padding: '2px', position: 'absolute', content: [myText] }
than

    <div style="padding: 2px; position: 'absolute'">${myText}</div>
The main reason I ended up settling for JSX was just convention: I don't want to be the one with my own unique format for UI trees unless I can convince everybody else to use my format.

Note that Jetpack Compose has a very similar declarative reactive paradigm as React, but represents components with Kotlin language mechanisms. IMHO I like it much better, because it's much more composeable.

tshaddox · 2 years ago
Fascinating that React simultaneously receives criticism as being

1) boring, old technology that has been around for so long that no one even remember why it was chosen in the first place, and

2) extremely fast-churning, bleeding edge software that is constantly changing and breaking because the JS community is more interested in chasing trends than building robust stuff.

pwdisswordfishc · 2 years ago
React has merely aged, not matured.
paulddraper · 2 years ago
Same people who say:

1) the ecosystem keeps chasing shiny tech that is constantly changing, not boring solutions

2) everything should be written in Rust

robin_reala · 2 years ago
React “won” because Facebook spent three years flying devrel to every web conference on earth to persuade other people that Facebook’s problem space was applicable to small agencies.

Back in reality, React is slow and massively overbuilt for the majority of stuff that most people are building.

If you played around with Web Components a long time ago then you probably played with the v0 spec, which was somewhat different to the current version.

troupo · 2 years ago
> React “won” because Facebook spent three years flying devrel to every web conference

You do know that Google sponsored and ran things like Polymer conf? That it builds lit? That Google's devs have literally overrun and overruled most web specs committees? That Google has spend hundreds of millions of dollars promoting Web Components?

And yet here we are.

JamesSwift · 2 years ago
React "won" I think because it trojan horsed itself as being "just the view" but then morphed into a hand-rolled kitchen-sink solution, and inertia kept people around.
paulddraper · 2 years ago
!!!

If React won, it was precisely because it was not "overbuilt."

It was simpler (deliberately) than Backbone, Angular, Vue, Svelte, etc.

You can implement a React clone in a few hundred lines, a la Preact.

djrenren · 2 years ago
As someone who just had to answer this for my startup, the value of React is that it's robust and immensely hire-able. If you're looking for frontend developers, the one thing you can always expect is at least passable React knowledge.

Everything else, even if it has a better technical fit for your project, is likely riskier for your organization.

pseudosavant · 2 years ago
Some of the most productive teams I've worked with (not as a dev) have been for tech stacks I personally don't enjoy using. Java, .NET/C#, React, etc. In practice, I'd rather quickly hire a local senior Java/C# dev for 1X than scour the interwebs to hire a Golang dev that requires relocation for 1.5-2X.

If I was going to learn a language though, I'd probably learn Golang. Their rate is so much higher.

Draiken · 2 years ago
I find this argument so absurd. If you know JavaScript and basic programming, you can use any front-end framework.

We're hyper-specializing people in a specific framework that then don't even understand the basics of JavaScript itself.

I already find the divide between frontend and backend developers unnecessary the majority of the time. This takes it a step further and in turn creates monstrosities like the leftpad debacle.

Can we stop with this nonsense? Hire good developers and let them spend 5 minutes to learn the god damn framework of the week. If your hire can't learn React in a week, I have some bad news for you.

mattlondon · 2 years ago
Would anyone pick react these days, if they did not already use it/know it/think-it-is-what-they-should-use-because-everyone-else-does?

I think that is the point. The original "pitch" for react in my mind was that it was lightweight and simple. I don't think you can say that any more, and I think a lot of rough edges have been identified (e.g. hooks fiasco, app state management, dependency-hell etc to name just 3) after years of use.

It's the same cycle that always happens. Old thing ossifies and grows fat overtime trying to be all things to all people. Then some new thing appears that starts with a clean slate and no prior expectations that proves popular as a result

JacobThreeThree · 2 years ago
It's as you describe, but also the spec and browser support landscape has changed.
davedx · 2 years ago
React isn't legacy technology. What a perfidious statement.

I can easily justify the reasons I still use React, but I can't be bothered writing it out every time some gimmicky front-end tech hits HN.

sesm · 2 years ago
Every alternative to React roughly fall into one of 3 categories:

1. Go back to reactive templates.

2. Sprinkle directives over plain HTML a-la early Angular 1.

3. HTML over the wire.

All those ideas pre-date React and React won against them back in 2014.

mustaflex · 2 years ago
Web components are a bit verbose by themselves but used with a library like lit.js you can build a framework agnostic component library. Angular and Vue support WC out of the box and they have a wrapper for React. I think the only thing missing(or not mature enough right) now is SSR. There are probably libraries other than lit.js that take the pain out of writing WC.

I was skeptical at first but I've seen in production a lit.js/WC component library used with React and Angular successfully in the banking sector and it works surprisingly well.

gustavus · 2 years ago
It sounds like the common thing that someone in the Frontend space would say, that a technology less than 5 years old says the technology is old.

I prefer the terms stable, mature, or hardened.

People use React/Angular because large products are forced to have a way to organize things across multiple developers and time. Now don't get me wrong I think these JS bloated websites are an abomination that have largely made the web worse and not better, especially since UX "engineers" feel a compulsive need to change the layout every 6 months and now even simply scrolling through a page involves 50 web requests, and takes a full 3 minutes to load the next page... but I digress.

austin-cheney · 2 years ago
As a full time JavaScript developer of 15 years it boils down to 2 reasons.

1. Eases candidate selection. There is no uniform baseline of competence in software generally and certainly nothing exists for web development. Its often the blind leading the blind, so outsource everything to a tool. At the very least, people that cannot use that tool are then not qualified to be there if you discount absolutely everything else. After all, it isn't as though employers are willing to train new developers to perform as required, so they need to turn this into a commodity as much as possible.

2. Composition. Most of the people who do web development cannot write original software, plan, or organize at the level required by modern applications. Employers still need people to do trivial things to get text to appear on screen. As the demand for these trivial tasks still exists employers still need to hire people to do this work, and so they attempt to outsource the parts that require higher intelligence.

These beg the obvious question: What will happen when employers realize they don't need to overpay developers to do this work when half of it can be pushed into content management systems and the other half can be pushed into AI?

meiraleal · 2 years ago
Yes, I agree with him. What's the reason to use React? It is over-engineered and too complicated for no clear benefit. It takes longer to build an app using react just because you have to deal with things that are exclusive to react
octagon2023 · 2 years ago
Try next.js. We have seen massive improvements in code quality and development velocity using v13/14. Our codebase is a mix of typical server rendered crud web and client only logic (web3). It feels like php without the bad parts. In particular react actions proved to be a major quality of life improvement.
troupo · 2 years ago
> They were pretty messy and felt like they did a poor job of encapsulation, ultimately. (At least at the time.)

They are still messy. https://w3c.github.io/webcomponents-cg/2022.html

Deleted Comment

earthboundkid · 2 years ago
No, they just lock you into one framework per component. I don't know why people say obviously false stuff like this about web components besides they just really, really want it to be true. Yeah, if you're willing to have the same framework on the page ten times, you can just chuck them all in separate script tags using the custom element API. But if you care about making a performant page with progressive enhancement, etc. this is a bad strategy.

Even the name "web components" is basically just marketing fluff. When people say "web component", they mean using two particular DOM APIs: customElement and shadow DOM. Those are both pretty niche APIs. There are some cases where they are helpful, but 99% of the time, they don't add much to a project versus good old querySelectorAll and normal CSS.

jakelazaroff · 2 years ago
Author here — I'm not sure what you mean by "lock you into one framework per component". The point is that you can encapsulate framework code within web components, not that every component you write should be a web component.

Let's say you're writing a Vue app and you really want to use a library that's only available as a React component. You can wrap that library in a web component and use it in your Vue app just like you would any other HTML element. The rest of your app can continue being Vue, using normal Vue components.

mmis1000 · 2 years ago
The biggest problem of web component is that it don't support most state injection(for things that rely on contexts, for example: tabs) and template instantiation(render function of react or scoped slot in vue for example), which literally every current popular web framework does. You may pass string or number as string to it. But anything more complicate that can't be easily serialized? Good luck.

You may add another layer of abstraction on the top of it. But that only make you another framework (like polymer) instead of actually using web components.

In other word. Web component is useful to encapsulate an 'app' (for example: a interactive map viewer that accept an address) inside another app. But is mostly useless to encapsulate anything other than a simple ui/input component. There is basically 0 functionality to inter-blend between parent and child components of different frameworks.

jdmg94 · 2 years ago
except you can't use it as a normal component, you can't adjust its CSS normally, you have to `&::part()` your way around and hope for the best. Accessing through refs is a complete blackbox. I work with web components daily and it is a hindrance to my daily work, it is very common for people at my org to just re-write a component instead of using its web component version.
Devasta · 2 years ago
That sounds awful to be honest. A recipe for total loss of standardization within an org.
oblak · 2 years ago
I've been fought by people insisting that if we're using a framework, we should be using it for everything, if it has it, even when both agree that doing it natively is actually less cumbersome. All that in the name of consistency. I think middle ground is a good solution.

On topic: I don't think WebComponents are going to "make it" until someone builds a nice framework on top of them. React, Vue, Svelte, etc. solve a number of problems that are not directly solved by Web Components. State management, rendering, routing - right now, these are, imho, the high level areas that need solid solutions for an UI app to function in any sane way. How much of that is solved by going Web Components?

spankalee · 2 years ago
I work on Lit, which I would hesitate to call a framework, but gives a framework-like DX for building web components, while trying to keep opinions to a minimum and lock-in as low as possible.

It's got reactivity, declarative templates, great performance, SSR, TypeScript support, native CSS encapsulation, context, tasks, and more.

It's used to build Material Design, settings and devtools UIs for Chrome, some UI for Firefox, Reddit, Photoshop Web...

https://lit.dev if you're interested.

troupo · 2 years ago
> lock-in as low as possible.

As in:

- reactivity. Specific to lit

- declarative templates. Specific to lit

- SSR. Specific to lit.

- context. Specific to lit.

- tasks. Specific to lit

"minimal" and "low lock-in".

Please do not hesitate to call it a framework. If you call React a framework, then lit is definitely a framework.

veeti · 2 years ago
How do we know this won't be killed off by Google in six months?
earthboundkid · 2 years ago
"Web Components" are the name for a dream, not an actual technology. The actual technologies involved -- customElement and shadow DOM -- are pretty crappy to use directly, and even when hidden behind a framework/library don't buy you that much. But people want it to be true that there is such a thing as a "Web Component" so the dream lives on.
gitaarik · 2 years ago
Why do you think this? I've been using it for years and it works lovely, no complaints at all.
o11c · 2 years ago
> I've been fought by people insisting that if we're using a framework, we should be using it for everything,

Remember the definition of a framework: a framework is just a library that does not play well with others.

jdmg94 · 2 years ago
Stencil does it, but the resulting web components are still not great to work with because of shadow dom and the missing standards you can't expect from custom elements. You want inline styles? hope your dev remember to drill those down.
DarkNova6 · 2 years ago
A foolish consistency is the hobgoblin of the little mind
toasted-subs · 2 years ago
Svelte compiles into WebComponents.
beebeepka · 2 years ago
That's good to know. I really liked what I saw last time I played with it but it's hard to find many job listings where people are using svelte. Almost everything is react and surprisingly, at from what I can tell, it's getting even bigger share in job postings I used to see. Hooray for uniformity, I guess.
steve_taylor · 2 years ago
That’s news to me and probably everyone who uses Svelte including its developers.
tannhaeuser · 2 years ago
In case anyone was wondering, JavaScript per se isn't replaced at all. All mentioned examples still use event listeners, querySelectorAll, ES modules, and what not. Most importantly, you need to subclass HTMLElement and register your custom element using JavaScript in the first place eg:

    class MyElement
      extends HTMLElement {
    }
    
    window.customElements
      .register('my-element', 
        MyElement)
(the hyphen in the name is idiosyncratically required by the custom element spec).

As such, "HTML web components" (aka custom elements, which have be around for many years) are targeted at developers not hypothetical web users/authors. Then what is the point? When you're relying on JavaScript anyway, you have already much greater freedoms - syntactically and otherwise.

Custom element declarations and custom vocabularies can make sense as a means to organize and isolate authoring concerns when you're creating hypertext documents. The fact alone that you have to use JavaScript for registering custom elements make them a non-starter though (ie consider an authoring tool which surely doesn't want to execute arbitrary JavaScript in client docs).

It's not that there's no precedent either. SGML has a mechanism for parametric macro expansion where your element is syntactically replaced into an arbitrary markup fragment, with type-checked arguments (= attributes at the call site, just as with custom elements), and with type-checking the resultant expansion in context (ie. checking whether the expansion adheres to the content model at the expansion site), also having of course the capability to include JavaScript. Moreover, SGML actually can serialize/re-parse such markup whereas HTML's preliminary APIs for fragment parsing won't deal with contextual tag inference at all.

runarberg · 2 years ago
For me, being able to offer my library as a web component is kind of neat. Sure I can ask users of my library to import it then query select math inputs, then apply my library on these, and remember to apply it also on DOM change.

    <script type="module">
      import lib from "/path/to/my/lib.js";
      for (const target of document.querySelectorAll(".target")) {
        lib(target);
      }
      // TODO: Watch for DOM change and apply lib.
    <script>

    <span class="target">Some Input</span>
Or I can simply ask them to import my web component module and use the custom element:

    <script src="/path/to/my/web-component.js"></script>

    <my-lib>Some input</my-lib>
The latter certainly feels like a superior API for my users.

svieira · 2 years ago
Or you can do a little more work in your lib for your users and offer:

   <script type="module">
     import lib from "the-lib.co.uk";
     lib({ target: ".target" });
    </script>
If your users might not want you to watch the _whole_ DOM for performance reasons:

   <script type="module">
     import lib from "the-lib.co.uk";
     lib({
        target: ".target",
        root: ".all-the-targets-show-up-here"
      });
    </script>
And if your users might already have a mutation observer in their apps:

    <script type="module">
     import lib from "the-lib.co.uk";
     lib({
        target: ".target",
        observer: theAppObserver
      });
    </script>

itslennysfault · 2 years ago
I like the idea of web components, but really dislike html and js being intermingled (the reason I don't like React/JSX). In web components its even worse because its HTML as a string which means it has no validation and isn't syntax aware. I much prefer the angular approach where you have separate css,html,ts files, and would love a web component framework that could work similarly.

Searching for this I found some kinda hacky solutions on Stack Overflow which use fetch to load html/css at runtime.

djrenren · 2 years ago
Web Components are really just the minimal APIs required to allow the implementation of new HTML elements. This includes things like:

- Responding to being attached to the DOM

- Encapsulating DOM nodes (the Shadow DOM)

- Scoped styling (Shadow DOM + User defined stylesheets + CSS parts)

It is definitively not a templating engine. It doesn't provide any new APIs for creating DOM nodes, or mutating them a la React or handlebars or lit-html. Templating is basically the "next step up the stack". Using shadowDom.innerHTML = `...`; is basically a stand-in for having an actual templating engine.

There is work going on, developing a native templating system in the browser which may interest you. It's called the DOM Parts proposal and you can find info on it here: https://github.com/WICG/webcomponents/blob/gh-pages/proposal...

jacobsimon · 2 years ago
I like React but I actually agree with you re: JSX, it helps me to remember that JSX is 'just javascript' - it's a syntactical shorthand for creating a component tree, which then happens to be rendered into HTML.
claytongulick · 2 years ago
If you use a good rendering library, like lit-html then (at least in vscode) you get very nice syntax highlighting, completion and validation:

    html`
    <this is all syntax highlighted>
    `

itslennysfault · 2 years ago
I was actually just looking at that after posting this (lit is new to me). That's a pretty cool solution. I'd still prefer an option to have the html in its own file, but that is just my taste. I know a lot of people feel exactly the opposite.
yohannparis · 2 years ago
You can use `<template>` for that purpose and keep your separation of concerns okay.
MrDresden · 2 years ago
As a non web dev I had to look this up and yeah, this looks like a very sane and clean way to separate concerns and get proper handling from IDEs:

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

gitaarik · 2 years ago
Indeed, the Web Components APIs don't demand that you put the HTML and JS together. You can use it and structure it to your own likes.
acheong08 · 2 years ago
Rather than putting the HTML in JS, you can fetch HTML in the JS.

E.g. https://github.com/g-utils/WebComponentFactory

fuzzy2 · 2 years ago
Then… use Angular Elements?

Using innerHTML isn’t specific to Web Components in any way. It was and is a quick & dirty way to dynamically insert HTML.

paulddraper · 2 years ago
> its HTML as a string

Can you explain what you mean by that?

itslennysfault · 2 years ago
This is the example from the article, and pretty common practice for web components. As far as an IDE is concerned this is just a string of text (it doesn't know/care that it is html). This makes it more error prone as the IDE can't catch syntax errors in the html.

  connectedCallback() {
    this.shadow.innerHTML = `
      <p>Hello from a web component!</p>
      <style>
        p {
          color: pink;
          font-weight: bold;
          padding: 1rem;
          border: 4px solid pink;
        }
      </style>
    `;
  }

thfuran · 2 years ago
Html as a string literal in code rather than the html being in a separate .html file.
IshKebab · 2 years ago
React uses JSX/TSX which is much better because it is syntax checked and even type checked in the case of TSX.
preommr · 2 years ago
Web components are a half-baked solution. It only becomes useful with another framework (even if it's very lightweight) like lit. At which point I might as well use vue/react/svelte since I am already brining in a library. Tech like preact is really lightweight as well, and given the popularity of react, is enough to offset any benefits web components have.

I would really like it if we reached a point where a web project only had a single dependency that's a bundler like vite that you point to an index file, and that's it.

OJFord · 2 years ago
I think we're going in the opposite direction though - everyone wants to hide what's going on and use some magic CLI that just takes care of everything for you, don't worry about how or when or what to do if it goes wrong, just run `flyctl deploy`, `wrangler publish` (Cloudflare), `npx wizzle wazzle` :sparkles: :tada: never `git commit -m '(chore): [...]'` again!

Oh and here's a readme example of how to set that up if you're using pnpm v42 with sveltekit v2 and webpack v99. For any other combination of the 5 packagers, 19 bundlers, and 56 frameworks commonly in use and giving examples like this recommending each other - have fun.

reidjs · 2 years ago
I use them for a basic website (no build step) for things like navigation components and page templates. They are great for that, but not much else in my experience. Once you have a complex UI or multiple devs on a project it’s probably better to just use a full framework
codegeek · 2 years ago
"half-baked solution"

Can you elaborate further ? Anything that removes dependencies from external libraries is a huge plus for me so I am curious as someone who is not great at JS.

troupo · 2 years ago
> Can you elaborate further ?

As you read the following, keep in mind that at this time Web Components have been in development for almost 12 years.

The core is just three standards, CustomElements, Shadow DOM and HTML Imports (already deprecated and removed in favor of JS-only imports). And people will go out of hteir way to sell you the idea that this is lightweight, all that you need etc.

However.

They've already spawned half a dozen new web standards just to deal with issues they inflicted on themselves. None of these issues are present in any other solution/lib/framework that exists.

These range from the fact that web components cannot participate in forms (fixed with a new spec: https://web.dev/articles/more-capable-form-controls) to their inability to share stylesheets (fixed with a new spec: https://web.dev/articles/constructable-stylesheets) to whatever else (hard to keep track).

They will need at least 20 more new web standards to fix other issues that, once again, are not a problem for literally every other framework, library, or hand-written code under the sun: https://w3c.github.io/webcomponents-cg/2022.html.

Among my favorite ones: a web component button cannot be a submit button in a form; you cannot reference an id inside a shadow root, and that breaks ARIA.

To call them half-baked is an understatement. They are badly thought-out, badly implemented APIs with no forethought or visible planning, and literally no end goal in sight. The people building this met to hash out what more is needed for them to be complete only last year, 11 years into development. All development before that looked like ad-hoc patches by people surprised that a yet another thing doesn't work, but is sorely needed.

tauchunfall · 2 years ago
I recently rebuild some parts of a large APM (application performance monitoring) solution to find out how much JavaScript is needed to have similar functionality (minus the backend, of course), e.g. faceted search.

It's interesting how much of a component system one can build only by using `<input>`, `<label>`, and `<form>`. For the remaining interactive elements that can't be build easily without JavaScript I plan to use Web Components.

For me this is a reasonable 80-percent solution. But for web applications with high requirements I would use React and React-Aria components/hooks.