Hacker News new | past | comments | ask | show | jobs | submit login

Web Components have got to be the single most overrated web feature I've ever witnessed in the many years I've been messing around with browsers. You know, even WITH React and no Web Components, there was already a pretty reliable way to integrate third party libraries into React without a ton of glue: the DOM. Like for example, if you want to integrate a text editor like Monaco or Quill, basically all you have to do is give it a DOM node and tie together whatever props/events/bindings you want. You don't really need monaco-react, which is not even a large library to begin with.

The main reason why React is still popular is, drum roll please... The programming model. JSX is not an antiquated idea, it is still one of the better ways to integrate the UI part of a JS application into the JS part directly. I greatly prefer JS logic inside of my HTML versus a bespoke template language specifically because it's easy to compose and construct complex logic in.

I've been messing around with Svelte a bit in spare time. I really like Svelte and will probably continue to use it, but the two things I will note is:

- The integration with Web Components is imperfect and doesn't really hit me as something I would seek out.

- The templating logic in the HTML feels decidedly inferior versus just being able to use JS logic and JSX. Try doing a for loop where you count up; the best answer I could find on the internet was to construct an Array using `Array(number)` and enumerate over it...

What I really want is actually more like React's programming model with Svelte's "compiling down to nothing" mantra.

But this Web Components fervor, I know people get very heated about it, but I strongly believe that in 10 years it's going to be one of those grotesquely complex legacy features nobody can get rid of.




SolidJS sounds exactly like what you want https://www.solidjs.com/


That looks great. It doesn't mention compiling down to nothing, but it definitely offers the programming model of React Hooks without needing a virtual DOM, which is already a good innovation, and probably something I'd like more than Svelte.


I find Solid's model pretty damn close to "compiling down to nothing". I chose Solid for my project because I wanted to support plugins that used other UI frameworks. I recently got a Svelte plugin working with the SolidJS router. I could probably make it prettier... but it's literally a call to Solid's `createComponent` with the Router and an anchoring div to which the Svelte component is mounted. Ezpz.

https://github.com/AlexErrant/Pentive/blob/main/example-plug...


I'm a big SolidJS fan, it's pretty much become my default framework for little things, and I highly recommend it.

It is very small and very quick - one of the fastest frameworks out there - but also not too complicated or lean. The signals system takes a bit of getting used to, particularly if you're coming from the React world (e.g. there are no render functions, rather each attribute is reactively updated when its data dependencies update), but it's also incredibly powerful once it clicks. Also, once you get down to it, almost everything is just native browser elements, so if you need to integrate with another tool or library, it's usually really obvious how that should work.


Problem with Solidjs is lack of mature ecosystem.


Once upon a time, I remember one of the plans for React was the ability to compile components into web components. Your code wouldn't have to change at all, but it would mean CSS couldn't leak in/out of the component boundaries like it does now. I think it would've also made it easier to use a React component in other frameworks, since all they'd see is the common web component interface instead of the React interface?


> I remember one of the plans for React was the ability to compile components into web components.

This was also the case (-ish) for Vue, Svelte, Solid. Their authors were really bullish on web components in the beginning. Now they are all on the scale from extremely negative towards them to completely indifferent.


While JSX is very well suited for programmatically defining your UI, it's about all that React is worth these days. You know about string literals right? You don't need JSX and in-fact can get away with:

   render(props) {
      return(
         `<div>
         {props.value}
         </div>`
      );
   }


My perspective is that JSX is all that React has to offer. And lots of developers - myself included - were doing "JSX" a decade before React arrived. Because it, like, super obviously a good idea.


It must be obvious to everyone else then but not me, would be good to get an explanation. My first reaction, and still reaction, to JSX is loathing at the mixing of JS + HTML. JSX's site says that this is a way of recognizing they are tied together and the focus is on separating concerns instead of technologies. Yet Angular manages to do a similar thing through its components, and still achieve separation of HTML/JS.


Angular is a fucking abomination on this front.

Angular doesn't separate concerns at all, it just ties it all together with an entirely new and un-intuitive DSL that you have to now write in the HTML.

Just look at your DSL here: https://angular.io/guide/binding-syntax#types-of-data-bindin...

You abso-fucking-lutely are writing code in your html, you're just writing a crippled version of their custom DSL instead of plain old javascript.

