jeswin 3 days ago

I tried to understand the referenced article "Web Components Are Not the Future" - but found that there weren't many convincing arguments.

The current state of Front-end frameworks is an absolute mess. Speaking for myself, I don't want to learn a complex framework. I don't want to learn magic that I don't understand without reading the documentation (useState, createSignal et al). Magic in frameworks is often a hack, unlike magic in libraries. The first library I used was Prototype. It felt like magic, and it truly was. And so was jQuery, and Backbone. I never had to guess what "useState" does behind the scenes.

There are many things which don't carry over into Web Components from current JS frameworks. But if you start from Web Components (ignoring everything you know about frameworks), it suddenly becomes intuitive. And it brings in abilities which are missing otherwise, such as isolation via Shadow DOM. It grows on you.

In my view the only thing we should retain from the React era is JSX (for many reasons, true type-safety, autocomplete etc). I wrote a library last week for using Web Components with JSX. No magic other than JSX. https://webjsx.org

  • crabmusket 3 days ago

    > I don't want to learn a complex framework. I don't want to learn magic that I don't understand without reading the documentation (useState, createSignal et al).

    I can't really parse this sentence. It seems to have a lot of ideas in it. Do you want to learn a framework at all, or have one that is so magical that it feels like it doesn't need to be learned? Do you want to read documentation or not? Do you think the problem with React is that its primitives are unsuited to the work you do in it? Or to the work anybody needs to do?

    I've spent most of my professional career in Vue, so I don't have a great perspective on the React ecosystem. But Vue feels like it must be included in your "complex framework" statement. I've definitely felt some pain from overuse of the framework, or poor understanding of various features, libraries, etc. The ecosystem around full-on SPAs is indeed complex. I'm just not sure what other systems would let me personally, and us broadly, manage a complex stateful client-side app.

    (This is entirely separate to overuse of SPAs for things that shouldn't be SPAs.)

    • eddd-ddde 3 days ago

      I think the point is that frameworks ' magic isn't 100% there yet. You eventually HAVE to dive deep and understand things about the implementation to understand how to use it.

      • AlexErrant 3 days ago

        Ryan builds out Solid's reactivity system (createSignal) from scratch in about 20 minutes, live, in this video https://youtu.be/N-Y32BqhoYQ?t=1100

        I haven't bothered fully grokking it because I've never had to understand the impl details. Solid gives me literal dom elements, and that's low-level enough for me.

      • ruszki 2 days ago

        I’ve never seen a framework or even languages into which I don’t need to dig deep from time to time. It seems to me an unachievable high bar.

    • hu3 3 days ago

      I'll try to give an example of "bad magic".

      Did you know React renders twice in developer mode to try to expose bugs with side effects?

      If this doesn't raise an eyebrow, I don't know what will.

      • jemmyw 3 days ago

        That seems like a pragmatic solution. The point of having a dev mode is to help development and catch mistakes. if(devMode) { rerender() } doesn't seem like magic. Though in general I really dislike the term magic for what is just code doing something.

        • hu3 2 days ago

          Humans have limited cognitive capacity (and time).

          To me magic code is code that requires a significant level of cognitive investment to understand and keep in your brain RAM. That threshold varies between people but it's always there.

          In React's case, the chosen solution is not the issue here. It's a symptom of bad architecture. The library should be doing more than rendering twice to protect developers from side effects, to a point that rendering twice wouldn't be required.

          That feels as bad as rebooting JBOSS servers once a day to "fix" OOM crashes. It's a hack at best and doesn't fix the real issue.

          • jemmyw 16 minutes ago

            I disagree. React is saying that you need to pass it a function for rendering a component and it does not guarantee how many times that function will be called. There are documented, well defined ways to call side effects based on component lifecycles.

            However, how can react know what a side effect is? Hook into well known ones by hijacking the browser API? That sounds like a bad idea. Provide their own linter/compiler. That seems on the radar but I'm not sure I like the idea.

            Also react doesn't stop you from doing it. You can say nah it's fine I want my side effect. It just runs the render explicitly twice in development, something that could happen in production for various reasons, so you can see what will happen.

            Your proposed solution isn't very practical. A better solution would be a guarantee that render will only run once. But that's not how react has ever worked. There are other frameworks that do that. As with anything, there'll be a trade-off.

          • edflsafoiewq 2 days ago

            > The library should be doing more than rendering twice to protect developers from side effects

            Like what?

            • bryanrasmussen 2 days ago

              probably the parent poster does not use React so it would seem a heavy demand on a human to make, given the already stated limited cognitive energy and time.

              I suppose I would think not rendering twice and some sort of warning about side effects would be beneficial, rendering twice means that you get a misleading view of what your application behavior is, I can see how people would - from an architectural perspective - consider it bad without necessarily using the framework.

              • kaoD 2 days ago

                > some sort of warning about side effects would be beneficial

                Rendering twice is exactly what allows you to detect that. How would you detect a side effect if not by calling the function twice?

                React's contract is that your component should be allowed to render twice without any changes so this is just upholding the invariant in dev mode.

              • hu3 2 days ago

                I do also use React, unfortunately.

            • hu3 2 days ago

              If you have to ask.

              Learn Elm and you'll see React's shortcomings clearer. They don't render twice but that is just the tip of the iceberg.

              Be warned though, exiting the cave is painful.

              • jemmyw a day ago

                I've used elm. It's not that great. In many ways it has the same shortcomings as react but far worse. That is you find yourself wanting to do something as yet unsupported (which we often do because otherwise why write new software in the first place) you have to break out of it's abstraction. Except doing so is 10x harder with elm, and the community around it is so much smaller you can't find the answers. Also, after I personally had moved on, there was something of a tension between the community and the authors. Maybe that's resolved, although I'd suspect for some the resolution was to no longer be part of it.

            • Daishiman 2 days ago

              Things like validating or limiting possible React code you can write such that these effects are impossible, in the same manner that abstract data types in programming languages attempt to define data structures that are correct by construction, or the same way that reactive programming enforces a programming paradigm that attempts to minimize unwanted interaction glitches.

        • CharlieDigital 2 days ago

          It's because the fundamental model of React's render cycle is unintuitive when combined with state. It's easy to make mistakes of this class specifically with React.

        • mpweiher 2 days ago

          > That seems like a pragmatic solution.

          That's not a contradiction to it being bad magic.

          In fact, this being a pragmatic solution is a strong, though not conclusive, indicator that the underlying abstractions are not fit for purpose.

          And the fact that lots of pragmatic choices led to those abstractions that are not fit for purpose also is an indicator that something about the starting point or the road is not right. Or both.

          • jemmyw 6 minutes ago

            > abstractions that are not fit for purpose

            You say that, but react is very successful, indicating that it's abstractions are working just fine for many people. Maybe we'd say they're not perfect but they fit it's purpose. It might not be my favourite frontend library to work with, but it's the one I'd be most likely to choose for commercial work because it does work well, and high use means that people have explored many solutions to problems with it.

      • Guillaume86 2 days ago

        Why do you care? Or are you just against the general idea of a framework having constaints that are a bit unusual for their language, like "components must be pure"?

      • c-hendricks 2 days ago

        It doesn't though. StrictMode does, and that's optional.

      • kaba0 2 days ago

        Why would that be bad magic? It’s a very clever way to expose stuff that is accidentally side effecting.

    • szundi 3 days ago

      I think he was pretty clear that the "magic" in frameworks is not something you can easily understand, therefore have to guess how it really works. He doesn't like that.

      • jemmyw 3 days ago

        You don't need to guess. You can actually read the code! Not saying that you should straight away when learning, but later, when you're familiar with your framework, I think reading through the codebase and understanding it is good practice.

        • cj 2 days ago

          You can read the code, but it’s complex and convoluted.

          He referenced Backbone as a comparison point. If you compare Backbone’s source code to React’s source code, you’ll get what he means.

          Basically, libraries like Backbone are small and simple enough that you can literally read the source code and fully understand how it works. Compare that to React, where the source code is an order of magnitude larger and very difficult to fully grasp the inner workings.

          The simplicity and ability to easily understand the source code obviously comes with tradeoffs (e.g. with Backbone, to use it to build a reasonably complex app, you basically have to build your own framework on top of it, compared to React which has more abstractions and therefore is more plug and play.

          • jemmyw a day ago

            It's complex but not that convoluted.

        • spion 2 days ago

          IIRC reading the React source code became quite a feat around the time fibers were introduced.

    • mpweiher 2 days ago

      > Do you want to learn a framework at all, or have one that is so magical that it feels like it doesn't need to be learned?

      My view is that the problem domain is not complex enough to warrant the complexity of our "solutions".

      See also: https://www.youtube.com/watch?v=ubaX1Smg6pY

      Is it really "Complex"? Or did we just make it "Complicated"?

    • redman25 2 days ago

      I've found the Vue community to be a little better at managing complexity than the react community has mainly because Vue was originally touted as a solution to some of react's problems. People are more conscious of the tradeoffs.

  • rty32 3 days ago

    One aspect of this is how you think about UI. The underlying pattern of jQuery is fully side-effects -- you select an element and make some changes to it. Frameworks like React and Vue.js allows to create UI components whose states are completely determined by data, i.e. what the UI looks like is the value of a pure function, mathematically speaking. It also updates the UI with minimum DOM changes when the data changes. (Although you don't have to make them pure, and arguably you can achieve the same thing with jQuery.) Depending on where you are, it makes UI widgets much more readable and maintainable. These frameworks are innovative in terms of state management compared to "old approaches" (of course, with additional benefits like reusability etc)

    Bear in mind that today's websites and web based desktop applications are much, much more complicated than two decades ago, and has a much higher requirement for scalability and maintainability. If you just want to create simple UI, indeed they may not be your best choice.

  • jsyang00 3 days ago

    You do not need to know how `useState` works to understand how to use it to write a React application, it is fairly intuitive to understand how to apply the pattern.

    If I look at your library, it seems to me like it requires a much more complex mental model to begin to use.

    Of course, it is better in theory for a developer to thoroughly understand the details of their framework, but empirically, React has been very successful in allowing people to build relatively sophisticated applications while understanding very little of the underlying model.

    • InsideOutSanta 3 days ago

      "You do not need to know how `useState` works"

      I feel like you eventually do. The issue with React, at least in my experience, is that it's a type of abstraction that seems ill-suited for how the web works under the hood, so it's incredibly leaky. Everything seems to make sense initially, and you get along just fine, but then you run into an edge case, and there's an official workaround for the edge case, but then you run into edge cases for the workaround for the edge case, and suddenly, that's your whole life.

      Before you know it, you really do have to know how things actually work under the hood.

      • dartos 2 days ago

        I thought pre-hooks react provided a really nice and simple abstraction over how the web works.

        FRP is a nice fit for the kind of UI that makes the majority of the web.

        Hooks ruined the framework imo. Confusing api (useState returning an array for example).

        Having a class component with hooks for lifecycle behavior made perfect sense. Each component’s state being a field on those classes was easy to understand.

        Hooks came out of left field and made everything more complex for the worse.

        • kaoD 2 days ago

          > Hooks ruined the framework imo. Confusing api (useState returning an array for example).

          It just returns a tuple. That's not confusing at all and it's a very well established pattern in most modern languages.

          If there's anything that can be considered complex and footgun-y in React it's useEffect because most of the time you shouldn't use it at all but it can be abused very easily and it kinda works even if you abuse it (but introduces a huge maintenance burden).

          • dartos 2 days ago

            > It just returns a tuple. That's not confusing at all and it's a very well established pattern in most modern languages.

            A few things wrong with this. It does not return a tuple, it returns an array with 2 elements. You, as the react dev, need to just know that this is the case and that one is the value and the other is a set function.

            In most modern languages, tuples are common, yes. But not in JavaScript. React isn’t a python or go framework, it’s a JavaScript framework. Why doesn’t it act like almost everything else in js land and return an object with 2 named fields? Why place extra knowledge burden on the developer? It’s just poor api design

            Yes useEffect is also a huge complex pain point, but it just takes longer to type out why that is.

            Pretty much all the hooks are as almost nothing else in the JavaScript ecosystem acts like they do.

            • xpl 2 days ago

              > Yes useEffect is also a huge complex pain point

              We have a rule of thumb in our projects: if you use useEffect directly in application code, it is a probable sign that something is wrong with your code, like you're working on a wrong level of abstraction. Almost every direct use of useEffect is better solved with some standard hook from a popular library (like react-use or whatever you like — there are plenty of them).

              Like, binding event listeners? useEventListener

              Network/async calls? useAsync

              timeouts/intervals? useInterval, useTimeout

              And etc. etc.

              useEffect is really a low-level building block for library code and we rarely use it directly, as it is unsafe and hides the original intent. Much like `new` and `delete` in C++ — you don't use it directly, there are smart pointers. Library hooks are your safe smart pointers over useEffect.

            • xpl 2 days ago

              > Why doesn’t it act like almost everything else in js land and return an object with 2 named fields

              The explanation is actually very simple: because in 100% of times you need to give those two fields custom names. It is easier and more concise with tuple:

                const [text, setText] = ...
              
              Than with object + renaming, which quickly gets clumsy when you have dozens of such lines in your component:

                const {value: text, setValue: setText} = ...
              • dartos 2 days ago

                That’s not a good reason.

                Especially in our world where strong typing is something preferable.

                Fewer characters at the cost of clarity is poor api design. Implicitness is almost always worse than explicitness.

                Explicit !== clumsy

                And again, almost nothing else in the js ecosystem behaves like this. Especially at the time of the big hooks update to react.

                Also, again, it’s not a tuple. It’s an array with 2 elements. JavaScript does not have tuples or the semantics for interacting with them as such. You just need to know that there’s always going to be 2 elements.

                That extra knowledge burden is the hallmark of poor api design.

                • xpl 2 days ago

                  > Also, again, it’s not a tuple. It’s an array with 2 elements. JavaScript does not have tuples or the semantics for interacting with them as such

                  Not true. In TypeScript, there are tuples — you can perfectly describe an array having 2 elements with different types, and even give names to them:

                    type KVPairTuple = [key: string, value: number]
                  
                  We use it all the time for simple 2-element thingies. You can say JavaScript isn't TypeScript, but cmon, just everybody out there uses TypeScript, it is the basic norm nowadays. So we're really talking about TypeScript semantics here.

                  Also, even JS uses tuples for its core APIs. Enter `Object.entries` and `Object.fromEntries` — they operate on kv-pairs in form of 2-element arrays. So your assertion that tuples are something alien to JS ecosystem isn't accurate simply because of that.

                  • dartos a day ago

                    > Not true. In TypeScript…

                    Not talking about typescript.

                    Typescript wasn’t nearly as wide spread or as complete back then anyway. Facebook was still on flow.

                    > they operate on kv-pairs in form of 2-element arrays.

                    So… Not tuples…

                    > So your assertion that tuples are something alien to JS ecosystem isn't accurate simply because of that.

                    My words were “almost nothing else.” I’m sure someone somewhere uses the idea of tuples in their js code (implemented as arrays, ofc) but it’s extremely far from the norm.

                    Also none of that refutes my point that it’s poor api design. Thanks for being pedantic tho.

                    • kaoD a day ago

                      > Not talking about typescript.

                      TS is just encoding JS semantics into a type system.

                      A function returning a fixed-size array in JS is effectively returning, semantically, a tuple. They're just not a different type unlike in other languages (for different reasons).

                      JS arrays are not even arrays since they (1) are not contiguous and (2) do not require items to be of the same size (typed arrays are actual arrays though) except by their backing implementation (which uses js vals, but that's a property of the implementation, not the language). They're sparse vectors. But nobody cares about that technical distinction and we still call fixed-size arrays tuples and variable-size arrays arrays. You can even attach properties to them because arrays are not vectors, they are objects. Or can be, for that matter. The backing implementations are complex and very dynamic.

                      JS was intentionally made this simple so it could have emergent semantics. Scheme-ish.

                      > Typescript wasn’t nearly as wide spread or as complete back then anyway. Facebook was still on flow.

                      It was when they introduced hooks.

        • com2kid 2 days ago

          React + classes made sense. Redux was hard to use. All react needed was a simple state management solution that didn't take 500 loc across multiple files and a ton of useless object copying to make a page full of form elements work.

          Instead it got a complete paradigm shift to a leaky abstraction. Not that the previous abstraction wasn't leaky, it was alwayz super easy to have components re-render when not necessarily.

        • ljm 2 days ago

          There's a world where browser UIs are programmed in Smalltalk instead, which I think is what the authors of the DOM may have intended when building it out OOP-style.

          It would bear almost no resemblance to the web we have today, but message passing between UI components throughout various parts of their lifecycle has been a great way to model an interface for decades. You only need to look at the overall fit and finish of a typical MacOS or iOS app, with Swift simply pulling Objective-C into the 21st century.

          • dartos 2 days ago

            Web UIs tend to make heavy use of message passing via event listeners.

            The major difference between web UIs and desktop apps is two fold. In web UIs, you don’t generally have an event loop in which you change your app state based on system input events and there is, generally, a slow request/response cycle for any interaction.

            That’s why immediate mode UI doesn’t really fit well in web land.

      • djbusby 3 days ago

        Seems like that happens with every frameworks I've ever used since 2000 (in Perl, PHP, Ruby, JS, etc). Every framework makes the easy things slightly easier, the boring stuff is included and you get to focus on the fun/hard part - and I think then, naturally, you bump into the edge. But! You get to that point faster. And then you have to know the guts to solve the issue the "framework" way or do some lower-level shit-hack.

        I feel like it's just a natural law of any general purpose framework.

        It made the first 80% of the job easy. Now you just have to finish the other 80%.

    • recursive 3 days ago

      This hasn't been my experience at all. The implementation details even leak into this crazy thing called "the rules of hooks". It looks like a function but it's actually this new thing called a hook. Which state will you get? That depends on whether the reconciler considers this invocation to be a mount or update. Getting the wrong one? Try restructuring your elements or adding or removing a "key" attribute.

      People tolerate this because they learned it but I don't think there is anything essentially simple about it.

      • phist_mcgee 2 days ago

        If you have an understanding of closures, hooks are quite intuitive.

        • recursive 2 days ago

          I have a pretty thorough understanding of both. But I can't understand how you'd find them to be similar in any way. Functions forming closures can be called conditionally, in a loop, or even when no react component is even rendering. Most of the complexity of hooks is not addressed at all by closures, and I don't really what part of their behavior is related at all. Maybe just that you can pass a value to one function, and then get it returned from another one.

          The standard hooks delegate to a dispatcher, which has access to the current fiber. The current fiber has a linked list of memoizedState for the current work node. It's true that a lot of the functions that eventually service the hook calls do contain closures. But that doesn't seem to grant much insight into how to use them or how they work.

          It's like saying "if you have an understanding of loops, the reconciler is quite intuitive". I mean yes, the reconciler uses loops. But the behavior of reconciliation may still be quite mysterious.

          • kaoD 2 days ago

            I'll try to fix the comment you're replying to:

            I think of React components as not closures but coroutines (and hooks are its yield points).

            Hooks are implicitly keyed by index which is the most magic-y/surprising part... but I'm sure if you had to manually key them that'd be criticized too (and would be abused to death-by-bugs, so I can see why they went with this design).

            If you understand both points above, you understand hooks.

            I still fail to get the (usual) criticism of hooks. They have lots of warts but the API (which is often what gets mentioned) is the most superficial and less annoying criticism. Feels like something that would be mentioned after just skimming the docs. Very shallow.

            On the contrary: useEffect is a footgun and deserves criticism. useRef being overloaded to mimic instance variables is confusing for newbies (but this is just a naming issue IMO). The difference between normal/layout/insertion effects is complex and subtle. The new stuff that tries to solve some issues with the concurrent mode (like transitions/deferred value/etc.) feels like a huge hack.

            React 19 will come with its own warts (actions, RSC...)

            But the API? I don't care at all. Pretty simple, at least for my mental model.

            • com2kid 2 days ago

              The complaint is they prior to hooks react didn't have any of this complexity. It was pretty simple to understand. Class components works mostly as you expected them to. There are a handful of things that were really hard to do with class components that hooks + function components made easier, but lots of other things became more complicated with each new set of features react has added since then. At this point the solution to "class components are complicate" is far more complicated than class components ever were.

              • kaoD 2 days ago

                I understand the complaint but my point is that, in my experience (which admittedly might be biased), the complaint usually does not resonate with anyone that did actually use React for at least a moderately complex app.

                Hook's API is not perfect but it's a good-enough abstraction that allows the user to have even better abstractions and separation of concerns.

                Actual React users did not care about that because the pragmatism far outweighs the theoretical ugliness... which honestly is not even that ugly if you have a mental model similar to coroutines (of course if all you do is OOP a class will look better to you...)

                I have recently been fixing some stuff in my old React pre-hooks code and I hated it because class-based components had all sorts of concerns intermixed on their lifecycle methods... no matter how much you tried to abstract them.

                Abstracting those into reusable hooks was a breeze and made everything much easier to follow and maintain.

                Hooks are far better from a pragmatic point of view.

                > There are a handful of things that were really hard to do with class components that hooks + function components made easier, but lots of other things became more complicated

                Like what? Does not match my experience at all.

                • com2kid 2 days ago

                  > I have recently been fixing some stuff in my old React pre-hooks code and I hated it because class-based components had all sorts of concerns intermixed on their lifecycle methods... no matter how much you tried to abstract them.

                  The lifecycle concerns are still there, sometimes things need to happen when a component is first displayed, and sometimes things need to happen with a component is removed from the page. It is just handled differently now.

                  My other issue with hooks vs classes is that, and I say this as someone who loves FP, the best application of OO programming is for UIs. At the base level, a text input field has an object created in the browser, and that input field has state. UIs are inherently stateful things. The OO model is natural for building UIs, you typically shove an object on the screen, that object has some state, and the user manipulates that state.

                  OO is a great abstraction for UIs. IMHO it is a pretty bad abstraction for most other problem domains, but for stateful UIs, OO maps pretty darn well to what is actually happening!

                  I just don't see the benefit of throwing another abstraction layer on top of all that.

                  One reason I love Svelte 4 (haven't tried 5 yet) is that it is so bloody simple compared to React. After years of programming in React, I was literally 5x more productive in my first ever Svelte project than I had ever been in React.

                  All I need is a good way to encapsulate HTML components for reuse (which is fundamentally an OO thing, instantiate new instances of a component template!) and a good state management system that pushes state changes out to subscribed components.

                • recursive 2 days ago

                  For me, it's not OOP vs functional. I find "functional" to be a misnomer as its applied to most react components. Functional used to have a clear definition about having a stable return value and only varying based on parameters.

                  However, the same problem started afflicting class-based components prior to the introduction of hooks. When fibers were created, component instances no longer tracked their own state. State was injected into them prior to invoking the render function, based on reconciliation. I suppose even before that the reconciler was still choosing which component instance to render.

                  But at least components had an identity that could be addressed in application code. Now component identity is effectively the fiber instance identity (or its alternate), which is impossible to get a reference to.

                  In real life, people really seem to like hooks. I can see some of the benefits they provide over the OOP class-based component model. But I can't avoid also seeing the mental foot-guns associated with it.

                  The very first time I every tried to write a react app, I got tripped up by this. I add a component that moves around in a parent component conditionally. So I had `const inner = <Inner />`, and then based on some condition it would be inserted in various places in the rendered parent component.

                  Of course after much wailing and gnashing of teeth, I learned that this variable declaration wasn't establishing a component identity. It merely creates an "element", even if it has a key attribute. Component identity, as used to retrieve state, is fundamentally tangled up with reconciliation which can only see the final rendered output of a component. No other components can have state, at least as recorded by a hook.

                  Most people don't seem to have trouble with this, but it's not how I naturally think of things.

                  • kaoD 2 days ago

                    Unless my memory is very hazy none of that is related to hooks.

                    Identity in React has always relied on vDOM structure or `key` which was introduced in React 0.4.0 (July 17 2013, <2 months after initial public release).

                    > For me, it's not OOP vs functional.

                    Neither is for me. Note I didn't mention functional once.

                    • recursive 2 days ago

                      > Identity in React has always relied on vDOM structure or `key` which was introduced in React 0.4.0

                      You are correct. But so, I believe, was I. Apologies for being unclear. vDOM structure is determined based on the return values from render functions. As opposed to the line of code where elements are created. So if you have `const cmp = <Comp />` in a render function, it doesn't have an identity yet. As you note, that will be determined later, sometime after this render function returns. It might not have a state at all. It might even have multiple states. If the current rendering is an update, `cmp` might be a mount instead.

                      All these determinations are made based on the content (structure and key attributes) of the assembled vDOM and the reconciliation heuristics.

                      > Note I didn't mention functional once.

                      I assumed that's the comparison you were drawing with this line. "better" than what?

                      > of course if all you do is OOP a class will look better to you

                • kccqzy 2 days ago

                  > because class-based components had all sorts of concerns intermixed on their lifecycle methods

                  I think this just means your components are too large and try to do too many things. When your components are simple, their concerns are simple enough that they can immediately be understood, even if spread over several lifecycle methods.

                • watwut 2 days ago

                  > of course if all you do is OOP a class will look better to you...

                  Funny thing is, I do not know what coroutines are and have zero experience with them. I am object oriented class programmer who never cared about functional programming.

                  I figured hooks intuitively and straightforwardly when I had to work with react a year ago. Ok, function with state, but it was easy to read them, imagine what they do and maintain the code. It just seemed as an improvement over the old react to me, despite having no coroutines knowledge.

                  • kaoD 2 days ago

                    Exactly!

                    To be honest they're not full-blown coroutines (since the React runtime cannot control when the component progresses) which might be a bit more complex to grasp... but the idea of "yielding control" to someone else (i.e. to React, when calling one of its hooks) is there and as you say it's pretty straightforward.

            • recursive 2 days ago

              Which coroutine gets resumed by a rendering component is determined by reconciliation. Rendered components themselves have no identity aside from the reconciler's algorithm for equality.

              For me, this is the root of the problem. Or one of them anyway.

              Hooks are keyed by execution order, but also the reconciler's opinion about component identity, which you can only control indirectly. Fortunately it usually does what you want. Unfortunately it's not all the time.

              I feel like I do understand hooks, but it's not from reading the docs, and it's not from using them. I know this is not typical but doing those things didn't seem to illuminate much to me. I would still find them doing things I didn't want that I couldn't explain. It was only after reading the source that I feel like I understand the model. And personally, it's not one I would use by choice. I can do it if I'm required by a team I'm on. But for me, there's a mental overhead for "thinking in react". It's not a natural set of constraints for me.

            • afiori 2 days ago

              I think that the clearer way to explain hooks is just referencing how they are implemented.

              When a function component is called it is called on a "fiber" a stateful representation of the component instance.

              This fiber is available to the hook as if it was global variable that is set before the component is rendered.

              This is why you cannot call a hook is a setTimeout or a callback to another component: the global fiber is either unset or has a different value.

              The other part is that each hook invocation works on a state accessed as sorta fiber.hooks[index++].

              So for example you can call hooks in a loop or in conditionals or in synchronous callbacks, but each rendering must be compatible with the first.

              Eg

                let s;
                If(Math.random()<0.5) s=useState({});
                else s=useState([])
              
              Should work.

              You could also do the same with useEffect if you keep the length/nullness of the dept array.

            • 8note 2 days ago

              Ive probably been doing it wrong, but isn't useEffect needed to make any hooks work? useState does nothing most of the time

        • imtringued 2 days ago

          Hooks have very little to do with closures.

          The key aspect of hooks is that what you are doing is something like this:

          function(context) { context.useState() }

          Where context is a variable that stores all the hook related data, except in reality that variable is a hidden global variable and useState() accesses that variable internally.

          Yeah, they added hooks as global functions so that they look like a "cute" DSL. It saves you the effort to type c.useState instead of useState I guess.

          The above code is just for illustrative purposes to get the idea across, according to other commenters the internal implementation has changed from what I remember, but the principle is still the same. Global functions demand global state.

    • bakugo 3 days ago

      You don't need to understand how useState works if you're writing a page with a button that increments a number when pressed, from a beginner's tutorial.

      As soon as you work on any remotely complex codebase, you will run into problems that require a decent mental model of the underlying "magic" to properly understand and solve. "Building sophisticated applications while understanding very little of the underlying model" is how you end up with gigantic piles of unmaintainable spaghetti code full of awful hacks, which seems to be the standard for React applications.

      • lolinder 3 days ago

        Is this less true of Web Components?

        I've worked with a lot of different tech stacks over my career and every single one of them has required understanding the internals once you start using them seriously. I haven't found React to be substantially worse for that than any other tech stack I've used.

        • peebeebee 3 days ago

          With webcomponents you are pretty close to the “metal”. If you know how to write good vanilla JavaScript, you can take most of that knowledge into webcomponents. You only need to learn the custom components lifecycle, and shadowDOM, which is knowledge about web-standards. With other frameworks you need to learn template syntaxing, how state propagates, how the compiler works, etc etc. Lot of that knowledge might be obsolete in 10 years.

          Which isn’t to say it can’t be worth it. Learning multiple frameworks and libraries is also very helpful to skill up because you are learning about different concepts and implementations.

          • Narhem 3 days ago

            Another advantage of web components is the syntax is similar enough to Java (especially with JavaDocs) switching between coding a Java spring backend and a Web component based front end is doesn’t need as much of a mental context switch.

    • azangru 2 days ago

      While you do not need to understand how useState, or any other hooks work, you do need to know that this piece of code will behave differently from the rest of your javascript. Painfully, when the calling of (most of the) hooks is concerned, React takes away from the developer the ability to write conditional logic. This is both unintuitive and bonkers, and it requires the developer to come up with convoluted techniques for working around this limitation. This is part of what 'understanding of how hooks work' means.

    • _heimdall 2 days ago

      There are a lot of footguns in react if you don't know how use state works.

      If you don't know what triggers a re-render you can end up in a state where the data was changed but the UI didn't update, or where the data changed once and re-rendered multiple times.

      In my experience the issues are more noticeable with async state changes, like making network requests or state-driven animations.

    • jeswin 3 days ago

      > If I look at your library, it seems to me like it requires a much more complex mental model to begin to use.

      How so?

      It has two functions:

      (1) createElement(jsx): Allows you to use JSX to write HTML markup. Returns Virtual Nodes.

      (2) applyDiff(parent, vNodes): Merges Virtual Nodes created with JSX into the real DOM efficiently.

      This is all you need to know. I can keep it simple because I am not doing much in the library. I felt that if I stayed close to the standards, I wouldn't need to do much.

      • BoorishBears 3 days ago

        Maybe you have the luxury of users who want applications that have all the reactivity of a DMV form, but in my apps at some point I'll need the very simple priciple of "do something complex when this value changes" and reimplement useState/useEffect in an ad-hoc manner anyways.

        I'm more of a backend/embedded developer than a web developer and I still honestly don't get how people find useState/useEffect as intimidating as your comment makes them out to be.

    • bvrmn 2 days ago

      Aha-ha. Devs constantly try to use dynamic hooks. For example conditionally rendered component which allocates a hook. Yes, React would trigger a warning, that number of hooks was changed. But this implementation detail requires you to have at least a mental model of what hooks actually are to avoid gotchas.

  • chmod775 2 days ago

    > I don't want to learn magic that I don't understand without reading the documentation (useState, createSignal et al).

    Really now. Most devs who think to themselves "man I wonder how useState works internally" will arrive at the logical and correct answer within seconds. It's not complicated or magic. There are bare-bones implementations of react hooks (-ish) with a couple hundred lines of code. Implementing a basic "useState" and "runFunctionComponent" is easier than most third-semester CS assignments.

    If that's the bar for magic, I'm surrounded by 20th level Warlocks coming up with new Eldritch Invocations for fun over breakfast.

    • spion 2 days ago

      > Implementing a basic "useState" and "runFunctionComponent" is easier than most third-semester CS assignments.

      I'm not sure it is. There is a global dispatcher that finds the right component state to use and increments a counter to ensure that the correct state "slot" for that component is used. There are also a bunch of mechanisms to prevent slot mismatches. I guess you could make a loose analogy with writing custom allocators, except instead of the binding knowing the address, the order of calling useState determines the address :) Really not that simple.

      • chmod775 a day ago

        > I'm not sure it is. There is a global dispatcher that finds the right component state to use and increments a counter to ensure that the correct state "slot" for that component is used.

        Explicitly not part of that proposed task. We're talking about a basic hooks implementation with useState here, not how react deals with its tree of components.

        For the sake of the task the signature of runFunctionComponent just needs to be

            runFunctionComponent<P, R>(fc: (props: P) => R, props: P, hooks?: any[]): { hooks: any[], returnValue: R }
        
        or even dumbed down to

            runWithHooks(runFC: () => void, hooks?: any[]): any[]
        
        where runFC would wrap the call to the function component to pass the appropriate props and store the return value, freeing students from thinking about that. Also specify the function doesn't need to be re-entrant.

        In either case it won't need concern itself with what the component returns (children, whatever), matching children to tree nodes, or scheduling, at all. Would be nonsense to cram that logic in there anyhow.

        What you were talking about would make a good later task: easy to get a basic implementation, but hard to get an implementation that isn't subtly wrong in some way. Plus you can slap on extra goals like supporting keys. Lots of room to score students beyond just pass/fail.

    • zelphirkalt 2 days ago

      Hundreds of lines of code?? That sounds like way too much complication for something like that, tbh.

      • chmod775 2 days ago

        If you want to be at least sort-of react hooks compatible, there's a bunch of hooks you need to implement.

      • kaba0 2 days ago

        Heh? My smallest hobby project that is not a POC but actually is finished and is doing something is like 1000 lines long. There are very few stuff you can do with less than 100 lines.

        (Just for completeness sake, Haskell and alia sometimes might get away with less lines, because they tend to be “wider”. Word-count is a better metric here)

    • imtringued 2 days ago

      >Most devs who think to themselves "man I wonder how useState works internally" will arrive at the logical and correct answer within seconds.

      The answer is shockingly dumb. To be fair, I checked the code years ago, but basically almost every hook calls useReducer internally and useReducer uses an array stored in a global variable that is set before your component code gets called and the order of the hook calls determines which hook gets what useReducer state.

      It's basically a giant kludge and the React developers and users pat themselves on the back how "functional" their components are, when in reality they are flinging global mutable state like crazy.

      • chmod775 2 days ago

        > It's basically a giant kludge and the React developers and users pat themselves on the back how "functional" their components are, when in reality they are flinging global mutable state like crazy.

        This is true for literally every useful computer program ever. At some level it operates exclusively on global mutable state. Doesn't mean your high level programmer-facing interface has to look like that though.

      • kaba0 2 days ago

        Haskell compiles down to a C “subset” called C-, and flings mutable state and memory like crazy. That’s the whole point of encapsulation, if the abstraction is sound then it absolutely doesn’t matter that react uses global state — like how else would they do it with this user ergonomics? Using JS is a given.

  • InsideOutSanta 3 days ago

    I'm building my most recent project with web components + htmx, and it's mind-blowing how much better all of this feels to me than the typical React/Angular stack. I think there's a place for React and Angular and technologies like them, but 90% of the projects that currently use them would be better off with a much simpler stack.

    • DimmieMan 2 days ago

      I have a growing belief the advantage the advantage you're seeing is more HTML first *culture* rather than HTMX itself, I feel the same way using SvelteKit.

      For example, you submit a form with a couple extra tags on a stock HTML form, do some processing server side and swap out the form (or redirect or whatever). No overriding the on submit callback, no having to wire up a validation hook, no having to think about where things are running.

      React and angular have a very "let's solve this in JS" culture that creates ultimately unnecessary complexity demons for that 90%.

      • LegionMammal978 2 days ago

        On the other hand, I've recently been helping someone out with their messy SvelteKit website, and I've personally found the framework horrible to learn. The routing and rendering logic is all diced up between +layout.ts, +layout.svelte, +page.svelte, another +page.svelte, and a few other .ts and .svelte files scattered around lib/, to the point where I can hardly understand what data is going where, and which parts are rerendered when that data is modified. Also, prerendering has bitten me with odd discrepancies between localhost and production.

        While this messy project likely isn't the best showcase of SvelteKit, I just haven't experienced its alleged simplicity: there are too many files with special roles, and too much magic transforming things behind the scenes. I'd take React over this any day, where the components form a simple tree, and the dependencies are (often painfully) explicit instead of being swept under the rug.

        • DimmieMan 2 days ago

          You know I almost didn't mention svelte in passing to ward off this type of comment... Replace svelte and react with any framework and you can a thousand arguments of the same damn format and probably a couple in this thread, It was tangental to the point.

          One possible advantage of something like HTMX + web components I guess is splitting things into a million files all over the place that can fetch data and manage their own state is painful which seems to be how most svelte/react/whatever disasters are made.

          There's plenty of ways to make a HTMX disaster but the culture and methodologies being pushed are all leading towards simple, HTML first design which I believe might be the 'secret sauce' rather than the technology itself.

          • LegionMammal978 2 days ago

            Sorry if I sounded rather cliche. What I was trying to get at is that my #1 concern will always be data flow: if you can't easily understand what affects what else and how, then you'll end up with a huge mess of edge cases that will sink your website. And whether a framework is 'HTML-first' or not seems to be mostly orthogonal to this issue, as far as I can tell. Parts of Svelte are guilty (IMHO) of opaque data flow, and so are things like Redux built on top of React.

            That is, the way I see it, a tree is a tree, whether it's superficially written in JSX or HTMX. But of the ways to move data up and down the tree (and/or modify the tree itself), I prefer the explicitness of pure React over the magic of many of its competitors.

        • wruza 2 days ago

          I feel exactly this about everything in modern programming. It’s almost a generation thing. Files over files over files. Half of a file is imports, another half is an ad-hoc boilerplate with a single line of action code. What could be a page of code is now a folder subtree with a bunch of whatever.

          It’s like they all read some shitty book similar to that one about OO patterns.

      • troupo 2 days ago

        > No overriding the on submit callback, no having to wire up a validation hook, no having to think about where things are running.

        BTW, forms are broken in Web Components. From needing to wire them manually with Javascript via Form Data to custom submit buttons not working in forms (will be solved with another Javascript-only spec maybe in the next ten years)

  • meiraleal 3 days ago

    > In my view the only thing we should retain from the React era is JSX

    honestly lit-html is much better and based on existing browser APIs. We should make it part of the webcomponents spec! Which is a work in progress:

    https://github.com/WICG/webcomponents/issues/1069

    • troupo 2 days ago

      > lit-html is much better and based on existing browser APIs.

      Ah yes. A new framework with its own custom DSL, its own custom hook, sorry, "directive" rules, it's own incompatible flavor of SSR is definitely the way to go, and whould be a part of the standard unlike Polymer before it which was also touted as the bee's knees.

      > We should make it part of the webcomponents spec! Which is a work in progress:

      Whatever the outcome of that discussion, it won't be lit.

  • EMM_386 3 days ago

    > The current state of Front-end frameworks is an absolute mess. Speaking for myself, I don't want to learn a complex framework.

    It's really not that hard. I was able to pick up Angular to a level where I could create complex sites with it, or submit acceptable PRs that involved in, in week or so.

    Granted, I am an experienced developer (C# since beta, HTML/JS/CSS from the start) but it seemed to just make sense quickly.

    So when I was asked by a company to replace their aging, complex portal to manage critical infrastructure, I chose Angular for the front end.

    That was smooth sailing. It was stable, performant, looked good and everyone was happy.

    People often avoid it because it has a "steep learning curve" but that mainly seems to come from developers who came into the industry knowing only JavaScript and maybe a little React. If you are more experienced, you can pick it up right away.

    And it helps, a lot, to use such frameworks on large complex sites. For various reasons.

    • jeswin 3 days ago

      It's a libraries vs frameworks thing. Libraries are relatively safer.

      Frameworks in C# are slightly better (compared to those on JS), because there are blessed Frameworks and most people are using them. In the JS world, you can see very popular frameworks (with millions of downloads) get abandoned. Not saying that all is well in the .Net world; desktop frameworks are an example. But overall it's a bit different because one company more or less controls it.

    • edwinjm 2 days ago

      To be productive in Angular, you also have to know RxJS, which comes with twenty or so functions you have to become familiar with and with some peculiarities like hot and cold observables. So, no, Angular is not easy to learn.

  • mock-possum 3 days ago

    Have you tried the Lit library? Using lithtml to write web components based on Lit Component is DREAMY imo, if you’re into web components. It really reminds me of using jquery’s helper methods for ajax - like why wasn’t it just this way by default all along.

  • kccqzy 2 days ago

    For the specific point about useState, I agree about it being too magical. These days when I do write frontend code I use Reagent in Clojurescript. (I use Clojurescript partly for other reasons like its elegant syntax that's better than JSX, and built-in immutable data structures.) Its implementation of (r/atom) is a whole lot more intuitive: you can even think of it as a mutable pointer where the dereferences are tracked. On the other hand useState just feels like a hack for people who really want to avoid writing both classes and closures, and it is a roundabout way of doing things that could have been done in a much more standard and familiar way.

  • coffeefirst 3 days ago

    Yeah. I know React quite well, there are legitimate use cases where it shines, but...

    What we've lost is the ability to say "let's make a website today" and just start making UI without build tools or crazy install trees or massive libraries that need maintenance and security updates, and drop it on a server somewhere.

    I keep thinking I can have that back... ES6 imports are fully supported now, modern CSS is amazing, all we really need is an SSR/a11y-friendly way to do some kind of nestable HTML macro/component, and we can party like it's 2007 (but with grid, and import statements, and all the other new shiny objects).

    • lolinder 3 days ago

      As I'm thinking about this, the main thing that is left before I could imagine a build-free website/webapp is TypeScript support in the browser. Even just esbuild-style stripping of types would be enough, but I can't imagine bringing myself to write even a small amount of JavaScript without types any more.

      Even without that, a tiny system that just depends on tsc should be within reach at this point.

      • evilduck 3 days ago

        I wouldn’t personally make these tradeoffs but for the sake of argument if you're willing to write substantially more type info into JSDocs (AI tooling may alleviate this nowadays) you can retain most of the coverage and assurances without using anything Typescript adds to the syntax superset while still using it for type checking during development. Even without the type-heavy JSDocs you might be able to alter your coding style to lean into easing and increasing inference (more classes instead of types or interfaces) and get pretty far.

        Honestly though, I just never really run into use cases where I need to "make a page in a day" and where modern tooling gets in the way. I'm comfortable with create-react-app, NextJS, Gatsby, and a couple other things, I can definitely put a new static asset project from one of those on a VPS by shuffling files over scp in the timespan it takes to make a pot of coffee, and I would strongly prefer having those tools than trying to be "pure" for hand-wavy reasons and unproven benefit.

    • codethief 2 days ago

      > and we can party

      You go party but for a large team (or group of teams) I will still prefer the explicitness of data flow and the type safety that Angular/React/Vue/… give me.

    • stickfigure 2 days ago

      As soon as you said "SSR" you've brought in a complex build system and server infrastructure.

      But if you just want a simple web page with some javascript or even a react spa, it's not a whole lot of buttonclicks. Super easy to get deployed on something like cloudflare pages too. IMO it's easier today than it was back in the html forms era.

  • jdmg94 2 days ago

    I work with web components within a FAANG company, it was a huge mistake and everyone hates it. If your argument for web components is that they're "so intuitive you don't have to learn" then you're lying to yourself.

    • rty32 2 days ago

      The comment could be so much more helpful if it just casually mentioned what people hate web components about. Sigh.

    • cy_hauser 2 days ago

      How about Lit? I'm just looking at frameworks, components, etc. I was thinking of Lit as simplified web components? Is that valid?

  • 8n4vidtmkvmk 3 days ago

    In my admittedly little experience with shadow DOM, it doesn't isolate as much as it claims. CSS variables pierce the boundary, so if your styles are built around that, you can still run into trouble.

    I just haven't seen any benefit whatsoever once you have CSS modules. And CSS layers help too.

    • peebeebee 3 days ago

      ShadowDOM, and by extension web components are great for providing an extended set of HTML ‘native’ components. Let’s say your company has multiple frontend SPAs with different technologies (angular, react, svelte,…) they could all use the same set of company custom components, like a custom datepicker, or fancy selectbox.

      • epolanski 2 days ago

        This is the promise, but my experience tells me that web components fall short of that goal.

    • epolanski 2 days ago

      This has been a major concern for me.

      We went for a web component because we needed the same functionality on different websites using different tools.

      Issue was that we authored the web component with tailwind and then deployed the web component on different websites, some having different versions of tailwind themselves. Even minor differences in hosts tailwind versions led to quite surprising results.

      What we did in the end is to write a tool that given the tailwind classes used in the webcomponent it would then rewrite the rules at the :root of the web component's own css.

      Another reason for unhappiness came from lack of isolation regarding the units that derive from the host's base font which forced us to work in pixels directly.

      All in all, while I understand some of the decisions that went into web components, I can't lie and say that I too have few reasons to not be fully on the web components train, they fall short of the promise of author once, use everywhere.

  • qudat 2 days ago

    JSX is the worst part of react so I find that to be a pretty wild take.

    • postalrat 2 days ago

      You honestly can't think of anything worse than JSX? JSX bothers you more than all the ways useEffect gets used or the restrictions for hooks.

      • qudat 2 days ago

        The use API is very simple; JSX is a bastardized version of html that is atrocious to read and write. Just imagine all the dev time spent dealing with jsx/tsx. From IDE support to babel, typescript, etc. it is a burden on the JS/Ts ecosystem and severely contributes to fatigue.

        Yes. JSX is extremely complex to support and it is absolutely the worst part of react.

        • postalrat 15 hours ago

          So what is the alternative that solves all these perceived problems?

  • blovescoffee 3 days ago

    How does your library deal with state management and data flow? What primitives does your library offer for optimization?

    • wruza 2 days ago

      How does a regular program deal with “state management” and “data flow”?

      We all just programmed things for decades when web guys pop out with this “state management” pseudo-problem and started to invent thousands of pseudo-solutions for it.

      And why do we need “optimization”? It’s a user interface, not an accounting software core. A user types a character, you update few divs content or way under a thousand of divs’ visibility. Which optimization does that need?

      • blovescoffee 2 days ago

        First "Web guys" is such a demeaning way about talking about real and serious engineers solving real and serious engineering problems. If you don't think frontend engineering solves serious problems, I don't think your opinions about it are serious.

        All real world programs are stateful. You need some tooling and/or conventions to handle that in a clean way. I recommend this blog post about React Query that talks about some challenges and solutions on the frontend for state management: https://ui.dev/why-react-query

        You're questioning the importance of optimization on a website for hackers/tinkerers/engineers?

        You need optimization for page speed, SEO, animation, elegance, pushing the boundaries...

        edit to address: "Which optimization does that need?"

        Optimistic updates, debouncing, handling large responses, cache, etc. etc.

        • wruza a day ago

          Can you recommend a blog post about “state management” in non-frontend? E.g. some server or maybe a desktop app like e.g. your backup manager. Because my whole premise is that the “problem” is self-imposed, which react is literally the part of.

          If you don't think frontend engineering solves serious problems, I don't think your opinions about it are serious.

          I don’t think “frontend” is at all serious, because I have developed user-facing systems since around 2000, and “frontend” (which we called gui controls back in the day) was never a biggest story, when it was worth telling at all. Mostly complex distributed accounting software with various integrations at all levels. I’m not afraid of appeals to serious engineers with serious problems, cause I am one of them and can question it freely.

          If I appear somewhat toxic, that simply reflects the toxic positivity about the absurd state of things in web dev. It is a collective delusion which suddenly disappears when people get forced out if it, by e.g. going htmx route. Not advocating for htmx specifically, it just happens to be a perfect litmus test. Same for php, people still use it outside of “frontend” bubble and don’t know that “managing” their “state” is a hard problem that requires tens of versions of the best framework of the month.

          • Izkata a day ago

            > Can you recommend a blog post about “state management” in non-frontend? E.g. some server or maybe a desktop app like e.g. your backup manager. Because my whole premise is that the “problem” is self-imposed, which react is literally the part of.

            It's largely unnecessary there because those can talk directly to the database and use it as their data store without a large performance penalty. Plenty of server-based systems like PHP don't even have persistent state to manage, whatever wasn't stored in the database is discarded when the response is sent.

            > It is a collective delusion which suddenly disappears when people get forced out if it, by e.g. going htmx route.

            There is a performance penalty here where every state change is a web request. That's a large part of where frontend state management libraries began, with Backbone providing objects that would be synced with database tables and acted like a local cache.

      • papichulo2023 2 days ago

        Old way was storing data in sessions or hidden html inputs. Both way worse than modern alternatives. You kinda sound like you have no idea what you are talking about. Having to render thousands of elements is not uncommon.

  • azangru 3 days ago

    > In my view the only thing we should retain from the React era is JSX

    How do you deal with the non-existing difference between attributes and properties in JSX? Is every attribute a property and vice versa? Do properties reflect back as attributes?

    • edwinjm 2 days ago

      In Lit, a web component framework, you can set properties with, for example, href=... and you can set attributes with .href=...

      This can be taken over to JSX.

      • azangru a day ago

        > In Lit, a web component framework, you can set properties with, for example, href=... and you can set attributes with .href=...

        Only it's the other way around.

    • nsonha 3 days ago

      jsx is just a syntax to construct elements with attributes. You can still add properties like you do in a web component. In React you mostly never deal with instances (and properties) but that doesn't mean other ways to model components utilizing jsx cannot.

      • azangru 3 days ago

        Jsx uses properties, not attributes, while pretending that it uses attributes. Html attributes are strings, whereas jsx allows you to pass different data types to child components. Thus, properties. Which is also why is uses camel-cased names, or insists on className. Because these are the names of HTMLElement's properties.

        • WorldMaker 2 days ago

          Those are React optimizations/restrictions, not JSX restrictions. They want to make diff/patch as fast/simple as possible and rely on properties to do that as much as possible. `className` might have been a restriction in early JSX parsers trying to avoid keyword clashes, but every current JSX parser (especially Typescript) has no problems with JS keywords embedded in JSX. (I don't think it actually was a restriction at any point, but early JSX parsers might have been conservative in how they wanted to parse given the fate of E4X.)

          Snabbdom [1] takes an approach of explicitly separating `props` and `attrs` at the expense of extra verbosity in the JSX `<span props={{ className: 'example' }} attrs={{ 'aria-label': 'Example'>Example</span>`. My Butterfloat [2] uses simple heuristics, starting with the props because you can conditionally type a ton of JS type data (and MDN link comments) out of TS DOM types for a strong autocomplete experience, adding common important-to-HTML copy/paste shortcuts such as `class` and `for` and switching to attributes if an XML namespace seems to be in use or the name includes a `-` and seems to be qebab-cased rather than camel-cased.

          [1] https://github.com/snabbdom/snabbdom?tab=readme-ov-file#jsx

          [2] https://worldmaker.net/butterfloat/

        • rschristian 8 hours ago

          Every JSX implementation uses a mix of setting props & attributes, depending on the specific label, as the DOM can be a bit weird with how some things reflect. Generally properties are preferable to attributes, however.

        • nsonha 3 days ago

          that's React's implementation, we are talking what it would be if not React. IMO the semantic is similar to attribute, example:

          let element = <my-thing my-attribute={value} />

          element.property = prop

  • Narhem 3 days ago

    If you use web components enough you realize why tools like useState exists then you have to bring in another library like alpine to offer the functionality.

    The whole point of web components is the ability to offer class encapsulation within the browser without anything other than a file server.

    JSX has much nicer syntax but I’d rather not have to deal with the overhead of launching a node server. Makes developing time quicker when working with smaller codebases.

  • sandreas 3 days ago

    Well, there is a project to convert react components to native ones[1]... this way you can write react and use it everywhere. I think this is the way to go, similar to svelte's approach. Write what you want but compile it to native standards.

    1: https://github.com/bitovi/react-to-web-component

  • deliriumchn 2 days ago

    > I don't want to learn a complex framework. I don't want to learn magic that I don't understand without reading the documentation (useState, createSignal et al)

    I'm always suprised reading statements like that. No offence, but maybe you're in wrong career if you don't want to learn how most popular and important tools of today work... Not to mention that its so simple you can learn everything required to be efficient during lunch break

    • lelanthran 2 days ago

      > I'm always suprised reading statements like that. No offence, but maybe you're in wrong career if you don't want to learn how most popular and important tools of today work... Not to mention that its so simple you can learn everything required to be efficient during lunch break

      This is such a common comment that I am never surprised to see it pop up whenever the "front-end mess" discussion arises.

      No, you cannot learn React over a lunch break. You cannot learn Angular and Vue over a lunch break.

      I am skeptical that even you, personally, can learn just the footguns alone present in the hundreds of thousands of lines of code in a specific $FRAMEWORK over one lunch break, two lunch breaks or even a dozen lunch breaks.

      All those thousands of lines of code implement something, and I will wager a month of my income against a month of your income that you will not learn more than 3 or 4 concepts over a single lunch break, because they all have multiple concepts, multiple use-cases, multiple exceptions-to-the-general-rule and multiple footguns without even including the edge-cases they solve.

      You will spend several years of lunch breaks, unless you consider reading the wikipedia overview for each $FRAMEWORK to be "learning the $FRAMEWORK".

      Web components, OTOH, have less functionality than full-blow $FRAMEWORKS, but each can be individually learned over a lunch break, reused by non-JS-developers and is a knowledge base that is more or less future-proof.

      • watwut 2 days ago

        React is particularly easy to learn tho, much easier then angular.

        What you definitely can not learn over lunch breakis whatever local developers created as a local ad-hoc framework. Those area always more time consuming to work with, because you have no internet, stack overflow or documentation to help you.

  • wslh 3 days ago

    > I don't want to learn a complex framework.

    Completely agree. As a casual programmer, I just want something simple, inspired in VB6.

  • jrochkind1 3 days ago

    You implied but didn't say explicitly, are you doing your front-end development with web components now personally?

  • gspencley 2 days ago

    > In my view the only thing we should retain from the React era is JSX (for many reasons, true type-safety, autocomplete etc)

    Warning: opinion incoming.

    JSX is one of two reasons that I never liked React at all and wish it would go away.

    I've been developing "web applications" since the latter half of the 90s. I've worked with everything from an in-house built dynamic template language (very similar to what PHP did in the early days) developed in C++ and served using CGI in Apache, to developing with PHP to Java Spring MVC to Django to modern frontend frameworks including both React and Angular.

    JSX reminds me of what PHP was like in the 90s and early 00s. People adopted it widely because the barrier to entry was extremely low. We had all of these static HTML websites and "developers" could just go in and start adding control flow to those documents in order to add dynamic functionality. It was easy ... and it quickly turned into a complete mess so big that PHP ended up with a reputation as being a toy language that "serious programmers" wouldn't be caught dead touching. That reputation was a bit unfair but also kind of earned.

    With the rise of PHP's popularity, the PHP "community" itself came to realize that they had a decent turing-complete programming language that they were working with, but that this idea of mixing business logic within HTML documents was a massive anti-pattern. It's ironic that what began its journey as a template language eventually realized that the best thing for the language was to stop using it as a template language, and to adopt different template languages such as Smarty in order to promote a separation of concerns between view / presentation concerns and business logic.

    React was never created as a "framework." There are actual frameworks that are starting to come out that use React for its view layer, such as NextJS, but React itself is just a library that allows you to create custom components and then choose your adventure when it comes to what other libraries you want to mix and match. But because people reach for React to start throwing together dynamic frontends quickly, everything is compononent-first. So it actively encourages you to put business and integration concerns in what really ought to be your view / presentation "layer."

    And JSX magnifies that problem by just being JavaScript. So, again, it's PHP all over again. You've got a very powerful turing-complete programming language that you intersperse with your markup and you get messes. Even in the most well-written, concern-separated React projects I still see a lot of "ugliness" that comes through with JSX.

    I did mention that it was one of two reasons I'm not a fan of React, the other is that - again because it was only conceived of as a component / view library - there is no inbuilt view encapsulation / scoped styles. This problem is somewhat mitigated by CSS modules these days. But view encapsulation is something that I've always seen as Angular's killer feature - the ability to just style your tags directly and create component markup that is completely devoid of class="" attributes. Angular and VueJS actually trained me to hate 99% of class="" attributes and to think of them as a type of code smell... just because it is possible to create higher-level components that don't have any at all but still styling when needed.

    • stickfigure 2 days ago

      Separating components is more important than separating presentation and business logic, and React/JSX excels at that. Old style MVC and templating frameworks that promised clean presentation/business separation ended up with two giant muddled piles of disorganized code. Components gave us a better organizational structure for complicated UIs, and that's why that form of separation won out.

      If you have nice clean modular components, it doesn't matter too much where the code vs template boundaries are inside. They shouldn't be so complex that it matters. This is why I like JSX - for any given component, everything is in one place.

      • gspencley 18 hours ago

        > and that's why that form of separation won out.

        React won out because it has a low barrier to entry and is very unopinionated. That's not a bad thing. But don't pretend for a second that it won out as any kind of industry standard because it was technologically superior or was a better designed "framework" (again, it's not and never was a framework, it's a view library for creating components).

        There are 3 broad concerns when it comes to programming for the virtual machine that we call the web browser:

        - Semantic demarcation, which is what markup does: this is a paragraph, this is a header, this is card etc.

        - Visual decoration and styling, what CSS does. This is how a paragraph looks, this is how a card looks etc.

        - Interactivity and control flow: what JavaScript does. When the user clicks the button this is what happens.

        Those are all distinct responsibilities which the browser handles separately natively.

        We don't need to even start talking about MVC or OOP design patterns when talking about spearating your concerns. That's a basic engineering concept of isolating your moving parts to keep things simpler and allow you to change things in isolation without acccidentally breaking something else, which is the bane of software maintenance.

        The notion that diluting separation of concerns is a design innovation that makes software development and maintenance somehow easier is truly baffling.

    • imtringued 2 days ago

      Some of us need to get work done and not worry about the XSS potential that inline styles represent so we set our CSP to block all inline JavaScript and CSS.

      Btw I'm sorry if I misunderstood what you're trying to say, because you're mostly dissing the class attribute which I very much depend on purely to keep my websites secure.

      • gspencley 18 hours ago

        Yup you misunderstood. I would be just as much opposed to inline styles as using class="" attributes.

        With frameworks like Angular, you can create a component and bind CSS styling to that component in a way that you can select just your HTML tags directly ... like style div {} instead of styling .my-card {} etc. And those styles are not "global", they are scoped to only those elements that are referenced in your component's markup.

        There are two ways that this can be implemented and frameworks often let you choose which one you want to employ: Shadow DOM or emulation. With emulation, the classes and selectors get generated for you at compile time so if you inspect the DOM you'll see tons of class="" attributes that were auto-generated ... but the developer never had to write them or think about them.

        The result is code that is so much nicer to read and work with.

  • jaredklewis 3 days ago

    > I never had to guess what "useState" does behind the scenes.

    It's weird to me that React hooks are always dragged out in these arguments as some kind of bogeyman. If you understand the idea of a virtual DOM and a render loop, then it is only a tiny step from there to understand hooks. And you can understand all of these concepts in about 15 minutes: https://www.youtube.com/watch?v=1VVfMVQabx0

    I just don't get all the hand wringing regarding frontend frameworks. I've been using React since 2014 and in 10 years, there has been exactly one big change to the framework: hooks. When they came out, I spent 15 minutes to understand them. It didn't kill me.

    And React has been undisputed king the frontend frameworks hill for at least 9 years, but people still act like it's some sort of ever-changing, confusing landscape of options. If you want boring, stable front-end development, choose a super popular, well documented tool like React. Or if you don't like frameworks, use vanilla JS. It's not a crisis.

    • edwinjm 2 days ago

      "This framework feels very natural to me" says person using the framework for ten years.

      • watwut 2 days ago

        I came back to react around a year ago, hooks were completely new to me and pretty instantly understandable. They are just not difficult to comprehend or use.

    • ForHackernews 2 days ago

      > If you understand the idea of a virtual DOM and a render loop, then it is only a tiny step from there to understand hooks

      Once you understand the arcana of the magisterium, it becomes obvious why the encyclicals must be unitarian!

apitman 3 days ago

I think part of the reason people talk past each other on this issue is because they're optimizing for different things. If you're working for a VC-backed startup with a central product that needs to move quickly and is going to require constant maintenance anyway, a framework might be a good fit for you.

But I work in an academic lab. We don't have tons of money to maintain the apps that we've written. We need them to just keep working once funding has moved on to new projects.

We're just finishing up a rewrite of an app from Vue to Web Components. It had dependency rotted to the point where we couldn't update anything because of dependency hell. Rather than spend hours trying to fix it, which we've done before and would have to do again until the end of time, I decided to experiment with Web Components. The experience was immediately so nice that we went all in. No regrets. We went from ~15 dependencies to ~1 (d3js).

If you're curious to try the apps, old one[0] new one[1].

[0]: https://bam.iobio.io/

[1]: https://bam2.iobio.io/

  • Jcampuzano2 3 days ago

    Sometimes I don't understand this argument because theres nobody forcing you to always be on the latest version of a framework. You could have just stayed on the version of Vue you were using without issues. Unless theres some compelling reason you could use it into the end of time and be just fine.

    Thats not to say that maybe for your use case you could have not used it in the first place or that removing the dependency was a bad idea - just that if you do like Vue there doesn't seem to be anything forcing you to always be on the latest version.

    • Joeri 2 days ago

      A particular framework version usually depends on a particular version of build tools, and those are written to a particular release of an OS. When apple updates Xcode the compiled npm packages often have to update support as well, and the old versions of those packages start breaking on new OS releases. You can’t ship a web app that you can’t build.

      An often used hack is containerizing the dev setup to decouple from OS versions, but that comes with its own set of downsides.

    • WD-42 3 days ago

      What happens when old versions stop receiving security updates?

      • pilif 2 days ago

        And not just that - also dependencies of dependencies.

        You have $FRAMEWORK using $BUILD_SYSTEM and depending on $NODE_VERSION which is running on $OS_VERSION in $ARCHITECTURE.

        Eventually, there will be a security flaw in $OS_VERSION which will force you do update the OS (which eventually will be a major OS update) and on which $NODE_VERSION might not run any more at which point you find out that $BUILD_SYSTEM doesn't run on newer node any more because it relied on a package that shipped some binary do do its thing and the source code of that binary doesn't compile on later GCC versions any more.

        And now you're in deep-shit because of a very distant but yet super important security issue that brought your house of cards crumbling down.

        This is not a theoretical issue either. I've seen this happen to applications with a JS frontend that was only as little as 5 years old. It was impossible to build any more and needed some serious changes because of underlying OS updates cascading up the stack.

        The fewer dependencies you have and the smaller they are, the bigger is the chance that things keep running as you exchange parts of your stack when you're forced to and the bigger the chance that you will remember what you have to do to rebuild if disaster strikes.

        I'm aware that for many people 5 years is a huge time span though and that you either start a new thing every year or two at which point none of this matters, or you're at the other extreme and run RHEL and are able to back-port security patches manually if the need arises at which point none of this matters either.

        But if you're in the middle of the two extremes, then keeping up to date incrementally is super important and being able to do that quickly and easily is inversely proportional to the amount and size of dependencies.

        • zelphirkalt 2 days ago

          One frequent situation is, that companies are not aware of how bad this can get and their frontend devs have a resume/hype driven thing going on, building it in the new tool, leaving after a few years for greener pastures, leaving behing a ticking time bomb for someone else to deal with. Not so many people stay at the same job 5y+ these days. Companies don't know how to keep their talent and engineers are forces to switch jobs every now and then to keep or improve their salaries.

      • Jcampuzano2 3 days ago

        Rarely do security issues come from directly as a result of your choice of frontend/client framework which should really only be in charge of displaying your data. Almost all issues should be handled by your backend.

        Most cases where it becomes an issue is when people drop security best practices falsely believing their frontend/client validation is a security layer.

        Anybody thinking updating your frontend solves your security issues has deeper problems.

        • wavemode 3 days ago

          Doesn't matter, a security update is a security update. So, especially when you work in a larger company, you end up having strict compliance requirements to keep things up to date.

          I'm as annoyed by it as the next guy. The supposed vulnerabilities are almost never actually relevant for frontend code, and rather assume that you are running Node as a web server.

          It's just one of those weird things that has resulted from how the JavaScript ecosystem has centralized around using node for everything (i.e. building frontend code as well as executing backend code - even though the two have kind of nothing to do with each other.)

          • jamesfinlayson 2 days ago

            Yep, I've been in a big company with a dedicated security team and it was easier to just patch the dependency than to try and argue that we weren't vulnerable (otherwise it would probably go on some risk register and be re-raised again in a few months time).

        • WD-42 3 days ago

          > Rarely do security issues come from directly as a result of your choice of frontend/client framework

          Front end client frameworks now span the backend. Nextjs is the prime example. It has plenty of CVEs already.

          • Jcampuzano2 3 days ago

            Well next is not a frontend framework and doesn't claim to be. Its very clearly a full stack framework. Vue by itself isn't.

            • regularfry 2 days ago

              Can you server-side render Vue? If you answer "yes" then it has exactly the same type of back-end security concerns that Next has by way of it rendering React.

        • zelphirkalt 2 days ago

          About having other problems, I think you are right. However, often it is the frontend engineers pushing for using more frontend frameworks on the server side as well, and then implementing business logic there, not merely presentation, using arguments like "then we can have a mono repo for all the things and have type checks for frontend and backend" or "all in on language!" and suddenly you got into that situation.

      • ImHereToVote 2 days ago

        May God have mercy on your soul if you rely on your frontend for security. You might as well duct tape a shotgun to your scull.

  • jitl 3 days ago

    If you can rewrite to remove all dependencies except for d3js, why couldn’t you do the same thing, but also retain a dependency on Vue? What is it about Vue that requires the extra dependencies - is it built system things? (I’ve never used Vue)

    • apitman 3 days ago

      Vue itself must be updated. And if you throw out the router, Vuetify, state management, etc, what is it adding above Web Components anyway?

      • athanagor2 2 days ago

        As far as I know there's no simple and performant way to have the DOM be a function of the state with existing standards

        • apitman 2 days ago

          I design my web components so they emit custom events and provide methods for parents to mutate them/trigger re-renders. This might not scale to huge apps but I don't have any interest in working on something like that.

        • hasanhaja 2 days ago

          What do you mean specifically when you say?

          > DOM be a function of the state

          I understand the benefits of the mental model, but the tooling that delivers that generally have a lot of complexity that isn't trivial to parse and understand. I think the benefit of being able to parse and understand your abstractions (ones you build yourselves or buy off the shelf like a framework) is there are always gaps in the constraints under which they had originally been designed; so you'll always need to understand how it works under the hood.

          React's class-based components were simpler because the lifecycle methods were explicit, but the hook-based model is "easier"; however, the component lifecycle is still present. The demo code does look really clean, but in real life you quickly start to face the underlying complexity of the abstractions (e.g., useEffect, memoization, realizing how fine-grained your reactivity is is based on how you've drawn those component boundaries). You can write these optimizations yourself, or wait for the new auto-memoizing React compiler to land, but in all cases, the overall complexity remains the same (or is higher). And this isn't unique to React or other frameworks, and you'll always need to delve a little deeper.

          I agree that the DOM APIs could be more declarative (e.g., declarative custom elements proposal [1], declarative shadow DOM, `@scope` CSS as another way to scope styles), and there is activity in that space, both in the W3 Web Components Community Group and the Open UI Community Group. I'm trying to get more involved in those discussions and I'd recommend everyone who cares about the web and how we build for it to participate.

          I think the process of standardization for new features (through the proposals phases to finally landing in browsers) is the effort to raise the floor for all to build on top of. I remember when Promises were landing everywhere and feeling a little overwhelmed by what it meant to me because I was using Bluebird. Then the feeling of "maybe I can simplify what I'm doing and lean more on the platform" set in. Frameworks are a testbed for new ideas, and we can go further by trying to see what pieces we can pull out and standardize around (e.g., Signals proposal [2]), so we can go back to testing new ideas on top of that.

          [1] https://github.com/WICG/webcomponents/blob/gh-pages/proposal... [2] https://github.com/tc39/proposal-signals

      • haradion 2 days ago

        Especially with Vue 3, most of the reactive state management you need for all but the largest and most complex of apps is built right into the core. Vuex and Pinia really aren't necessary for most users.

  • wg0 2 days ago

    I'd argue that if you get the hang of it, development in Web components won't be slower than in any frameworks.

    So I don't understand why VC ecosystem can't get by without frameworks.

  • troupo 2 days ago

    I doubt you're authoring all web components by hand. I doubt you're not using any external dependencies.

    • apitman 2 days ago

      We're not even using lit. Feel free to check out the code[0]. It's not the best (we're still learning web components) but it's working pretty well for us so far.

      [0]: https://github.com/iobio/bam.iobio

      • troupo 2 days ago

        Thanks! I'll take a look

        • troupo a day ago

          That's quite a commitment to write "naked" web components by hand.

          Kudos on keeping external deps to an absolute minimum

          • apitman 16 hours ago

            They're not perfect. In particular accessibility probably isn't very good. But that hasn't been as high a priority since it's a dataviz app anyway.

    • zelphirkalt 2 days ago

      It would be good to tell us, why you doubt the GP in that regard.

      • troupo 2 days ago

        Because authoring web components is pain.

        Because browser APIs and elements are quite limited so you're likely to pull in external deps tht provide better interfaces etc.

mentalgear 3 days ago

One of the things I really appreciate about Svelte is its support for generating Web Components through the Custom Elements API. Since Svelte compiles down to plain JS/HTML/CSS, creating reusable components that work across any framework or vanilla JS becomes seamless. https://svelte.dev/docs/custom-elements-api

MrThoughtful 3 days ago

I have been following the web components discussion for years now and just don't see what I can do with them that makes my life as a fullstack developer better.

All the examples I have seen use them to template some data into html. I can do that with handlebars already.

Am I missing someting?

  • traverseda 3 days ago

    There are two models of the "web", where HTML is a document and where HTML is the scenegraph of a more complicated app.

    If you're using HTML as a document you can use web-components to include fancier interactive real-time feature

    * A terminal emulator web component that attaches to a websocket * A date picker web component, add features like checking if a date is already taken * Custom form elements in general, a search-box that takes a URL for auto-completion suggestions * A map, but not a full mapping application * A data table, like the jquery plugin of old * Lightweight interactivity like tab widgets * Basically any of the custom components that jquery-ui provided

    Yes you can do all of these without webcomponents, but the HTML is a lot cleaner and a lot more document like if it's a custom component. Mixing the model and scenegraph views of the web is not my favorite. It sure would be nice if there was a consistent library of web components available.

    You can actually do pretty decent live-chat with something like HTMX and server-sent-events, I think. But it's sort of a progressive-enhancement view of HTML as a document model.

  • tomxor 3 days ago

    Full native isolation. HTML, CSS, JS, the whole thing, no tricks, the browser isolates it for you. It's really nice to be able to make a web component, clearly define the JS, HTML and even CSS API in terms of variables, and then throw it into any environment without it breaking, or without creating a complex maze of CSS name spaces and framework dependencies.

    • MrThoughtful 3 days ago

      Is there really ever a use case for that?

      When do you want part of your page to have different fonts, colors, everything from the rest of the page?

      • skrebbel 3 days ago

        We ran into this too, and ended up not using the Shadow DOM at all. We want our stuff to automatically use the page's fonts, sizes, colors etc. Also we want customers to be able to customize stuff with CSS without having to use JS hacks to inject CSS into the shadow DOM (this gets especially cumbersome when you're nesting web components). Personally I feel like the shadow DOM is the most oversold part of web components, in that it's so all-or-nothing that it often creates more problems than it solves.

        • mock-possum 3 days ago

          Which is another thing I love about web components - if you don’t want shadow dom, then don’t use it - you can build using just custom elements.

          • skrebbel 2 days ago

            True, but i wish there was a way to say "don't inherit anything here except fonts and colors".

            Being able to make a new root for rems would be nice too.

            • hmcdona1 2 days ago

              The Shadow DOM does exactly what you are asking for here. Just use CSS variables, they pierce right through:

              https://open-wc.org/guides/knowledge/styling/styles-piercing...

              • skrebbel 2 days ago

                yeah so this means that if i want to use a page's font family but not its font size, the user has to do extra effort, and set not just `font-family: "Comic Sans"`, but also `--some-component-font-family: "Comic Sans"`. i'd love it if i could just selectively inherit stuff and not other stuff, without the user having to learn which css variables my thing supports. of course you can't do this with domain specific stuff, but you could make a thing fit kinda sorta well into its environment by default, and right now using a shadow DOM doesn't let you do that.

      • rty32 3 days ago

        It is not a choice in many situations. For a large company that has many different teams that own many different parts of a product, even though teams adhere to the same "UI standards", things get complicated quickly. For example, CSS classes that have name conflict can cause UI to break (which happens more often than you think, and strictly adhering to naming rules is just hard for humans). That's just one example. Custom elements with shadow DOM is a simple and straightforward solution to this, and it makes sense -- JavaScript code are scoped to modules and use imports/exports to define interfaces, and it is just natural to do that for UI instead of putting every class that other people don't care about in the global CSS space.

      • pradn 3 days ago

        The use-case for having isolated objects with parameters, much like classes in Java, is to be able to a) share code, b) hide internal details, and c) have object behavior be governed solely by a constrained set of inputs.

        So the point isn't to have your web component be different from the rest of the page. The point is that you can pass in parameters to make an off-the-shelf component look how you want. However, exactly how much freedom you want to give users is up to the component author. It is possible for there to be too little freedom, true.

        See here [1] for a concrete example of someone writing a reusable web component, and figuring out how to let users customize the styling.

        [1]: https://nolanlawson.com/2021/01/03/options-for-styling-web-c...

      • eyelidlessness 3 days ago

        In terms of style isolation, the answer is very much “it depends”. And it depends as much on the nature of what the component does, as the kind of isolation you want to achieve.

        - Namespace isolation. Example: you have different components in the same codebase or otherwise meant to work together; you may want assurance that a locally defined style attached to class “foo” doesn’t have unexpected effects on other components which happen to use the same class a different way. This is commonly achieved with build tooling, eg by mangling class names.

        - Cascade isolation. Example: you have an embeddable widget that you want to look consistent in any context, regardless of the styles of its parent DOM. This is achievable to some extent without custom elements, but they are a way to achieve it with confidence in a relatively straightforward way (at the expense of other limitations and complexity).

      • gedy 3 days ago

        This 100%. Web components get praised for this isolation - and it’s like the exact thing I do not want if I’m building an application. Like try to have a global CSS theme, or use bootstrap, etc. (Please don’t suggest I embed a link to global CSS in every component.)

        Like I get it if you’re sharing a component on different sites, like an embedded component or ad banner, etc. But it just gets in the way if you’re trying to do normal things that the majority of web apps need.

        • HumanOstrich 3 days ago

          There are ways to apply global styles to your components other than importing a global sheet. There's just not a standard way defined in the spec. Isolation by default is the correct path for them to take compared to the alternatives. That doesn't make it useless just because you don't know how to do it in a good way.

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

          • gedy 3 days ago

            My main point is that gets in the way, unlike most other web frameworks when building normal applications. It's a headwind that always comes up and hurts adoption imho.

      • mixmastamyk 2 days ago

        From reading the parent site the use cases seem to be large enterprise and cross site components, say a twitter embed or advertising bar.

    • ThatMedicIsASpy 2 days ago

      It is my personal nightmare. I want to write custom css to customize my Homeassistant. Only to find out every single thing is in a shadow root and I cannot write css to adress what I want to change. WHICH WOULD BE REALLY SIMPLE IF I CAN WRITE PLAIN OLD CSS.

      I can't believe how extremely mad and frustraded I became when I found out - writing this out fills me with rage.

    • SahAssar 2 days ago

      Web components don't do any JS isolation, right? And when you say HTML isolation I think its probably important to say that any custom element registered is global, so if Web-Component-A uses Web-Component-B version 1 then Web-Component-C cant use Web-Component-B version 2 (unless Web-Component-B includes the version in its name).

      If you want actual isolation of the whole web stack (HTML/CSS/JS) I don't think there are any alternatives to iframes.

  • deergomoo 3 days ago

    They are very good for progressive enhancement, for example you could have a web component that wraps a <table> to add fancy features like filtering or drag-and-drop reordering. If JS is disabled or fails to load, the user just gets a plain table, but they still get the content. When this stuff was new, that was much better for the user than what would happen with a front-end framework (they would get a white page), but now server-side rendering is widely available in those frameworks it’s less of a selling point.

    They are also good for style encapsulation, i.e. you could drop someone else’s component in your page and not worry about it affecting or being affected by your CSS. Anecdotally I feel like that is less of a common desire now than it was ~10 years ago, with the rise of both “headless” UI libraries (behaviour without dictating appearance) and the prevalence of scoped styles in front-end frameworks.

    What does annoy me about the standard is that to use slots you must opt into the shadow DOM, which means that if you’re trying to create reusable components for your own stuff, you can’t style them just by dropping a stylesheet into the page. I’m sure there’s a technical reason why this is the case, but annoying nonetheless.

  • jhp123 3 days ago

    the examples probably avoid talking about the dynamic APIs because they are super ugly and very stateful. It's hard to say that Web Components are the future when your demo shows 200 lines of manual DOM reconciliation.

    • j-krieger 3 days ago

      I‘ve come to the same conclusion while using them pretty extensively. The idea is nice, but they are not there yet.

      • microflash 3 days ago

        Sure, there is some pain but after years of several Angular and a Vue migration, I'd say that pain is much less than the pain of framework migration. People often overlook the experience of a framework for a long term use.

      • vinnymac 3 days ago

        This could summarize every interaction I’ve had with Web Components since the beginning. Web Components are becoming the Nuclear Fusion of Web standards.

        • j-krieger 2 days ago

          Only 10 more years or so, pinky promise ;)

  • skrebbel 3 days ago

    Web Components let you use a UI component made in a different framework than yours. That's it. For most other purposes they're pretty awful.

    Also they let you publish a UI component that works in every framework, without having to build 7 versions of it (or just exclude everyone who's not on React, or something like that)

    • BostonFern 3 days ago

      That’s also the conclusion I’ve drawn. This seems to be the reason Web Components exists.

  • mejutoco 3 days ago

    IMO the slots that allow a component to have children are the difference. You can compose indepent components that way. Also the styles are scoped to the component by default, and you can only break the scope with custom vars (css vars)

  • Cthulhu_ 2 days ago

    Web components are a standard and built into the browser, Handlebars is a separate library. Web components are a way to encapsulate and isolate structure (html), appearance (css) and behaviour (js) into components, extending HTML.

    It's like jquery widgets but without dependencies.

  • someothherguyy 3 days ago

    Are you genuinely asking as a professional? Seems like a big ask for someone to go over all you are misunderstanding if you think they are equivalent to a template language.

    • PaulHoule 3 days ago

      The standard, like PWA, is designed for maximum feasible misunderstanding. To the average dev it seems like a random bunch of features that don’t hang together. Five developers could look at it and be like the blind men discussing the elephant —- hung up on individual parts and not seeing the whole, if there is a whole.

      There are a lot of candidates for “what’s wrong with modern web standards” but this fragmentation, which comes from a rather mathematical view of programming, is one of them. Thing is, a lot of web devs never studied computer science (even CS 101) and less than 5% live in San Francisco.

      • Capricorn2481 3 days ago

        > and less than 5% live in San Francisco

        How will they ever understand web components.

    • tome 3 days ago

      On the other hand, if they're completely different from a template language it seems like it should be just a moments work to demonstrate why, and help a fellow professional understand what they're missing.

      • EGreg 3 days ago

        Well um

        1) You dont have to load an external library

        2) Shadow DOM

        3) Dynamic slots

        That’s about it, honestly LOL.

        I guess the main point of most browser APIs was to let apps use browser features.

        This one actually tried to make a standard way for apps to use other apps. But they already had their own libraries so nyeh, thank you very much! LOL

        • antifa 2 days ago

          Now I'm curious, what template engines don't have dynamic slots? Is that actually a rare enough feature to declare webcomponents special for having it? Does webcomponents have an advanced version of it?

lapcat 3 days ago

The worst part about web components and the shadow DOM is how they can prevent browser extensions from working correctly, or working at all.

And the browser vendors aren't in a hurry to remedy this situation.

  • 0x1ceb00da 2 days ago

    This. User agent configurability is the killer feature of web.

webdevladder 3 days ago

I think this minimizes the fact that interop - the main selling point to me as a user - comes at a performance cost where every component you use could have its own unnecessary runtime attached.[1] Using a framework like Lit with web components is the recommended way to use them.

This cost will compound over time where new frameworks emerge, and components get stuck on older versions of their frameworks.

I can't see this as anything but significant, and not to be minimized. Having multiple redundant libraries on a page is not the direction I would advise anyone to take, particularly not when baked into the accepted best practices. This bodes poorly in the long term.

I've listened to the arguments from web component advocates in blog posts, social media, and videos for years now, and I should be in the target market. But on top of the interop tax, they're full of negatives that aren't present in the mainstream frameworks.

Interop works great within each framework's ecosystem. The same dynamics that cause developers to seek interop cause them to huddle around a small number of mainstream frameworks. So we get a few vibrant ecosystems that push the state of the art together. Web components cannot keep up on the tech side of things, and introduce a ton of complexity to the web platform - ignorable to me as a dev, but not for browser implementers - in service of their early 2010s designs.

[1] https://x.com/Rich_Harris/status/1840116730716119356

  • nolanl 3 days ago

    I cover this in another post [1], but broadly:

    - Not every web app is perf-sensitive to every extra kB (eCommerce is, productivity tools typically aren't)

    - Plenty of frameworks have tiny runtimes, e.g. Svelte is 2.7kB [2]

    - I wouldn't advocate for 100 different frameworks on the page, but let's say 5-6 would be fine IMO

    No one is arguing that this is ideal, but sometimes this model can help, e.g. for gradual migrations or micro-frontends.

    BTW React 17 actually introduced a feature where you could do exactly this: have multiple versions of React on the same page [3].

    [1]: https://nolanlawson.com/2021/08/01/why-its-okay-for-web-comp...

    [2]: https://bundlephobia.com/package/svelte@4.2.19

    [3]: https://legacy.reactjs.org/blog/2020/10/20/react-v17.html

  • afavour 3 days ago

    While this is true I think the multiple libraries problem is a rounding error when you look at the majority of web apps created today. React and react-dom combined are over 100KB. Svelte and Lit are in the single digits. So you could embed a lot of frameworks before you get close to the bloat people use every single day without even thinking about it.

    • webdevladder 3 days ago

      As a Svelte user this argument rings hollow. You can't judge frontend by React and the way it's badly used.

      • afavour 3 days ago

        > You can't judge frontend by React and the way it's badly used.

        IMO you can because it’s the vast majority of webapp usage today. I’m also a heavy Svelte user and I love it but front end web dev is practically a React monoculture so it makes sense to think about it when evaluating options.

        I’m not saying it isn’t a problem inherent in web components, it is. But using it as a reason to not adopt web components runs contrary to the logic the vast majority of the industry currently uses. Perfect as the enemy of good and all that.

        • webdevladder 3 days ago

          React is irrelevant for me and my users. This is not an argument in favor of web components over Svelte. Adopting web components would mean an objectively worse UX for my users - for example requiring them to enable JS.

          You won't get a Svelte to look past the flaws of web components by saying "React is bad".

          • afavour 3 days ago

            Yes, you’re talking about you and your users. I’m talking about the industry at large. Those two perspectives don’t have to line up.

            The article we’re discussing is titled “Web Components are okay”, not “Web Components are better than Svelte for webdevladder and their users”.

            • webdevladder 3 days ago

              Look at the thread you've created here - I'm arguing that the article minimizes the antipattern cost they impose, and your response brings up React as if it somehow changes that.

              • afavour 3 days ago

                Yes, I previously mentioned the “perfect as the enemy of good” argument.

                Like I already said, I use and like Svelte. But the vast majority of the web dev ecosystem uses React. Web components would be better than everyone using React. Arguably everyone using Svelte could be better still but that’s a separate debate.

                > your response brings up React as if it somehow changes that.

                It does. Because the industry clearly has no problem with a large upfront cost, given that it imposes one today. Web components would be better than what we have today even if it isn’t the ideal.

      • azemetre 3 days ago

        You absolutely can judge tools by how they are used, especially if said tool encourages poor usage.

        • throwawayha 3 days ago

          Except, any beginner can make a mess with anything. Methodologies and frameworks evolve, but not all create any for beginners.

        • webdevladder 3 days ago

          You can judge React, but like I said, not frontend. You're responding to an argument I didn't make.

    • hajile 3 days ago

      React has one up-front size for rendering code whether you use 1 component or 10,000 components.

      Svelte and Lit rendering code size just keeps going up, and up, and up....

      You can argue about which is better, but this kind of naive size comparison is disingenuous.

      • afavour 3 days ago

        While it’s true that Svelte and Lit can grow in size dependent on project there’s no world in which even large projects get close to the base level of the React runtime.

        • troupo 2 days ago

          Reddit rewrote a small part of their website with web components using lit. 100+ requests and over a megabyte of Javascript to render a side menu.

          Because they probably did the "several runtimes don't matter" thing, and every tiny component loads the full lit runtime

          • afavour 19 hours ago

            I have no idea about that but if the figures you’re providing are correct it’s pretty obvious the answer is that they did it wrong. There is nothing in the web component API that would require 100+ requests nor several MB of JS, especially when you’re in control of every step in the process!

          • spankalee 2 days ago

            > every tiny component loads the full lit runtime

            This is just not true.

  • webdevladder 3 days ago

    A more broad observation, I'm being pointed in the parent comment - web components need to win over framework authors. The signs are not trending well here from what I've seen consistently. That community is on X and web components are not addressing their problems and they're not used in optimal scenarios. I hope web components can win them over but they're mostly saying they've been a failure, arguably on balance bad for the web.

  • skrebbel 3 days ago

    I don't really understand this argument, to be frank. Most runtimes are pretty small, and there's not much of a performance overhead to both runtimes running at the same time. It's not like these are two realtime engines both purring along in the background or something like that. All modern web frameworks are reactive, and won't do anything unless something needs responding to. If one part of the page is built with React, another part is built with Lit, and a third part with Svelte, I don't see how that will have noticeably worse UX (or battery consumption) than a page made with just one framework, even when reactive triggers are frequently exchanged between them.

    The tweet you quote is about whether web components are "useful primitives on which to build frameworks". I doubt many web component fans (who actually really used them) would say that they are. They're a distribution mechanism, and the only alternative I've seen from these framework authors is "just make the same library 7 times, once for React, once for Preact, once for Svelte, once for Solid, once for Vue, once for vanilla JS". This is awful.

    • webdevladder 3 days ago

      You're ignoring page bloat as a performance cost. That's hugely impactful for UX on the web.

      • skrebbel 3 days ago

        Not entirely, I said "Most runtimes are pretty small".

        I think people got trained by React into thinking that frameworks are big. SolidJS is 7kb, Lit is 5kb, Svelte is tiny and used to have no runtime at all, etc. Only React is big. And, well, if you're writing React components and publishing them as web components, it's usually quite feasible to build them with Preact instead, which is tiny as well.

        So on a page with like some hodgepodge of 5 frameworks purring along inside various web components, there's still going to be only 20-30 kb of extra overhead. You can compress one image slightly better and save more than that.

        • webdevladder 3 days ago

          The point being made is that web components can pay this cost per-component, and this problem will compound over time. This is an unprecendented cost to frontend framworks and it's the expected usage pattern.

          • skrebbel 3 days ago

            I've yet to see this go wrong in practice. The kinds of components that are worth publishing as web components are often large, non-trivial components. Eg media libraries, emoji pickers (like the one made by this article's author), chatboxes, and so on. They are the kinds of things you only have a limited number of on your page. They're also the kinds of things where application code tends to be much bigger than the framework (except if the framework is React).

            On the other hand, if a component is small and focused in scope, it's likely either written in vanilla JS (like https://shoelace.style/), or made for a single framework (like the average React infinite scroll component).

            In other words, I don't think you're wrong, but I do think you're prematurely optimizing a problem that doesn't really exist in reality. And the cost is big: if you get your way, every component author needs to either lock themselves into a single framework's users, or make 7-8 different versions of their component. I'd argue that that's much more wasteful than a few kb extra framework JS.

            • troupo 2 days ago

              > or made for a single framework

              And then each component will have the entirety of that framework packaged with it when you distribute them. Unless you take special care

          • spankalee 2 days ago

            This just doesn't happen much. Usually a whole app shares one instance of Lit.

            I did see one very badly configured app pull in six copies of Lit once because their bundler wasn't deduping, but: 1) that's still less than a React, and 2) an `npm dedupe` run fixed it.

          • mhoad 3 days ago

            It’s also just not actually true though. It’s not considered good practice to bundle your web components when publishing to npm for this exact reason. That’s something that should happen inside the final app itself where the components get used so you only have one instance of Lit for example if you are using that.

