gg2222 2 days ago

To the author: Yes, do consider SolidJS seriously. I find that its reactivity system is simple and the easiest to reason about, with none of the messiness and constant changes to "the best practice way to do things" like React has gone through the years.

SolidJS seems designed right so that it doesn't need so many major revisions and it feels quite stable.

It feels like an evolved React that is simpler to use.

Also its signals and stores can be used in normal .ts files, so it is easier to create re-usable "stores".

edit: BTW haven't been following Svelte but it's already version 5? I thought it was the newest framework.

  • sesm 2 days ago

    Looked at SolidJS, it's primary mechanism is signals, which are essentially runtime edit maps. They have the same downside as all other types of edit maps - programmer needs to compose them manually, which becomes messy very quickly with loops and conditions.

    • baxuz 18 hours ago

      What are edit maps?

      • sesm 6 hours ago

        Mapping between reactive variable and DOM element. I first heard this term in Million.js docs, but it explains very well what most 'reactive' frameworks are doing. For example, a Signal creates the mapping at runtime on first render.

  • zwnow 2 days ago

    >> SolidJS seems designed right so that it doesn't need so many major revisions

    Which is exactly what is said about every framework

    • Wazako 2 days ago

      It's different with solid-js, which is more of a library than a real framework.

      The solid-js surface is relatively small, the jsx / css is identical to the native, the Hook simply builds the DOM once. solid-js therefore brings above all a createSignal that adds an observer where it is called in the DOM to directly update the DOM accordingly.

      You might think of solid-js more as a signal primitive than a real framework.

      • gg2222 2 days ago

        Exactly. SolidJS api itself is very small, there is not much you actually have to learn. This makes it simple to reason about and at the same time gives you the confidence to wield it, which makes it actually feel more powerful.

      • zwnow 2 days ago

        Its funny because "its different with [insert framework]" is also said about every new framework ever.

      • bossyTeacher a day ago

        May I remind you that React was originally a library. Didn't stop it from morphing into...whatever it is now

  • tglide 2 days ago

    > SolidJS seems designed right so that it doesn't need so many major revisions and it feels quite stable.

    lol https://github.com/solidjs/solid/discussions/2425

    • gg2222 2 days ago

      Yes I know SolidJS 2.0 is coming. I said "it doesn't need so many major revisions", key word being "so many".

      (Telling myself: damn should of put that in my original comment cause of course someone's gonna comment that.)

      • dartos 2 days ago

        These frameworks have so many versions over time because the web, browsers, and people’s expectations of the capabilities of websites are a moving target.

        Over time you’ll see many major revisions as you do in every other framework in existence.

    • 0xblinq 2 days ago

      It’s major version 2. Compare that to the amount of major (and really breaking, like Vue) for all other frameworks.

      LOL

      • tglide 2 days ago

        Solid is much more recent, of course it has less major versions.

  • 0xblinq 2 days ago

    Solid is so underrated.

    The simplicity and the power it brings is so good.

    I’ve also used SolidStart for a project and it’s by far the best meta framework I’ve tried so far. Again, simplicity, power and extensibility.

    • flessner a day ago

      SolidJS is extremely well crafted signaling, I like it.

      However, the SolidJS ecosystem falls behind when building a full web application: The router is okay? Metadata is very separate... and SolidStart isn't pulling it all together in the way it should. Working with async is also a mess.

      This makes it feel like you're having to learn 3-4 entirely separate systems.

  • rxliuli 2 days ago

    Yes, what I want might be some better React, like JSX, but I don't like the complexity introduced by hooks and the binding of Next.js.

    • bossyTeacher a day ago

      The best time to learn React and use it was while it was small and literally just a library.

  • mkl 2 days ago
    • gg2222 2 days ago

      Yes, so actually SolidJS is newer.

      • yurishimo 2 days ago

        That’s technically true but Svelte had a major paradigm shift in v4 and an extension of that paradigm in v5. The name is older, but the underlying code is newer.

seanwilson 2 days ago

My current preference in Vue 3 (with the Composition API) but using JSX (which is generally only mentioned with React) instead of Vue HTML templates (e.g. https://vuejs.org/guide/extras/render-function#v-for, https://vuejs.org/guide/extras/render-function.html#jsx-tsx) with TypeScript. Correct me if I'm out-of-date, but my understanding is Vue is more batteries included, and state management is more concise. I strongly prefer JSX :

- I can write for-loops, conditions, etc. in the same language I write my logic in with the same TypeScript and (Vscode) IDE support (e.g. refactoring, formatting, error reporting) vs using a special template language + IDE plugin.

- I find HTML templates really ugly and harder to read in that your dynamic logic code gets lost inside the static markup and presentation code e.g. `<li v-if="items.length > 2" v-for="{ id, text } in items" :key="id" class="card card-body fw-bold small"> {{ text }} </li>` vs `{items.length > 2 && items.map(({ id, text }) => (<li key={id} class="card card-body fw-bold small">{text}</li>))}` (still quite ugly but most of the logic is on the outside now).

- I can easily assign chunks of HTML to variables or generate HTML snippets via concise functions in regular TypeScript instead of being forced to create a new verbose component via HTML templates each time e.g. the arrow function above can be assigned to variable and reused. HTML templates feel very limiting in comparison.

It's sometimes awkward finding the JSX syntax (like for using Vue slots), but this is more because it's less common.

Would be curious of others who have tried this Vue 3 + JSX combination!

  • stevage 2 days ago

    I prefer Pug with Vue3. Your example would be:

    ``` li.card.card-body.fw-bold.small(v-if="items.length > 2" v-for="{ id, text } in items" :key="id") | {{ text }} ```

    Personally I find this really readable. The HTML element is the most visible thing, then we get classes, then all the logic in parentheses. Then, standing by itself, the content. And we don't need any closing tag.

    • dmix 2 days ago

      Those smaller template languages make it really hard to switch to another system in the future. The further you stray from HTML the more technical overhead you’re creating for yourself and others in the future, just to save a small amount of time on template code which IDEs heavily automates now (closing tags, refactoring, etc).

      It also makes debugging harder because there’s a heavier translation of stuff you see in dev tools vs your codebase. It also makes gripping and automated project code replacement harder.

      You also can’t easily copy paste HTML code examples from other places. Other developers have to learn and might resist it so you have a mix of template systems.

      I could keep going…

      • stevage 2 days ago

        First, the point of pug is not saving time typing. It's creating a more readable format.

        I have never needed to move pug code to non pug. If I switched from Vue to Svelte I'd keep using Pug.

        I have sometimes needed to do the opposite. There are tools to automate it, but even manually it's much less effort than say converting Vue to React.

        Lastly, the promise of your comment, that technical debt is always an important consideration in all projects, is not correct.

        • dmix 2 days ago

          How big is your team? How many people touch it? Are you leaving it for the next developer to deal with after you leave? Have you dealt with hiring? Does your platform 100% stay in JS/pug or do you mix it with backend views?

          There's a million considerations.

          Ruby on Rails went through this over a decade with HAML with wide scale adoption and it was largely a mistake, projects always end up moving back to HTML. Or into JSX or whatever HTMLy syntax.

          I've worked on at least 3 or 4 projects that switched JS frameworks and stuff like pug would always be burden on moving over.

          Ive been down that rabbithole enough times and it's simply not worth the mostly overstated DX benefit. Nerds trying to be hyper efficient in the wrong ways.

          Simpler and closer to standards is always always better.

          • KronisLV 8 hours ago

            > Nerds trying to be hyper efficient in the wrong ways.

            > Simpler and closer to standards is always always better.

            I don’t entirely disagree, but if it’s fewer migrations between stuff and less churn that you’re after, at that point you might either:

            A) go in the direction of something like HTMX for suitable problems (or tbh most SSR approaches without the complexity of neither SPAs nor hydration)

            B) alternatively find the most milquetoast yet batteries included option out there, like Angular (and hope that something like AngularJS doesn’t happen)

          • stevage 19 hours ago

            > How big is your team? How many people touch it? Are you leaving it for the next developer to deal with after you leave? Have you dealt with hiring? Does your platform 100% stay in JS/pug or do you mix it with backend views?

            > There's a million considerations.

            Exactly. I'm speaking from my experience in my situations.

            > dmix 22 hours ago | parent | context | flag | on: Svelte5: A Less Favorable Vue3

            How big is your team? How many people touch it? Are you leaving it for the next developer to deal with after you leave? Have you dealt with hiring? Does your platform 100% stay in JS/pug or do you mix it with backend views?

            There's a million considerations.

            > Ruby on Rails went through this over a decade with HAML with wide scale adoption and it was largely a mistake, projects always end up moving back to HTML.

            No they don't. Perhaps the most visible projects do. Perhaps there is an overall trend. Even if projects change from one tech to another, it doesn't mean the original choice was a mistake.

            >Ive been down that rabbithole enough times and it's simply not worth the mostly overstated DX benefit.

            [to you]

            I have not seen any statements about Pug's "DX benefit" to know, but I do find I greatly prefer it, to the point where I'm willing to put in the work to enable Pug in any project I'm allowed to.

            > Nerds trying to be hyper efficient in the wrong ways.

            Just throwing a needless insult out there?

            >Simpler and closer to standards is always always better.

            "Always always" is never never right.

    • seanwilson 2 days ago

      Yeah, regular HTML is overly verbose. Being able to compose JSX generating functions and using regular JavaScript logic for loops, conditions etc. wins out for me though because realistic HTML gets big and messy otherwise. Can you do something like this in Pug? (where the actual HTML would be more complex, so you'd want to split it up like this)

          const elToolbar = generateToolbar(toolbarItems) // returns JSX
          const elUserCards = users.map(user => <div class="card card-body fw-bold">{{ user.name }}</div>)
      
          return <div>
              {elToolbar}
              {elUserCards}
          </div>
      
      I find doing something similar with Vue HTML templates has far too much boilerplate, and I have to learn/recall all this Vue specific boilerplate instead of using regular functions so I end up not breaking up my HTML as much. Unless there's a way to do something similar within in a single file?
      • gbuk2013 a day ago

        > Can you do something like this in Pug?

        https://pugjs.org/language/mixins.html

        • seanwilson 7 hours ago

          Any particular part? I'm maybe not following the specifics, but this is similar to the `elUserCards` example I gave? JSX is regular JavaScript, so you can use regular functions, maps, variables, default arguments etc. to generate repetitive HTML, just like you would to generate repetitive strings or JSON, without having to learn a new language.

      • bvrmn 2 days ago

        This approach is a classic footgun for beginners in the context of "hook rules". In general it's quite fragile.

        • seanwilson 2 days ago

          Can you explain more? You're talking about React (hooks) here? Or this applies to Vue + JSX as well?

          • bvrmn 2 days ago

            It's React thing. In maintenance context it's always better to not extract component instantiation. They could start to use hooks or they could be wrapped in conditions in a parent component and it would lead to severe quite hard to find issues.

            • seanwilson 2 days ago

              This is a bonus of using Vue then if this kind of code doesn't pose a problem there?

              Makes me wonder why this is all so difficult. Vue has a lot less problems for me than previous iterations and frameworks, but it's still frustrating how many footguns still exist. Like gotchas where you lose reactivity where linters/compilers won't catch the problem for you, and you forget the gotchas if you're not immersed in that framework for a while.

              I'm not getting why we can't have robust static checking for this stuff vs trusting every developer to be careful.

              • bvrmn 2 days ago

                Yep. I prefer Vue myself — no need to stay on toe tips full time. It's really a question of available ecosystem and quite phenomenal React's backward compatibility which ties very agile in other circumstances FE devs to the framework.

    • luminarious 2 days ago

      Pug templates have been the most readable in my projects. Underappreciated imho, wish Astro also supported it.

      • psychoslave 2 days ago

        Agree, but isn't the project very low in activity?

        https://github.com/pugjs/pug/activity

        That is not necessarily a bad thing, sometime stability is what matters the most. But here the last commit was removal of a security and bugs branch...

        • antifa 3 hours ago

          Pug has been pretty complete for quite a while, there just isn't that big of a potential for insecurity for something that becomes vue's html/jsx at build time and 99% of run time threats is basically that the dev sent unsanitized use input to v-html instead of v-text.

          The main problem with pug is that, AFAIK, vue is the only modern webframework with stable support for it.

    • Timon3 2 days ago

      I loved using Pug with Vue, but after coming across issues with tooling integration (e.g. eslint) too many times, I've returned to the default templates.

  • uallo 2 days ago

    The one thing that bugs me tremendously with Vue template syntax is slots. They are so annoying to use and hardly visible in code completion. Passing template/HTML fragments as props is so much nicer in JSX. This is the only reason, why I even consider using JSX instead of Vue's template syntax. Thus, I'm very much interested in your experiences with Vue+JSX. Especially in regards of (third-party) tooling support. While JSX is officially supported by Vue, it does not seem to be encouraged and may have subpar support in the ecosystem. But that is only something I'm afraid of, I do not have any experience with it, yet.

    • seanwilson 2 days ago

      > Passing template/HTML fragments as props is so much nicer in JSX.

      Ha, I do this in places but I'm not sure if this approach is encouraged? Compared to slots, I like this too, it's a lot less verbose and the syntax is simple and easy to remember.

      > While JSX is officially supported by Vue, it does not seem to be encouraged and may have subpar support in the ecosystem. But that is only something I'm afraid of, I do not have any experience with it, yet.

      Worst case, you can switch to Vue HTML templates in some files and use JSX in others. I've not found issues mixing them together like this.

      • yurishimo 2 days ago

        Does this also allow you to write multiple components in one file? I guess there wouldn’t be a problem with it if you use the primitive inside of a normal JS file.

        I’ve seen the third party package for the compiler that has popped up to try and handle this, but I don’t like the limitations.

        I’m hoping with Vue 4 they will find a way to support multiple components in one SFC file (which kinda violates the naming but hey…)

        • seanwilson 2 days ago

          > Does this also allow you to write multiple components in one file? I guess there wouldn’t be a problem with it if you use the primitive inside of a normal JS file.

          Yes, as in a component would be a regular JavaScript function that takes some parameters and gives you back some JSX to render. It's really concise and there's no need to muck around with plugins or anything special, it's just regular JavaScript.

          When I'm working on projects that use Vue HTML templates, I've often got pages that have some small HTML snippet that appears two or three times, and just don't want to go through the effort of having to break the snippet out into its own component file because its so verbose. JSX makes this really low friction so you do it more often.

  • crabmusket 2 days ago

    I have only tried your approach on small side projects. I quite liked it, for the reasons you mention.

    And for one more reason: the only tooling needed is esbuild, which can handle TSX. No finding a Vue SFC plugin, just a single dependency and you're off.

    (Of course you'll probably also want to install typescript itself as IDE type checking isn't adequate for a real project.)

    • seanwilson 2 days ago

      Yeah, I like that JSX is built into TypeScript like this so it's more standardised with less tooling required. JSX is probably less likely to change given its relatively wide usage compared to each framework having it's own template language and JSX is well supported by linters and formatters too.

  • rk06 2 days ago

    Personally i prefer to put v-for/v-if/else in a separate <template> tag. It makes it easier to identify and makes order explicit

  • apatheticonion 2 days ago

    Awesome! How do you use Vue with tsx/jsx?

nasso_dev a day ago

As a "Svelte5 enthusiast", I didn't stop reading and I wasn't particularly surprised... All frameworks/libraries/languages have quirks. I was perfectly aware of every single point listed yet I still enjoy Svelte 5 a lot more than 4.

> Form Components Are Uncontrolled by Default, Which Can Cause Issues > [...] > What happens if you remove the bind? One-way binding? No, it only sets the initial value, then the input's internal state takes over, contrary to expectations.

I strongly disagree. This is literally how HTML works. This makes forms with default values MUCH less awkward to author.

vlod a day ago

You know I've fallen in love with Svelte (specifically Sveltekit). I would strongly recommend giving it a shot.

I'm an experienced React dev and thought I'd try something new for a side project. I tried and liked SolidJS (and agree with a lot of the positive comments here) and Ryan seems super knowledgeably about everything front end. (It was a close second).

However I wanted to give Sveltekit a shot as it's so different to React (and SolidJS is not).

For me it seems to put me back to those good olde days (insert rose tinted glasses and violin music), where web dev was just html, css and js/jquery (yes, it was hard for it not to turn into spaghetti). However I coded like I was being chased by demons and loved every minute of it.

I don't get that with React. Having to fix stupid race conditions and constant rendering glitches gets to become grating.

Sveltekit (with it's signals approach, like SolidJS) sort of puts me back there. It's all just html, css (or tailwind), simple js and event driven.

You set up some state at the top <script> block and have loaders/actions (superforms is great) in external files. To me it all seems super intuitive.

authorfly 2 days ago

Thank you to author for pointing out some negatives here.

The 5th version made two "non-error", but ergonomic changes, for the sake of larger code bases and standard formats over quick, yet reliable, reactive and testable code (which first attracted me to svelte): - the need for getters and setters when using $runes in functions; this is a waste of time and almost always unnecessary in the contexts in which one uses small store classes. Not that Svelte 4 was better, it was different.. in a pinch, I'd take 4 though. - using folders for routing and using standard page.svelte.js and server.svelte.js naming for everything; it clutters your IDE file list. You could say it's good practise, but limiting to one component per file also causes more files in some cases than multiple components per file (as is possible in React)

Despite all this, Svelte 5 introduces $writable, which is kind of for the use case of one-off simple state - which doesn't need getters/setters - so the whole thing doesn't feel that consistent.

I don't mind using consistent runes - that is a bit of boilerplate, but makes it easier to reason about. I still love the reactivity of using bind (like Vue) and using $effect with it automatically figuring out what to do without the footguns of Reacts useEffect. I love that I can just start writing files and routing will work, css can just go there without a node module to process it.

Increasingly, I've realised React is probably going to remain my number 1: - Recent changes are mostly just shorthands to reduce boilerplate - Mobx has got state down - Hooks have footguns, but I know them - The eco-system is still unmatched - `use` and other statements allowing async loading (like other recent shorthands) is helpful, a lot of my components used to have boilerplate to do async stuff, and it took effort to make failure cases/loading work well. This pairs very well with server functions too.

  • d1sxeyes 2 days ago

    > the need for getters and setters when using $runes in functions; this is a waste of time and almost always unnecessary in the contexts in which one uses small store classes

    Yes, but then you can just use a class.

    > using folders for routing and using standard page.svelte.js and server.svelte.js naming for everything

    This wasn’t introduced with Svelte 5, this is SvelteKit.

    > Despite all this, Svelte 5 introduces $writable

    No it doesn’t? Do you mean $state()?

    • rxliuli 2 days ago

      > Yes, but then you can just use a class.

      Yes, but I immediately pointed out the oddities of the combination of class and runes below, which looks very strange and inconsistent.

      > Despite all this, Svelte 5 introduces $writable

      I don't know what this is.

      • d1sxeyes 2 days ago

        > I immediately pointed out the oddities of the combination of class and runes

        True, and it is a bit weird, but you made it difficult to understand your point by talking about a function which creates and returns a class for some reason.

        It took me a second to work out you were the author of the original article, rather than OP by the way, didn’t really understand properly for a moment.

Taterr 2 days ago

As a new comer to JS frameworks Svelte 5 convinced me to use Vue instead.

I think Svelte has a nicer template syntax and the reactivity is cleaner is some cases, but it feels like there's no "best practice" or "recommended" patterns in a lot of common cases and I don't have the confidence to make something that won't suck later.

Vue has been more stable for longer so it's easier to find dozens of examples of the thing you're trying to do with less argument over how to do it, and LLMs seem to produce much better Vue code.

  • vlod a day ago

    >I don't have the confidence to make something that won't suck later.

    Well that's just development right there! Sucking for a long period of time is 'The Way', the path to greatness, which devs (IMHO) over-rely on LLM to shortcut.

    However I get your point. lol

pablopang 2 days ago

All the points in the gist are basically wrong...I will comment after point to point as soon as I'm back at the desk

  • agnishom 2 days ago

    This kind of enthusiastic debate is why I love the internet /semisarcasm

    • atypeoferror 2 days ago

      Give them time, it’s only been 11 hours. Now I just want to hear about the trip back to the desk

      • pablopang 2 days ago

        You know, on Saturday I generally spend my day with my family rather than answering snarky comments. But since I have some time now let's get down to the answer:

        > Runes Only Work in Svelte Components or .svelte.ts Files

        Yes and this is actually a positive thing: you want the compiler to touch a very contained part of your application, when you know you can expect magic. This also allow us to be more "aggressive" in the transformation since we know regular js libraries will not be affected by it.

        > Hooks Using Runes Must Wrap State in Functions

        This is true for svelte, Vue, solid and whatever signal based framework: the difference? Other frameworks can't deal with primitive values so you feel like you have to do extra work in svelte. In reality you can actually build both Vue and solid styles in svelte (the opposite is not true). $state({ value: "myval" }); if basically Vue ref.

        > Classes as First-Class Citizens for Runes... or Not?

        You start talking about classes and then complain that pojos don't have the same treatment? Those are two very different things, and again, it was a specific design choice...it might be a quirk that you have to know about (that the compiler literally highlight for you) but it serves as a guardrail for you to write less bug prone code. P.s. as said above you can actually build a ref function a la Vue pretty easily and you can use your ref function just like in Vue if you really want this behavior.

        > Svelte Templates Include Features That Cannot Be Implemented in JavaScript

        This is just blatantly false: you can test a bindable props by passing in state as props and that's literally it. If you want you can do ```ts const props = $state({ value: "" }); render(Component, { props }); ``` or if you want to have a literal prop you can just use getters and setters ```ts const value = $state(""); render(Component, { props: { get value(){ return value; }, set value(new_value){ value = new_value; } }}); ```

        > Form Components Are Uncontrolled by Default, Which Can Cause Issues

        As you've said this isn't specific to svelte...the controlled nature is specific to react. Why this would be the right thing? Most of the times having an uncontrolled form is much better and you can sync the state on submit or even better just use normal forms with enhance and sync the state on the server by getting progressive enhancement for free. And if you need it to be controlled, you have the tools to do it.

        > Small Ecosystem

        If you search for svelte specific packages you will certainly find less than react...but you can literally just use any JS package with ease in svelte. That said even for the things you describe in the post it seems you are a bit nitpicking: there a router but not an in memory one, there's shadcn/svelte but it has problems with shadow Dom...the rest you probably just need to search better: `virtua` is a wonderful virtual list, LayerChart a wonderful chart library.

        > Community Response

        We are definitely trying to work to reduce the apparent complexity...a lot of people looked at svelte 5 superficially and deemed it too complex. The same people after trying it for good agreed that is not complex at all and a huge step forward for composability and performance. Just try it out, trust us.

        That said: despite almost all the point being imho invalid this is still a good post because it show us where we can improve the docs and the explainers to ease out this experience.

        Peace out

pjmlp 2 days ago

As old timer I have framework fatigue.

It is either plain ASP.NET MVC, Spring or Next.js, depending on the programming language, and that is it.

  • CharlieDigital 2 days ago

    I would strongly recommend Vue3.

    I am also an old timer. Hand rolled HTML and JavaScript since '97?

    Came up with ASP (both VBScript and JSCript (it's like we're full circle with JS SSR)). Move to ASP.NET when it was in beta. jQuery, Prototype, Knockout.js.

    Vue.js SFC is the thing that feels closest to HTML + JavaScript components done right. It's reactivity model is the same as that of JS whereas React's reactivity model is "inverted" [0]

    The state model (Pinia or just composable reactive primitives) is simple, Just Works, and never gets in your way.

    Lots of folks like JSX because they don't like HTML and CSS. I'm the opposite; I like Vue because I like HTML and CSS and I like JavaScript. Vue is HTML + JavaScript done right with a congruent reactivity model.

    [0] https://chrlschn.dev/blog/2025/01/the-inverted-reactivity-mo...

    • pjmlp 2 days ago

      My use of Next.js is due to SaaS products that only support Next.js on their first party support and teams I work with, thus I won't be using Vue, regardless of how great it happens to be.

      Privately I seldom use any kind of JavaScript frameworks, other than when doing WebGL/WebGPU side projects, and then it is mostly Babylonjs.

      • rxliuli 2 days ago

        I think Vue 3 is better than Svelte 5's runes, but unfortunately, in my 7 years of using Vue, I've realized that Vue is just a follower of React and may never catch up, as it is only trying to optimize the status quo rather than break the deadlock.

        • CharlieDigital 2 days ago

          The exact opposite is probably true at a technical level.

          Vue 3.6, for example, is incorporating a new signals rebuild that's several times faster and probably the fastest signals implementation out there[0]

          Vue Vapor will also release in experimental mode in 3.6 and once it's mainstreamed, will probably also be among the fastest render models.

          Both changes do not affect the DX and require no migrations, but will provide faster performance for ever more complex apps.

          [0] https://www.youtube.com/watch?v=zvjOT7NHl4Q

          • rxliuli 2 days ago

            Yes, that's exactly my point. Vue 3 just improves things using existing technologies instead of creating truly fresh solutions.

            • CharlieDigital 2 days ago

              Wait, wait: so your take is that the upcoming alien-signals[0] library integration -- created from scratch to improve Vue's signals performance -- is just "using existing technologies instead of creating truly fresh solutions"?

              Basically, if I understand correctly, it's not "shiny" enough -- even though it is going to significantly improve signals performance.

              [0] https://github.com/stackblitz/alien-signals

  • brainzap 2 days ago

    vuejs is 10 years old

    • Etheryte 2 days ago

      And it has changed a lot in that time. The code we wrote in 0.x is very different from the paradigm of 3.x, and while I agree it's largely a change for the better, it's still a chore to keep up with it if that isn't the only thing you do.

      • yurishimo 2 days ago

        The change from V2 to today is much smaller. So small in fact that the paradigm of v2 is now a simple extraction under the hood of v3.

        V2 came out in 2016. The number of apps written before v2 is minuscule compared to even newer JS frameworks of today.

        I would argue that Vue has been one of the most stable frameworks in JS world and that stability and focus on simplifying the state mental model (aka, it just works) has been the reason for Vue’s continued steady growth across organizations and projects of all sizes.

        • Etheryte 2 days ago

          I'm not really sure if I can agree on stability. For all its warts and flaws, you can largely still write React 18.x the same way you wrote React 0.x. There's many new features and fancy tools in your pocket, but underneath it all, you can take the knowledge you had of 0.x and go straight to writing 18.x. It might not be whatever is the current vogue best practices, but it will work. While React has had many breaking changes over the years, I would argue that all of them are fairly minor, whereas Vue, Angular and now Svelte have introduced big breaking changes. Stability wise I feel like React comes out on top in that regard.

          I do agree that Vue is clearly the better paradigm, but unfortunately it's still very much lagging behind React in terms of adoption. I think big breaking changes might have a considerable part in that, it's hard to sell that upwards.

    • pjmlp 2 days ago

      And in 10 years I only took part in a single project using it, back in 2019.

      I would put Vue on third place of FE JavaScript frameworks.

tglide 2 days ago

> Runes Only Work in Svelte Components or .svelte.ts Files

This is like complaining that types only work in .ts files

> Hooks Using Runes Must Wrap State in Functions

This is on purpose, as you know. They want reactivity to be explicit. The benefit of runes is, that if you like Vue and Solid so much, you can literally create their reactive primitives in Runes, and it works.

> Classes as First-Class Citizens for Runes... or Not?

This entire section is weird. The title complains about classes, but then the second code snippet is a function back again. And the third is also equally weird, why would you ever need that.

> Svelte Templates Include Features That Cannot Be Implemented in JavaScript

This one I don't know sufficiently about. I'll let others argue about it. But I do think this was already present before

> Form Components Are Uncontrolled by Default, Which Can Cause Issues

Same here, Svelte always had this behavior. As you also state, this is present in other frameworks, such as Vue itself, which you're promoting as better than Svelte

> Ecosystem

If you want someone to point out the issues people had when migrating to Vue3, and still have to this day, sure. Every framework really, when they go through such a big change.

> Community Response

Criticism is fine. But a lot of the things have been discussed over and over tbh, and a lot of it is poorly structured, e.g. saying "svelte is react now", which just brings noise to the table. I've personally seen a lot of other criticism which has led to action being taken.

As a proof of that, recently here in hacker news there was a post criticizing Svelte 5. It is now mentioned on this PR as a change for it https://github.com/sveltejs/svelte/pull/15469

I do criticize things in Svelte as well, e.g. I do like the patterns for passing reactivity through boundaries, but I do think it needs to be well documented on how to, as people can get a bit lost. Or maybe some utilities shipped to it. But I don't personally like `ref` and `createSignal`. They come with their own issues.

  • rxliuli 2 days ago

    > This is like complaining that types only work in .ts files

    It reminds me that React hooks must start with "use," which is a very strange thing, no matter how they explain it. Additionally, I mention this because Vue 3/SolidJS, which also uses proxies, does not require you to use special file names; you can use it in any regular JS.

    > This is on purpose, as you know. They want reactivity to be explicit. The benefit of runes is, that if you like Vue and Solid so much, you can literally create their reactive primitives in Runes, and it works.

    It just adds extra boilerplate work. Unless you use a custom Proxy to wrap the runes state, I don't think it's possible to implement the Vue Composition API, and if you do that, there will be a double proxy, and even $state.snapshot won't save me.

    > This entire section is weird. The title complains about classes, but then the second code snippet is a function back again. And the third is also equally weird, why would you ever need that.

    Because the escape hatch left by svelte5 is very strange and seems inconsistent, in the four situations I listed, svelte5 can only make half of them effective, while vue3 and similar frameworks can make them all work properly.

    > Same here, Svelte always had this behavior. As you also state, this is present in other frameworks, such as Vue itself, which you're promoting as better than Svelte

    Yes, it has always existed, but svelte5 still hasn't addressed it. Also, I don't think vue3 is better than svelte4 because I believe their APIs are very different and not easy to compare. The runes API of svelte5 looks very familiar, and I will certainly try to compare them.

    • tommyquant 2 days ago

      > It reminds me that React hooks must start with "use," which is a very strange thing, no matter how they explain it. Additionally, I mention this because Vue 3/SolidJS, which also uses proxies, does not require you to use special file names; you can use it in any regular JS.

      You can name hooks whatever you want. The `use` prefix is just a linting thing. Once transpiled to JS, there isn't really any way for React to know whether you prefixed your hook with `use`.

      I understand the mistake though. The React docs state `You must follow these naming conventions` when talking about the `use` prefix. But that's all it is -- a convention.

teekoiv 2 days ago

I very much agree with the overall thesis of the post. Runes are just irksome in subtle ways.

One big point that the post misses, is that the Class escape hatch for runes is incompatible with constructor-set parameters.

Say you have a class that wraps a HTMLElement which you set in the constructor. This doesn't work:

  class Wrapper {
    dom: HTMLElement = $state()
    constructor(el: HTMLElement) {
      this.dom = el
    }
  }
as TypeScript throws an error about `Type 'undefined' is not assignable to type 'HTMLElement' for the $state()`. You could fix it by eg. `$state(undefined as unknown as HTMLElement)` but that's dumb. Interesting enough you could do something like:

  class Wrapper {
    dom: HTMLElement
    constructor(el: HTMLElement) {
      let d = $state(el)
      this.dom = d
    }
  }
Moreover, Vite/esbuild mangles class-field parameters with esnext into constructor-set parameters as they are just more versatile. So the original code becomes something like:

  class Wrapper {
    constructor(el: HTMLElement) {
      this.dom = $state(el)
    }
  }
Which is incompatible with rules of runes. I did whine about this already https://github.com/sveltejs/svelte/issues/14600 but so far no clear answer
  • _benton a day ago

    I agree with everything in the post but I still like using Svelte. We've adopted our own Store class and decorators which eliminates some of the issues in the post.

        class Wrapper extends Store {
            @state() accessor dom: HTMLElement;
            constructor(el: HTMLElement) { this.dom = el; }
        }
    
    The advantages here are that a) we don't need the .svelte.ts postfix and b) @state() makes TS support flawless with runes. And since we only use classes for state, most of the other objections in the post are mitigated. On the bindable issue, we simply just don't use that feature - one way dataflow ftw! :)

    I'm not saying Svelte 5 is flawless at all, but I think we found an approach that minimizes the downsides. The upside is really good performance and a metaframework that makes the most sense out of all the current options.

    • braebo 17 hours ago

      Oh wow, so this still works even though Svelte doesn't support TypeScript features that aren't just type annotations (like decorators)? Is that because you're outside of `svelte.ts` files so the compiler never touches them?

      • _benton 11 hours ago

        Yeah it works fine with the latest sveltekit. You do need to set { esbuild: target: "es2022" } in the vite config to enable JS decorators but that isn't specific to svelte. These aren't TS decorators, they're ecmascript decorators (https://github.com/tc39/proposal-decorators) which are at stage 3 and being adopted by JS runtimes.

        Under the hood the class is just creating a hidden property with $state({}) and the accessors are reading/writing to that property. Since $state() creates a deeply reactive object it acts the same as marking individual fields with $state().

  • beremaki 2 days ago

    > You could fix it by eg. `$state(undefined as unknown as HTMLElement)` but that's dumb

    I think the generic is what you are looking for

      class Wrapper {
        dom = $state<HTMLElement>();
        constructor(el: HTMLElement) {
          this.dom = el;
        }
      }
    
    the dom property will still be HTMLElement | undefined, if the 'undefined' bothers you have to add an exclamation mark and write "$state<HTMLElement>()!"
    • Etheryte 2 days ago

      That's still a manual type assertion though, and if a regular usage pattern demands one, then the library is doing it wrong. Regardless of how you annotate it, every manual override reduces the effectiveness of the type system.

  • hmry 2 days ago

    Use $state()! to fix the undefined is not assignable error.