Frankly - I much prefer to write plain old javascript instead of learning a new bastard language that isn't useful anywhere else.

JSX achieves that relatively well. It's not entirely plain old javascript. But it's about as close as I've seen anyone get for a template language complete with data binding.

EJS https://ejs.co/ was my pick before JSX. For similar reasons - I don't want to have to learn a dsl which is just a shoddy wrapper for the JS anyways. Just let me write the damn javascript.


EJS was my pick as well. Shame. I feel like Preact is closer to nirvana but then Svelte comes along. Ideal state: I want a tag, that represents a class, that binds its attributes to properties and subscribes to changes, that encapsulates this within the tag class, including styling.

I’m very fricking close to this with web components and default Vite build. The only gotcha is having to bring along a few utility classes I wrote that glued it all together. Fewer than 40 lines.


> and still achieve separation of HTML/JS.

Why is this important to maintain? People have been complaining about this since the beginning, but I've never seen anyone actually articulate what the problem is.


Before React and this generation of frameworks, we had jQuery. In the jQuery world your site should work without JS. The page downloads, it's a usable page, and then your script starts attaching to elements to make the page more dynamic and responsive, if possible. If not, you still have the page.

It seems to me that progressive enhancement was a genuinely great idea, but somehow the true concept got lost. Nowadays some insist it's ok to have a site that won't begin to do anything without JS, but at the same time it's not OK to mix JS into the HTML code. That somehow we're preserving the purity of HTML as a display layer just by putting it in a separate file.


The biggest pet peeve of mine is when I'm presented a UI that doesn't function because the javascript hasn't loaded yet.

Do not show me a UI if it doesn't work when I press/touch it. More, if I visit your site and your UI doesn't present itself within 1-3s, there should be some alternative UI presented that explains why (rather than just a white page).


Forgive a bit of snark, but…

So PHP?

Mixing html and code is a pretty old paradigm.


That exists in every react app today so what’s your point? Are you arguing against it? If so, other than what I described (web components) how would you build a view? Web components or react components are supposed to be self-encapsulated so you can just add them to your view. Code and all. We are talking about view model code or presentation code.


I'm just saying that

> were doing "JSX" a decade before React arrived

is another instance of "rediscovering old paradigms". What I'm not saying is that this method of building a view is unnecessary, or wrong.

> If so, other than what I described (web components) how would you build a view?

There are many ways to create a view. Programming history is littered with them anywhere there's a UI to be created. Will they interact nicely with React? Probably not most of them, but it doesn't mean they do not exist.


More specifically, for the web. <script type="text/template"> arrived over a decade ago and it's taken us this long to get a <template> standard, let alone a document.createDocumentFragment(). These things take time. I know we are quick to adopt the good and then be shocked it takes so long for the rest of the world to standardize on, but it only reinforces what paradigms "work", and which ones don't by which paradigms become standards. Time will tell.


I don't think OP is arguing against "self-contained components" (with template and code), but about "presentation and business code mixed". I really like Vue's solution compared to React - the template is strictly separate from the logic driving the template. Same file, but seperate areas.

I've previously updated some components in a design system to Vue 3, where I followed the HTML results set by the React implementation. Reading the Vue 2 components worked almost immediately. The React components were so over-complicated that I sometimes literally had to follow the browser inspector instead of understanding every twist and turn in the code. I have never seen a Vue codebase that is as unreadable as the average React codebase with mixed business and presentation.


PHP? That's back-end (and fortunately I've never had to use)

I'm taking about HTML/JavaScript front-ends. The ideas behind JSX go back to at least 2004 when I first began using that paradigm.


Regardless of where it runs, the paradigm is very similar.

On a separate note, the attitude of "That's back-end" that permeates HTML/Javascript development is probably one of my biggest pet peeves; the disdain for what programming languages and GUI implementations have offered in the past hinders learning lessons from those implementations.

And that only holds us back.


"That's back-end" is how you can tell a good javascript dev from a bad one. A bad one doesn't know where the express/bun line ends and the browser begins. Be glad.