claytongulick 3 days ago

I think one of the biggest "mistakes" with web components was coupling them in people's mind with shadow dom.

For app dev (not library dev) web components are a super lightweight easy option when you stick with the light dom.

You can continue to use bootstrap or tailwind or whatever css thing you like, but get great functional encapsulation with near zero cost, especially if you use lit-html or something similar as a renderer.

My teams have generally found working with native web components refreshing. It takes a dev coming from the framework world about a week to adjust, and then they never want to go back.

Just using simple class properties and a manual call to a render function on set() gives you all the benefits of reactivity without all the hassle of frameworks.

The problem most people have with getting started with WCs is that there's not much out there showing how do to it in "easy mode".

Most of the getting started things throw you right into shadow dom, css parts, and all these really painful technologies that were primarily intended for use by library authors, not app devs.

I've been building apps with native WCs for a long time now, I should get off my keister and write a guide on how to make your life easier with WCs, something like "The Good Parts".

  • nolanl 3 days ago

    I use shadow DOM every day, but yes, it is often the part of WCs that baffles people – probably because they don't need it.

    Alternative approaches that may work for your use case:

    - "HTML web components" [1] - light DOM only, SSR-first, good as a replacement for "jQuery sprinkles"

    - "Shadow gristle" [2] - use as little shadow DOM as possible. If you need styling or composition, put it in the light DOM!

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

    [2]: https://glazkov.com/2023/03/02/shadow-gristle/

  • replete 2 days ago

    > I've been building apps with native WCs for a long time now, I should get off my keister and write a guide on how to make your life easier with WCs, something like "The Good Parts".

    If you consider writing about this I'd like to read it. Or listen! Do you have a blog? In the process of gathering various comments about this technology as it appears there are blessings and curses, depending on how you use it.

  • kolme 2 days ago

    In my last gig we had exactly the same stack (WC without the shadow dom part + just lit-html) and it's great.

    The best part is not having a dependency hell situation every other week.

  • meiraleal 3 days ago

    That's exactly it. We are just missing slots for lightDOM