KolmogorovComp 2 days ago

All these irks to avoid redraw()ing when needed

bhaney 2 days ago

I didn't even know there was a Svelte 2

  • elaus 2 days ago

    I think people usually only talk about "Svelte", but that doesn't really imply a "Svelte v1". So it's very plausible to miss the existence of major versions of not working with it.

  • ilrwbwrkhv a day ago

    Earlier svelte was:

    let x = 10

    <div>{x}</div>

    x = 12

    now the div changes.

    It had its own unique, clean way of doing things and had its own identity.

    Now they went down the route of looking like exactly like the others while doing everything much worse.

    Of course a bunch of people keep telling me that yeah, this is much better. But they are brainwashed.

DannyBee 2 days ago

I use svelte a lot, because react's rules and such tend to drive me nuts.

It's not that i can't get used to them, it's that i just don't want to have to deal with them when they exist mainly because it made it easier to implement, not easier to use. It just gets the balance wrong for me. To each their own. I've met people who love them.

Some of these arguments resonate, some don't.

In the case of Svelte 5, it is (unfortunately) easier to understand if you look at the post-compiled code. Which often makes it totally obvious what is going on and what works or doesn't. Which is not great. It also often issues error messages that remind me of C++ 20 years ago in their unhelpfulness, before a lot of time was spent making the error message better. For example, I walked the tanstack folks through an example of generated code, because totally reasonable and smart people have trouble wrapping their head around what happens under the covers and what the error messages mean: https://github.com/TanStack/table/pull/5943