Also, GUI development has traditionally been a shit show. From Qt/WinForms to WPF to now using Web tech because the whole industry threw up their hands. There's MVC, MVVM, MVP, you name it to describe a proper UI->data relationship and all have failed to breach the boundary of their domain. Components, like ECS in game dev, are one way of solving this issue. Because we have to separate our markup from our logic we have JSX. I really wish I could do something like:

    this.view.set(<div></div>);
but the reality is this. If you're developing a UI using code, you don't need markup at all except for the specific element/display you are representing. Almost all of my webcomponents are just a div in a document.createElement and the rest is built up using the same. document.createElement. It's tedious, it's error prone, which is the argument for JSX. I don't need to create a Nav component and a Nav Bar component and a Nav Item component and a Nav Menu component, etc. I can just create a Nav Component and handle it all from there, simplifying my UI view code.

In the end, all of these work arounds are simply because we have to deal with the final product, html and we (myself included) get stuck behind the default tags because thats what we know. We don't need any of it. Define your own. Treat the page like it's one giant empty xml document and everything's derived from a div and see if the browser treats it any different. It doesn't. So your entire body could be made of:

    <article>
       <post>
           <post-title/>
           <post-author/>
           <post-body/>
       </post>
    </article>


> I don't need to create a Nav component and a Nav Bar component and a Nav Item component and a Nav Menu component, etc. I can just create a Nav Component and handle it all from there, simplifying my UI view code.

That seems like arguing you don't need functions in your programming language and can simplify it by inlining everything.


IYKYK, some cough frameworks cough have this idea of nesting nests of nests in order to have proper look and feel. I won't name names, but it became something people got used to and it's horrid. One or two parent->child stylings is one thing, but the aforementioned framework had up to 8 in this Nav functionality.


> the paradigm is very similar

I disagree. I believe you're referring to the paradigm of mixing markup and code, which I never did.


PHP is how I'd describe Astro.


what's going to make sure you didn't type <div></dib>


my ide... VSCode checks string literals for things like this.


Not exactly universal


Watch out for html escaping.


Assume props is pre-sanitized.


Ron Howard voice: in fact, props was not pre-sanitized.


you know about injection vulnerabilities, right? if you really want to spaghetti code your app with string representations of html, you can also use `dangerouslySetInnerHTML` in React.


You would do it as a tagged template literal rather than with plain string templating, similar to Postgres.js


For your div demo, sure, heck even the "todoapp" might work well enough with it.

But please, build something proper with just that and presumably a .innerHTML = ...

Let us know how it goes :)


I have many times and you've probably seen it in the wild but I won't give myself away that easily. A Fortune 50 does this with great success.


The point is you're susceptible to XSS attacks with that code.

But with a "tagged template" it should be easy to treat the variables before actually doing the templating, without making the code ugly.


It’s just an example


Hmmmm. Does that do escaping and such, or are you boned when an angle bracket shows up? Plus if the nodes are already parsed in your code it kinda sucks to stringify them so the browser can re-parse them.

Not to mention holding focus and other element state, would that just get blown away and replaced with a whole new element every time? (Where react does tree reconciliation to avoid unnecessarily blowing away and replacing elements)

Maybe you’re only addressing the point about programming model, but this approach seems like it has some issues.


I am indeed only address the point about the programming model. In react, state and bindings are one and the same (using useState). In mine, your class is the binding to the element, render is only called once and you're free to subscribe to any on* events back to your class functions you wish. onclick="this.click" just works in my world. You need a bit more than the 5 lines I showed but it's trivial. No shadow-dom, no reconciliation, no unnecessary blowing away of elements at all, and no reparsing the tree.


The shadow DOM is a great alternative to using iframes to get style isolation from the larger app, but everything else about custom elements/"web components" has better alternatives in user-land.