burcs 3 days ago

I love web components and am bullish on them breaking us out of the current frontend hellscape we have created for ourselves. I was recently able to give a short talk on the future of frontend, and it seemed like a lot of other people are hopeful for a way out as well.

As far as performance we built out a data table for our DB GUI that can load in hundreds of thousands of rows and the scrolling through is still buttery smooth.

We actually are getting ready to release our web component library, it's a bit early and rough around the edges but would love to get some more eyes on it! www.astra-ui.com

  • candiddevmike 3 days ago

    The only way to get out of the current front end hell IMO is if we get client side import:

    https://github.com/whatwg/html/issues/2791

    • arcbyte 3 days ago

      I'm aghast at the comments in that thread. They are truly asleep at the wheel.

      No wonder the front end is such a disaster with those mindsets running the show.

      • lelanthran 2 days ago

        > I'm aghast at the comments in that thread. They are truly asleep at the wheel.

        And the wheel that they're at is the one in a clown car. Which is driving off a cliff.

        Just having a custom element `<my-include-html remote-src='...'>`[1] is enough to forgo 50% of the reason for using a front-end framework with a build-step.

        [1] One that executes scripts, allows `<style>` tags, etc.

    • halfcat 2 days ago

      Would this be different from using HTMX to load an HTML partial on page load?

      Something like:

        <div hx-trigger="load" hx-get="/header.html"></div>
    • askonomm 3 days ago

      I mean <script type="module"></script> can do ECMAScript module imports.

  • jitl 3 days ago

    I looked at your docs:

    - renders very weird on my iPhone iPhone 15 Pro Max in Safari 18.0. Consider responsive design for smaller screen sizes to restyle the sidebar and set a body max-width instead of a width. You might not expect your users to develop on phones, but you might have a hard time with adoption if the docs are mobile hostile.

    - the “explore components” button at the bottom of the home page seems to link to nowhere

    - site claims “Learn from well-structured, accessible component implementations” as an advantage but I didn’t find any links to the implementation from the docs

    - site claims “No dependencies to manage or update” but isn’t astra-ui a dependency? It has a changelog (https://www.astra-ui.com/changes/). Likewise “Full control over the code and styling” I don’t understand how I can both have full control but also be taking a dependency on implementations provided by a library.

    I’m curious why you’ve decided to release this library? I’ve come to view open-sourcing internal software as useful to the company for a few specific reasons but to generally be a time-sink without much return unless it’s accomplishing a goal. Component libraries need to fight for general ecosystem adoption or there’s no audience and you might as well not publish at all.

    • burcs 3 days ago

      Really appreciate the write up here!

      Maybe rough around the edges is an understatement haha, we are actively working to make the docs here better.

      So a few things, these are very primitive components that can easily be updated and restyled.

      There’s a given that there will be a dependency when using a library, right? The thing is with this you don’t even need to npm install if you don’t want to. Just plug and play.

      As far as why… there isn’t much out there in terms of a web component driven component library and I think we’ve done some great stuff with ours. That plus we have customers embedding our components into their platform and it’s always helpful to see the source code.

      I hear you on the docs quality though we will work on that.

  • stavros 3 days ago

    Why aren't web components there/more popular yet? They seem like a fantastic solution

    • pfraze 3 days ago

      Web Components have some nice features, some bad features, and no killer feature. Developers have mostly chosen to ignore them for other approaches (React, Vue) where there are better ergonomics and stronger network effects.

      • meiraleal 3 days ago

        ShadowDOM should be a killer feature for people that wants to make web scrappers life a bit more difficult.

        • nsonha 3 days ago

          just do a quick scan in this thread, many say it's the one thing that makes web components not work for them. It's the opposite of what a killer feature means

          • meiraleal 3 days ago

            What users/devs like and what CEO/PMs want (stop bot scrapping) are different things.

            It was a joke tho, I use custom elements heavily but never with ShadowDOM. It is indeed a PITA.

    • kansface 3 days ago

      > They seem like a fantastic solution

      for which problem? They don't replace the need for a framework nor do they make writing in one easier. They don't make dev ex better. What is the actual use case? If they were highly useful, they would be used.

      • stavros 3 days ago

        Creating self-contained components that don't rely on loading extra management code, in a standard way.

        Maybe they aren't useful because the modern trend of web development is to not care about speed or size as much.

    • burcs 3 days ago

      The cynic in me wants to say it’s because they aren’t VC backed so there’s no main catalyst driving them.

      I don’t think a lot of people know about them, or if they do they have just heard about it in passing and have never actually used them.

      Whatever the reason is they have a marketing problem that’s for sure.

      • throwawayha 3 days ago

        Lots of open-source things got adopted without VC backing.

        There's a lot more options now, it would be good to have a way to have the best stand out.

      • stavros 3 days ago

        Ah, well that's encouraging, if the tech itself is good, it means I can start using them more.

    • remixff2400 2 days ago

      Implementation has been a big part https://news.ycombinator.com/item?id=36976670 (one of many discussions if you search for previous Hacker News articles)

      Especially earlier on, web components were implemented without incorporating some of the major feedback from developers. What resulted was a low-level tool with some really awkward warts and APIs that was more-or-less unusable. (hence, one of the reasons why when web components discussions come up, lit is always mentioned since it needs that extra layer to paper over some of the warts)

      TL;DR: it replaces some of the bad parts of Angular/React/etc. with its own set of bad parts that become more obvious only once you get deeper in.

    • j45 3 days ago

      New developers follow social proof often instead of learning from first principles.

      Web Components are seriously cool and worth looking at.

      • evilduck 3 days ago

        Social proof does tend to follow employment opportunities. If you're a new dev you don't have the luxury to make principled choices in technology, you're more worried about housing and food security and maybe paying back student loans. Asking new developers to trend-set the industry would be deeply unfair. If we want them to learn from first principles then entry level jobs should have first principles opportunities available.

        • j45 3 days ago

          I meant social proof like prejudice against technologies that employ but don’t seem popular and cool.

          Another confusion might be expecting an employer to educate you. That’s part of it but not the requirement.

          Self-directed learning is critical to go with any formal learning.

          First principles are needing to be taught where or before people are learning things like react. But they don’t, and get pulled into a world of complexity.

      • stavros 3 days ago

        Excellent, thank you!

  • tomjen3 3 days ago

    Why would I used them over something like a Vue component?

    • burcs 3 days ago

      They are framework-agnostic, meaning you're not locked into Vue, React, Angular, or any specific framework. They work natively in the browser, which makes them reusable everywhere, now and in the future.

      • throw310822 3 days ago

        > They are framework-agnostic

        This is a selling point only if your job is producing component libraries. Otherwise, if you're an application developer, you'll be using a framework anyway.

        • apotropaic 3 days ago

          Not entirely true. Making UI parts of your app using web components can future proof and prevent getting stuck on a framework.

    • throwawayha 3 days ago

      Vue is great but it's a personal preference and interpretation for you.

      It's not about better or worse for you, maybe for the average person.

  • shortrounddev2 2 days ago

    I just rewrote my company's frontend ad code in webcomponents

veggieroll 3 days ago

One thing about web components that I've appreciated is that they can work without JS enabled (at least in theory). I've done this a few times for progressive enhancement.

Broadly I agree with Nolan, though. Web components have enough rough edges that they're not going to take over the world in the current state. But, they are pretty nice for certain use cases.

I'm not sure what he means by not playing well with server side rendering though. I've been doing that without issues.

  • mariusor 3 days ago

    > they can work without JS enabled (at least in theory).

    I wonder what makes you say that. All that I've seen seems to indicate[1] that Javascript is needed in order to register the template with a specific tag.

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

    • debugnik 3 days ago

      Allegedly, declarative shadow DOM lets you declare the template next to the prerendered slot, without JS.

      • mariusor 3 days ago

        Where is this "alleged" though? From one of the paragraphs behind my link:

        > This won't appear in your page until you grab a reference to it with JavaScript and then append it to the DOM

        • debugnik 3 days ago

          Your link isn't showing the declarative shadow DOM, this does:

          https://web.dev/articles/declarative-shadow-dom#how_to_build...

          And the example below that one shows how to hydrate declarative shadow roots with JS custom elements, so the path to progressive enhancement should be clear.

          I say alleged because I haven't had the chance to try it beyond a toy example.

          • mariusor 2 days ago

            I'm not sure what you meant when you said "without JS". To actually use templates you need JS. Yes you can declare them, but what's the point?

            • debugnik 2 days ago

              You've ignored the part where the declarative template is immediately attached to its parent as a shadow root by the parser, and its siblings become the slot children. You don't need to instance or register anything with JS there, just copy-paste the template (admittedly lame, but kinda the same repetition as SSR today, just less involved and with a shadow root).

      • nsonha 3 days ago

        that's just wrong

        • debugnik 3 days ago

          What, exactly, is wrong? I need actual replies to continue a discussion.

          This is a declarative shadow root [1]. The template goes next to its slot contents, so you can render both separately on the server and let the HTML parser attach the shadow root, without JS, then use JS custom elements to progressively hydrate it.

          [1]: https://web.dev/articles/declarative-shadow-dom#how_to_build...

          • nsonha 2 days ago

            sorry I did not know about `shadowrootmode` but your original comment was just a single statement with a very specific claim.

            Now you are right about that you can use template without js. But I have to ask: what is the point of declarative shadow root?

            The point of template is to be reused instead of being used once at the same place that it's declared. This seems like adding more markup and introducing shadom dom for absolutely no reason. You may as well just write the markup directly .

            • debugnik 2 days ago

              The name of the template tag is misleading, I agree: It separates the shadow DOM elements, the "template", from the light ones, the children slots.

              Different server-side instances of the same components won't necessarily render the same shadow tree, so client-side reuse was out of the question for declarative shadow DOM. But unlike client-side template, you get to paint components much sooner, during the parser, or even without JS enabled.

              As for why a shadow root instead of the markup directly, well, that's kinda like asking why use web components at all, which I thought was part of the premise of this reply chain.

              Even without JS, the shadow DOM gives you scoped CSS and isolates the shadow elements from outer DOM and CSS selectors. And custom elements, the other half of web components, can be used in HTML before defining them in JS, at which point you get to enhance the entire page at once, so now you can progressively enhance properly isolated components possibly written with different frameworks.

              • nsonha 2 days ago

                > why a shadow root instead of the markup directly, well, that's kinda like asking why use web components at all

                that's way off. Web component is about encapsulation/reuse of code & markup.

                I am willing to entertain the idea that at some point, some people with authority did think the shadow dom was a key part of web components. However, as of now, if you just scan comments in this entire thread, everyone think it's an annoying abstraction that unfortunately people have to deal with in order to enjoy other benefits of web components.

                • debugnik 2 days ago

                  > I am willing to entertain the idea that

                  You better do, literally every authoritative description of web components lists shadow DOM, custom elements, and template. And the last one is kind of a remnant of the push for HTML imports, which went nowhere, and is currently insufficient for anything you'd use React for, so its main value now is how it's being repurposed for declarative shadow DOM.

                  So, personally, I'd say they're about shadow DOMs and custom elements, whether that's useful or not; I'm not convinced either!

    • DonHopkins 3 days ago

      Using HTML and CSS to make web interfaces without JavaScript is like using concrete to make garden gnomes without rebar, while the rest of the adult world is more concerned with using pre-stressed concrete with rebar to make skyscrapers and superhighways. Sure it's a marginal whimsical decorative use case, but not an important or interesting one.

      Most people who think turning off JavaScript is an important use case are only inflicting it upon themselves (and aggressively evangelizing that other people do it too) as performative luddites, to feed their martyr complex, so they have something to whine and complain about how the web is so unfair and out to get to them, and have exactly zero customers or products to support.

      • mariusor 3 days ago

        You seem to be quite careless about whom you offend, but I'm not a fan. Please quit it, the only one whining right now seems to be you.

        • nsonha 3 days ago

          really I feel the same as them

  • charrondev 3 days ago

    How is this supposed to work?

    With reactJS I know I can server render a component or template and I’ll say JSX makes a pretty good tempting language.

    With web components as far as I understand there is no good templating language built in anyways (so you have to bring your own) I’m not aware of a standard mechanism in which I can take some chunk of JS for a component associated with a tag and have it render out HTML that does not require JS to run.

  • nolanl 3 days ago

    Author here. I cover this in another post [1], but basically the interop benefits you get on the client just aren't there (yet) on the server. My north star:

    > Maybe in the future, when you can render 3 different web component frameworks on the server, and they compose together and hydrate nicely, then I’ll consider this solved.

    [1]: https://nolanlawson.com/2023/08/23/use-web-components-for-wh...

impostervt 2 days ago

A few months ago I started a job where I inherited a JS code base that is around 250,000 lines. It was one big class, with several sub classes, that did everything. Some files were 30k lines long.

No frameworks, no reactivity. If you click a button, you had to update everything on the screen with event listeners manually.

Took the guy years to write it. It's like a monk got locked in a cell for years with a basic book of javascript.

I started by refactoring into web components, because I had to do it piecemeal. It's been a big help, and I've cut 50k lines of code so far. But the real point was to just learn everything the old code was doing before I start a rewrite.

  • Sammi 2 days ago

    > I started by refactoring into web components, because I had to do it piecemeal.

    Yes. The key to making an old and arcane code base understandable to yourself, is to refactor one small part of it at a time. That you're redoing with web components is just one way that would achieve this. I applaud you for not just throwing everything it away and starting anew.

    On risk of this approach is that you get some way though and then move on to some other project, and someone else comes along and inherits the old project and starts refactoring in their own style, and so now you have an old arcane code base in three different styles... it still beats a rewrite of a 250.000 line code base in one go.

mmcnl 3 days ago

I don't really get this "frameworks vs. web components" discussion. They are both tools to solve different problems. Frameworks exist to render your view as function of state in a declarative way. They use web primitives to define the view layer. Web components can help there, but it doesn't solve the state management issue that frameworks aim to solve. That's a different problem that requires different solutions. In my opinion they can perfectly co-exist.

superkuh 3 days ago

Web components are okay as long as you only use them to progressively wrap actual HTML elements. If you're using custom-elements by themselves like a JS frontend replacement and just making entire web pages full of blank grey boxes that do nothing without JS, you're doing a bad job.

See: https://blog.jim-nielsen.com/2023/html-web-components/

  • claytongulick 3 days ago

    Oh? So anyone writing applications, PWAs, healthcare software, responsive mobile web apps, or a billion other business domains where the web makes sense as a UI is doing a bad job?

    Guess I've been doing a bad job for a long time now.

    • superkuh 3 days ago

      Yes, https://www.gov.uk/service-manual/technology/using-progressi...

      “All [UK] government services must follow progressive enhancement, even if part of the service or a parent service needs JavaScript”

      But more seriously, it's okay to do a bad job if you're being paid/forced to do it by a for-profit entity. That's what jobs are. Being paid to do things you wouldn't do otherwise (like making a webpage entirely inaccessible to people with screen readers because there's no text in the custom-elements pre-JS execution and not caring because the visually impaired don't contribute significantly to profit). Just don't chose to do a bad job for personal stuff.

      • royal_ts 3 days ago

        While that link is great advice it's not 100% true that you need to have JS enabled to render anything in a web component - there's declarative shadow dom. Also while it's also true to depend on as little as possible JavaScript it's also required for some accessibility aspects. You can get far with only HTML and CSS but not always all the way.

      • DecoySalamander 3 days ago

        Screen readers that can't do their job on dynamically generated pages are faulty and should not be relied upon by anyone, especially for browsing the web. There is absolutely no reason to be beholden to the incompetence of the developers of such software.

        • superkuh 3 days ago

          Yeah, those visually impaired people should be constantly changing their screen reader software so as to follow the eternally changing wave of web dev. That's totally a feasible and reasonable thing to ask. I'm sure the shadow dom is giving those dynamic screen readers zero problems. /s

          Please, please just consider putting actual text in the HTML. It helps a lot.

gaganyaan 3 days ago

I really dislike the Shadow DOM part of Web Components. Someone didn't learn any lessons from past mistakes and went and reinvented iframes. Trying to write tests or any automation for a web page that uses shadow dom is an exercise in misery, unnecessary at that.

addicted 3 days ago

Web components are lacking some basic functionality that makes using them in something complex difficult.

For example, one of the deal breakers we faced was the inability to unload and reload a web component. Once you load a web component you’re stuck with it until you refresh the browser.

You cannot have an SPA with one page loading 1 version of the web component and another loading another version without some ugly namespace mangling.

drawkbox 3 days ago

I dig WebComponents because I love building on standards which promote interoperability across frameworks and have long term lifelines. Standards reduce platform + dev lock-in and reduce framework balkanization and frankly chaos in many cases. You are a better developer if you understand the root standards and core systems, which WebComponents get you closer to.

I also like the Lit Framework (https://lit.dev/) from Google which is rarely mentioned but it is quite nice for some of the simplifications and extras you might need when building them but it doesn't get in the way or try to take over your entire domain with dev-lockin.

Whether going direct to WebComponents or a higher level simplification like Lit, they really are a freedom from dev lock-in that is nice to see.

skrebbel 3 days ago

I'm bullish on web components as a distribution mechanism. In fact, we're currently hard at work betting our entire company (https://talkjs.com - a component library + API for chat) on it.

I agree with Nolan here that the performance is fine. People keep comparing web components to React or Solid components, but the latter inherently have a tiny granularity whereas web components is primarily a way to distribute reuseable elements, not an application framework on its own. Don't make every tiny piece of your app its own little web component (or, at least, don't do it without a framework such as Lit to skip the pain). But web components are the way to build a component once and have it usable in all web frameworks (including none at all) out of the box. That's fantastic! And also unprecedented (on the web, that is).

It bothers me that so much of the discussion is still about whether web components are good primitives to build frameworks on top of. No, not really, they're pretty awful for that! But for distribution, nothing else comes close.

I'd love it for some alternative standard to emerge, without all the awful design choices of web components. And I agree with Rich (Svelte) and Ryan (Solid) that WCs being built into browsers are getting in the way of some other collective component interop design emerging. But until the framework authors stick their heads together and invent a fast, modular, non-shitty, property-only, functional-smelling standard for distributing components, I'm sticking with web components. For component authors, the only alternative is making a React version, a Preact version, a Lit version, a Svelte version, a Vue version, an Angular version, a Solid version and a vanilla JS version of the same UI component. That's awful! Web components are clunky but they're here, now!

  • delusional 3 days ago

    > With every programming language, you can do

    There are plenty of programming languages where you can't do that. If you really need that, can't you just register it as "my-thing-1" and then register the other one as "my-thing-2"?

    • skrebbel 3 days ago

      Sorry, I edited my post and took that out for being too detailed.

      > If you really need that, can't you just register it as "my-thing-1" and then register the other one as "my-thing-2"?

      Yes you can, but it means you gotta search-replace something, whereas in every modern programming language you just do an import or an alias or something like that.

      And you still can't solve hot-reloading a web component that way.

tannhaeuser 3 days ago

Let me explain the argument to you:

> You can always add another layer of abstraction to solve a problem but removing one can be difficult.

The argument being that there's no need to add anything to the browser stack and make it even more complex when it doesn't add any essential capability. There's already JS making everything possible; and yet, they keep on piling stuff. When with custom elements specifically, you also require JS anyway (to declare them).

> Elements are not components.

Idk maybe for "web devs" the concept is difficult to grasp that HTML isn't for them. It's for text authors, and as such a markup vocabulary where low-level elements are placed next to complex custom controls nilly-willy isn't really a useful evolutionary direction.

thomassmith65 3 days ago

I use web components, but I often want to design classes as MVC. It isn't obvious how this should work (though I assume the Web Component spec authors discussed the topic at some point). The awkwardness is:

(a) When you instantiate your View class (ie: 'web component') from JS, you probably want your Model and View to be 'owned' by properties of the Controller (eg: con.model and con.view). However...

(b) when an HTML tag instantiates your View, the View has to create its Model and Controller. And now there's no obvious place to store a reference to the Controller.

As a result, you have either to stick the Controller in a global variable somewhere, or - more likely - end up, not just with 'con.model' and 'con.view', but also with a new property: 'view.con'

So... two paths to create everything (Controller-based, or View-based), and this ugly '.con' property stuck in the View.

But, aside from this gripe, Web Components are okay.

  • mattlondon 3 days ago

    I don't think we components were intended as a complete "framework" for writing web apps, but more for the rendering of reusable UI components.

    So trying to do MVC with just web components feels a bit weird, at least to me. You'd need something extra I think

    • thomassmith65 3 days ago

      The problem is that the ShadowDOM is sort of the real View, and the CustomElement (judging it by its methods), is kind of a mix of a View and a Controller.

      Perhaps I should try making my controllers the HTMLElement subclasses, instead of my views. My gripe remains: the best approach is not obvious.

tomrod 3 days ago

I like seeing accessibility respected. Good post.

PaulHoule 3 days ago

I did a project that used Shadow DOM and related tech to address the problem of embedding a widget into a partner’s web site without any risk of CSS interference. Worked great, but this was one medium-sized widget that did not interact with the rest of the page.

dandrew5 3 days ago

Web Components are fun. I've played around with Lit, which some people have mentioned. Anybody tried Stencil? It looks similar from the outside but wondering how it plays out mid/late-term.

  • commanderkeen08 2 days ago

    Stencil has a way better DX. Especially if you’re doing a whole library of components. You pay a slightly higher perf tax for their auto loader and light vdom. Lit is the way to go if you have opinions and want no magic

carlual 2 days ago

I found a practical way to foster critical thinking skills and encourage independent thought at the end of Netflix's documentary, The Social Dilemma:

> I follow people on Twitter that I disagree with because I want to be exposed to different points of view.

Here is another good opportunity for it.

newhotelowner 3 days ago

Safari is the only browser without the full support

*Supports "Autonomous custom elements" but not "Customized built-in elements"

mrfinn 2 days ago

How can it be possible that we are in 2024 a no one seems to be proposing the most obvious improvement to the web, which is to create a new standard designed for web applications and let the HTML alone serving it's original purpose, which was to serve documents? (H*T*ML the T goes for "TEXT"!). Instead of that, and make things complex and unmanageable to the extreme, to "improve" things now we dropped out completely the MVC philosophy and went completely ahead with an spaghetti mess of Javascript, HTML, CSS, and create-your-desired-tags-at-will everywhere, aka Components.

PS. And not even mentioning Madnesscript which deserves another chapter in this story of horror.

  • openrisk 2 days ago

    There are probably many reasons. The history of technology development teaches us there are a lot of non-core factors that affect the adoption of alternative designs (influential entities and agendas, network effects, business models of those involved etc.)

    But there seems to be also an interesting intrinsic reason: The versatility of the digital "Document" paradigm itself. Text in its digital incarnation (a sequence of human readable strings) is not just your usual text. While printed text on a page involves the encoding and annotation of human language sentences you can encode a lot more things in human readable HTML/SVG/XML formats (e.g. numerical data, visual geometries, declarative UI etc.).

    The HTML family of documents is in this sense a sort of "super text". Its structure reflects already its huge dynamic (rich text) potential. But clearly you cannot solve everything in a declarative manner (though you should probably push it as far as possible). At some point the flexibility of code is important and the question then is what is the optimal way to do this (as in: easy, performant, versatile etc.). Alas at the moment we seem to be almost at the extreme opposite: everything as code.

    Ideally one would refactor all these declarative formats that have proven their utility and resilience and rethink the role of code / frameworks, taking into account all the developments and learnings of the past decades (web assembly, mobile, pwa etc.).

  • mixmastamyk a day ago

    It's a herding cats problem. Not practical for new actors to propose one and have it adopted; current principals are no longer trusted. No one else with deep pockets cares enough to donate the resources it would take and/or do the hard coordination work. We don't see viable new Operating Systems either, for example.

    That leaves minor feature additions as the only way forward.

wellpast 3 days ago

What’s missing in his point and examples about “performance isn’t everything” (aria properties, forEach, …) is that these are cases where you could optimize later when and if needed. Using forEach is a fluid coding choice at the time but if for any reason you need to optimize to a for loop you can with minimal fanfare. But buying into web components is more of a one-way door and harder to iterate optimizations, and that’s the problem.

jongjong 2 days ago

Tech discussions are hard to have nowadays because people are highly biased in favor of their current tech stacks.

The religiousness which used to be restricted to programming languages has expanded to include frameworks, databases, test runners, infrastructure, CI tooling, libraries; literally everything is a religion nowadays.

It makes almost all technical arguments disingenuous and pointless. Like people arguing about whose religion is more correct. Observable facts don't matter so much.

People see arguments in favor of some alternative stacks as a personal attack against their career.

It's probably because companies themselves have become so focused on hiring based on these stacks. They have become a matter of livelihood.

In the old days, many companies saw software engineering ability as a separate skill; now they barely even use the word 'software engineering.'

  • hu3 2 days ago

    Thanks for sharing this view. I relate a lot.

renegat0x0 3 days ago

This might be a stupid hot take, but I am surprised that so little of web UI exist outside of the browser. I mean why bootstrap or other frameworks are not managed by browser ecosystem? Why millions of people how to download same frameworks over and over?

shortrounddev2 2 days ago

I wish web components had a bit more to them

1. I wish you could reliably parse their attributes in the constructor instead of connectedCallback, so that they play better with typescript readonly properties

2. I wish I could declare properties in the class and have them automatically map to an attribute

3. I wish I could construct them using html instead of manipulating domnodes manylually

4. I wish I could construct child nodes first so that I can compose webcomponents with other webcomponents

As it stands webcomponents provide the ability to construct a single element at a somewhat predictable moment in time, automatically. That's cool, but their interface is lackluster to me

wordofx 2 days ago

> From my own personal experience: at Salesforce

lol

mtn6747 3 days ago

[flagged]

  • toddmorey 3 days ago

    So just more AI comment spam, huh? It's unfortunately ruining my favorite communities.

    • meiraleal 3 days ago

      it is only ruining if you decide to see the dead posts and still dislike that spam is being killed.

breck 2 days ago

We do web components better than the web. We just call them Parsers.

Geniuses build for The Scroll first. Retards build Web first.

(Don't misinterpret, I love The Web, but The Scroll is on track to be 100x better)

auggierose 2 days ago

Web components are not OK. They are shit. I wouldn't touch them, just as I wouldn't touch shit.

If you find React hooks hard to understand, then I really don't need to hear your opinion about anything, including about how web components and HTMX are so great. Just learn programming.

  • epolanski 2 days ago

    As someone who uses all of web components, react and Vue, depending on the project I really feel like to give such aggressive and opinionated takes you should consider doing it in a mature and professional way that goes into the "why" you feel like that.

    • auggierose 2 days ago

      Mature and professional is what gives us shit like web components, and people like you eating it. So, no, thank you.

      • epolanski 2 days ago

        Have you considered that there are different tools for different problems and that web components have their own space in the wide array of problems?

        Because they are a decent fit to a specific set of problems (e.g. authoring components you can embed on different platforms, regardless of the technology they are built with).

        I myself, as detailed in another comment, have concerns with web components, and having worked with them extensively, I feel they fall short in several aspects (especially regarding layout control, where they aren't isolated enough due to a series of design choices) but it's manageable.

        A problem that I had in two different companies (embedding a set of elements that had to work in very different applications and required the host to know little to nothing) after much analysis was best solved with web components and they did well at that.

        The possibility of doing `<script type module>import "yourcomponent.js"</script> <yourcomponent foo="bar"></yourcomponent>` without for us web component authors having to worry about the wide array of different technologies the hosts used (both at compile and runtime) has been in the end the best solution for both us and the consumers.

        As Ryan Carniato points out, most of the criticism web components get is that their usage is misunderstood, some of their behavior falls short of their goals, and their name conflates then with framework's components creating further confusion, which are something very different.

        The problem with comments like yours is that they add nothing of value to the discussion. We don't know if, when and where did you try to use web components, what hasn't worked for you and why, or if you've ever had the kind of problems where web components would've been a good fit or not.

        You end up giving the hopefully wrong impression of an obtuse person lacking the engineering sensibility to understand the context of problems and of their possible solutions.

        • auggierose 2 days ago

          Wow, your maturity and professionalism are off the charts, and I'll bite.

          There are two different kinds of problems: those that nature imposes on us, and those that we create due to our own stupidity and ignorance.

          Web components might help you to solve problems created by the latter (and in the process create more problems of the same sort). React, on the other hand, was a true step forwards for how to approach making user interfaces.

          Web components are a packaging mechanism for custom HTML tags. If it were just that, fine, but the spec tries to make them into so much more, and this is where the problem and the complexity, and all the shit is. They are not units you should think in when designing your application, because they are not a component framework. They don't solve a single problem I would have when creating an app. If things like web components did not exist, your customers would not run a wide array of different technologies, all doing the same thing in slightly different but equally shitty ways.

          • epolanski 2 days ago

            We maintain a wide array of b2c, internal and b2b products built in different periods.

            There is no solution to embed additional common functionality that has to stay consistent besides iframes or web components.

            The only alternative would be to implement the solution and all of its patches over and over.

            I'm glad you don't have that problem, but if you have sensible alternatives I'm all ears.

            • auggierose a day ago

              Just supply a JavaScript module that creates the component. That's what you would do if there were no web components. And it is more flexible, too.

              Now that web components are part of the standard, they might be the more convenient solution for distributing components to heterogeneous environments, and allow for nicer packaging. But the price tag for that slightly nicer packaging is too high, and web components should not exist in the first place. Also, nobody in their right mind will make web components manually, you will need a higher-level framework from which you can generate web components. And I think one of the creators of such a framework gave you his opinion on this.

              To summarise: web components are shit. The world would be a better place without them and the bloat of ill-thought out specs they bring.

  • dominicrose 2 days ago

    Honestly I would be fine if classes didn't exist. This means no methods, no "this". Namespaces, data structures and functions are enough to do everything.

    I started to like React when we could write components with functions.

  • tonis2 2 days ago

    I disagree, I would prefer light web-components, rather that react.js + the compilers and state managers.

    This make me into a bad programmer, I agree to disagree

  • ForHackernews 2 days ago

    What a weirdly aggressive comment. I could just as well say you should stop trying to (ab)use programming to make web pages and learn markup instead.

    React is a comedy of errors and imho should not be held up as aspirational https://medium.com/@fulalas/web-crap-has-taken-control-71c45...

    • auggierose 2 days ago

      React, especially with the addition of hooks, is brilliant from a conceptual point of view. I don't like their new docs though, they infantilise too much, trying to hide the concepts, instead of clearly exposing them. They don't even have a page anymore about how to set up React on your page without using something shitty like NextJS.

      Furthermore, there is really nothing to "learn" about markup. That is why it is markup.