IMHO, trying to teach people this level of idiosyncrasy is a bit silly, and regardless of theoretical benefit, seems unlikely to work long term. It feels like there is not enough compiler help here to make it feel really magical, though at a glance it looks like their good be. I hope they adjust this.

I also agree the community is frustrating to deal with a not insignificant amount of time. There are lots of good people, mind you, but also lots of "you are holding it wrong", etc. I reported what is a blazingly clear bug (once you know it exists):

Svelte5 ships two incompatible Snippet types because of the use of unique symbols for SnippetReturn. Different unique symbols are never compatible in TS.

So these two SnippetReturn types (which are then used in the Snippet type in each file):

  rg "SnippetReturn.*unique symbol"
  types/index.d.ts
  268:    const SnippetReturn: unique symbol;

  src/index.d.ts
  271:declare const SnippetReturn: unique symbol
are incompatible.

The error message you get if you trigger this is .. hilarious and hurts your brain (the two syntax highlighted types in this picture that look 100% identical are not compatible, one is from types/index.d.ts, one is from src/index.d.ts) - http://tiny.cc/wnkc001

I also reported a bug to the typescript folks about the error message.

The difference in how the triagers handled it were night and day. Amusingly, the svelte side has a bog simple and obvious fix - share the (typeof'd) unique symbol type between the two files so there are not two unique symbols. 5-10 line fix, at most. You just have to decide how much to share (IE just SnippetReturn or the whole Snippet type, or what). In the vast majority of projects i work on, someone would look at this, go "oh shit yeah we fucked that up whoops", fix it with the 10 line fix, and move on. There is absolutely zero reason or advantage to have the code like this. It is an obvious bug, it should be fixed, it's not worth a lot of time. But after many messages, I actually gave up on the svelte bug. To be fair i clearly got frustrated but man not a great experience ....

Compare to typescript - the typescript side requires work to issue a good error message here, and more thought.

Yet I'm in the midst of finishing a changelist on the typescript side to improve the compiler error message, because the experience dealing with the community was so much better.

Plenty of people I talk with have some story like this with Svelte :(

I will say, some of the other complaints here seem weird. SVAR grid works fine for tables. It supports variable heights and widths for columns. Maybe they specifically want unstyled tables? I dunno.

The usual ui complaint for svelte is not grid, but good tree components. They also pick a few things they admit are not unique to svelte, and exist in other popular frameworks. Seems like a weird shot

Also, complaining about file naming and "unpleasant code infection" is also weird.

The other arguments seem much stronger - the lawyer in me wants to yell "put your arguments in order of strength, and remove the weakest ones. Quality wins over volume, and most people are not going to read the whole thing". If i'm really trying to make an effective argument, i make short ones, not long ones. On HN i'll do longform because i don't care enough most of the time to spend the time editing to make it effective. But if i was really trying to be convincing i would make much shorter ones.

In any case, i think some of this is reasonable. But having spent lots of time with frameworks, i'll keep using Svelte5, but I do hope things improve. I feel like i'd spend the same amount of time with other idiosyncrasies if i moved to Solid.

  • rxliuli 2 days ago

    > I also agree the community is frustrating to deal with a not insignificant amount of time. There are lots of good people, mind you, but also lots of "you are holding it wrong", etc. I reported what is a blazingly clear bug (once you know it exists):

    Yes, when I posted this content on Reddit, someone immediately brought up "Svelte's reactivity doesn't exist at runtime" to refute me, which isn't even a valid argument in Svelte 5. https://www.reddit.com/r/sveltejs/comments/1j6ayaf/comment/m...

    > put your arguments in order of strength, and remove the weakest ones. Quality wins over volume, and most people are not going to read the whole thing

    I did remove some of them, such as the issue of "data ownership," which is the first time I've heard this term outside of Rust's web framework, but it was just a warning, not a blocking issue, so I deleted it. https://svelte.dev/docs/svelte/runtime-warnings#Client-warni...

    > In any case, i think some of this is reasonable. But having spent lots of time with frameworks, i'll keep using Svelte5, but I do hope things improve. I feel like i'd spend the same amount of time with other idiosyncrasies if i moved to Solid.

    Yes, the current project has been underway for 3 months, and I won't replace the entire web framework now, but I will definitely consider whether there are better options for the next project.