Each loops over anything with a length property:

    {#each {length: 3} as _, i}
https://stackoverflow.com/questions/58213585/svelte-3-how-to...


That's not really a huge improvement over just making a sparse array though, is it? Looks more confusing to me. Could be wrong but I'm pretty sure e.g. Array(1000000000) does not actually allocate much.


I'm not up to speed in JSX, how is it be better there? Don't one normally map over an array to loop? You cannot use for-loops inside JSX?

Or do you create an array of JSX-elements, like

    let elements=[]
    for (let i=0; i < 10; i++) {
      elements.push(<li key={i}>I'm number {i}</li>)
    }
    return <ol>{elements}</ol>;
Does not seem like an improvement to me.


It's just JS: You can do that, or you can use any helper method, or write your own helper. Can't really do that in Svelte.


captain obvious here, Polymer became LitElement which became the invisible Lit.dev (branding direction on par with twitter becoming x); pretty much state of the art on top of web components; not that anyone noticed, as I said--meetup.com keeps prompting me to take over one of the web component meetups where the (or one of) lead of the project can't seem to muster the effort. a bit frustrating when the lack of awareness is so profound and extensive--as evidenced by many of these comments, over many years. I'm sure many more projects will make the mistake of choosing React and Svelte before the conclusion mentioned here bubbles up.


I think JSX was a mistake and just using hyperscript would have been better for the ecosystem. I think frameworks peaked with mithril and have been downhill ever since.


Mithril wasnt back then what is it now.


I'm not familiar with how its evolved but I really enjoyed using it around 2015-2018.


How does one "react" to changes in a foreign element? Mutation Observers?


Those other tools you're using almost always give you a set of callbacks or events they will fire.

Just use the normal event handlers. If you're tied into a store (ex: redux/zustand/recoil/context/etc) just update the store from the non-react library and things will work themselves out just fine.

You can watch the DOM with mutationObservers, but if you own both pieces (react and non-react) why would you bother? They can both coordinate just fine.

MutationObservers really shine when you happen to missing an eventHandler you want in a library, or you're running on someone else's DOM so you don't control both sides (ex: you're an extension content_script).


I don't know.. Imagine you have a react component that needs to interact with something written in svelte...

I'm not convinced that people are building integration APIs for consumption by external code. That means no JS events (redundant since it uses stores or signals and whatnot) and minimal callback availability to hook into a component state.

One might not control the code if this is from an open-source library for instance.

Maybe the premise is "don't do that" , but then people still wanted WebComponents at some point. So seems there exist use-cases for component interaction. Or were people mistaken in the first place?


I don't understand your comment here.

I own both sides of the stack. Say I have a react component that happens to mount a svelte component in the DOM.

I expect Svelte code to be running somewhere (I wanted to use a svelte component, I have to initialize that stack).

I expect React code to be running somewhere (The main page is react, for example).

I expect to have some sort of signaling or state management solution (say a redux store, since the main page is react).

I can just update the redux store from both stacks. The store emits the correct events whenever it's updated - all subscribers are notified - react-redux does its magic and conditionally re-renders my react tree based on the new state.

I can do exactly the same thing in Svelte - subscribe to store events, see an events when react changes something, update my svelte app in response.

---

And it's absolutely not limited to redux... I can do the same thing by hand with global state, or by emitting custom events in the DOM, or any of a hundred other ways to get these two apps to work together. I own both sides - making them play nice is normally trivial (if not always quick, and sometimes tedious as all get out).


The state that is handled by svelte is not automatically visible to react and vice-versa.

That's the whole point of the question.


I guess my response is: "So make it visible". Because that's easy to do with any manner of methods.

Sure - each library is going to do its own thing with regards to how it manages it's internal DOM and state, but that does not matter at all.

All you care about in wiring them together is:

"Can I call some js code in response to state change in svelte?"

and

"Can I call some js code in response to a state change in react?"

and the answer to both is a resounding "Yes!".

So now I can easily make the state of one visible to the other... I just run some code in response to a change on either side that updates the state of the other - done.

If you want to get adventurous - you can automate the entire thing away with a proxy store, so it happens everywhere by default.


> I don't know.. Imagine you have a react component that needs to interact with something written in svelte...

this doesn't happen in practice... like at all...

is your implicit assumption that anything written in react will automatically work just fine with svelte but not the other way around? why would react -> svelte be any easier than svelte -> react, and why is the burden on React to solve interoperability problems between competing frontend frameworks?


That was an example, you can take it any way you want it (angular to react, react to angular etc) ... Don't get triggered. That's not the point.

Of course it can't happen if it's not easily if at all feasible. That doesn't mean that people don't want to do it.

The fact of the matter is that it seems to me that WebComponents are an attempt at solving an interoperability issue. Or am I misunderstanding?


> React's programming model with Svelte's "compiling down to nothing" mantra.

Solid JS!




Consider applying for YC's Spring batch! Applications are open till Feb 11.

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

Search: