- had a 3 year head start on Svetle (2013 vs. 2016)
- has major engineering orgs behind it. Facebook started it. Microsoft makes it work with Typescript.
- is easier to get started with. While JS-compilation is common, it's required for Svetle.
Svelte isn't free of pain points. Like any form of magic, it has edge cases. It's better but not "better enough" to de-throne React.
Svelte trades off runtime size for component size. It was created in the context of infographics for the New York Times online and for projects that roughly line up with that it's pretty much the technically best option.
I like the Svelte authoring experience and introduced it for a few components in a React based low-code platform. The reason I phased it out was a chat component that was ~600 LoC and 50-something reactive variables in a moderately complex chain blew up into ~5k LoC of output. I also ran into what seemed to be some transient invalidation issues. I was short on time to debug this and engage with the Svelte community so I rewrote it in React to match the rest of the system. It's possible I was doing something wrong but I don't have enough confidence to bet on 3.x again. I'll take another look when 4.x comes around.
> Presumably if Svelte were the be-all-end-all of front-end frameworks, it would dominate soon enough?
There's significant network effects around the established frameworks. Nobody gets fired for picking React. I personally think Solid is the best overall technically but the ecosystem and mindshare is smaller and that matters to a company making a business and not necessarily technical decision.
It sounds to me like you didn’t understand the details of Svelte’s reactivity model, which are very important, and fairly straightforward to learn, but different from what people are commonly used to—and so even if you theoretically learn the model, it may take time in more complex cases for it to come naturally. The crux of these sorts of problems tends to be that reactivity is a property of bindings, not data; and as a secondary effect, mutation is therefore rather hazardous.
> 50-something reactive variables in a moderately complex chain
It sounds also like you’re fighting the framework. I’ve seen stuff like what you describe in some React libraries (e.g. mirroring something DOMmy in React—common, but I hate it because it’s so much mindless duplication, among other faults), but in Svelte at this scale you’re likely to get better results from seeing if you can bag things together (e.g. let x = {a, b, c} rather than let a, b, c), or passing through components rather than reactive variables. But these are vague concepts which may not actually be relevant or applicable.
Svelte is a framework that definitely requires that you work with it, or you’ll have a miserable time, whereas with React you can, to a much greater extent, do awful things and get away with it.
And when you speak of 3.x and 4.x and such—there’s basically no chance any of this stuff will ever change in Svelte, it’s too fundamental. In some cases you might end up with better compiler warnings, but that’ll likely be the extent of it.
This is a reasonable assumption given what I've described. It's been almost two years but from what I remember the problem was updating what should have been the same reactive binding in two different locations. When trying to debug a problem I was stepping through the code and noticed that the indicies passed to `$$invalidate` were different. Checked for typos and shadowed declarations and found none. Rolled back to checkout and found the indicies matched. In the process of undoing/redoing my conclusion was that the introduction of an unrelated reactive binding was the difference. I could have been wrong; I was pretty exhausted at that point.
> It sounds also like you’re fighting the framework.
Sure. In this case it was getting a big chunk of JSON back from an endpoint I didn't control and trying to use a number of reactive variables to select out pieces for display. I've done similar things in a half dozen other reactive/FRP libraries without issue but I assumed I was off the beaten path in Svelte.
I realize that this is empty complaining about other peoples' hard work. I don't have the code any more and I don't have a reproducible test case so I have no problem with anybody waving this off.
Also, your component sounds cumbersome.
I also do a lot of code generation, and my absolute goal is to have it write code that I’d write if I were doing it by hand. That’s pretty key for me. If the output is better, then good. If the output is doing a bunch of stuff it doesn’t need to be doing because it’s taking my specific use case and making it conform with its own model for doing generic things, I don’t like it.
I was a web developer back when tables for layout, HTML attribute soup for styling, and applets for interactivity were going out of fashion. Semantic HTML and CSS for layout and styling and JS for interactivity were coming into fashion. Divs for layout, class soup for styling, and JS frameworks for interactivity hadn’t yet become mainstream when I stopped.
So my default is lean HTML, lean CSS, raw JS. Maybe JQuery if needs be. It’s an outdated default, but it’s mine. The thing is, I get great load times and performance for what I need. What I need is normal dashboard stuff - though because of the nature of the field I work in, it condenses a lot of information onto a page and that information is updating many times per second.
I don’t seem to get enough performance from the frontend frameworks I’ve tried. I don’t know if it comes from code bloat, or deep call stacks through god knows how many levels of indirection, the way DOM updates are issued, or something else - but it has just never seemed worth the learning curve to end up with something I can’t do myself with admittedly a lot of work.
As such, I find this review helpful. Svelte has caught my attention and I want to give it a go, but if the output is bloaty then that’s a red flag for me. If it’s bloaty because it isn’t doing backflips through the call stack, but is inlining code - that’s familiar territory and certainly something I can deal with.
This is fine but having spent a decade of my career doing this, I would never advocate for it in an app with any kind of frontend complexity or a chance to grow into it. The frameworks mostly obviate the need to understand layout thrashing, resource cleanup, and retained state conflicts in the DOM. If you're doing simple stuff these don't matter but they're challenging to fix and more challenging to stay fixed when a group is contributing.
> Svelte has caught my attention and I want to give it a go, but if the output is bloaty then that’s a red flag for me
Your use case is a pretty good fit for Svelte and you're likely to get output you'd find acceptable and given your preferences I think you're more likely to prefer its sensibilities over other frameworks that could provide the perf you're looking for. The tradeoff is kind of like the tradeoff between monomorphization vs virtual dispatch. The Svelte compiler is basically inlining the update code instead of using shared code in a runtime.
Svelte's whole shtick is using ASTs from the compiler to stuff at compile time where possible, to reduce bundle size and complexity.
This one, id wager. There isn’t necessarily anything wrong with your approach but Id agree that you should try svelte for this reason.
I was advocating/piloting a new framework in the app and was unhappy with the output versus the input and perceived complexity. I spend a significant fraction of my time cleaning up performance issues. A good chunk of that is download size so I care in general about what I'm sending across the wire.
> Also, your component sounds cumbersome.
Sure. It was the classic feature creep scenario.
For example:
const cells: Record<string, ReactNode> = { a: "hello world", b: <>hello <b>world</b></>, c: <Icon src="world.png" />}
The closest you could get in Svelte, is creating three new components (3 entire files), which are then rendered using `<svelte.component this={HelloWorldComponent} />`.This becomes a problem, when you build composed components that decide their layout based on logic thats too complex to express in CSS or Sveltes templating system.
For example:
- A component for tabbed navigation that automatically becomes a sidebar on desktop.
- React Router defining its entire navigation tree [1]
- Ant.Design defining the columns of the table, where you can trivially supply a short callback to render a cell [2]
[1]: https://reactrouter.com/en/main/routers/create-browser-route... [2]: https://ant.design/components/table
The automatic handling of dependencies and recomputing means you have less control over how updates work.
Also I think it is important to understand the mutations going on in your ui. Having them explicit like in Vue makes it easier to understand what is gonna happen by looking at the code versus the implicit way that Svelte uses.
Instead of easy-to-trace functional logic and pure functions you have a thing more like an electrical circuit, or like a highly advanced jQuery contraption. It's fine and even great for smaller bits of interactivity. It becomes increasingly unwieldy as the scope grows.
(And for tiny bits of interactivity there is HTMX, wonderful in its own way.)
Implicit 2 way data binding which makes logic hard to follow in larger projects, same with their reactivity model.
Is the 2 way data binding implicit? As I understood, you need the "bind:" keyword for 2 way data binding.
JSX is the best templating language.
Svelte hides complexity and this can bite you in tracking down issues.
React just feels better to me for a professional project, though I like Svelte.
Some types of errors cause your application to halt (which might feel like a UI freeze). There's no way to catch these errors and show an error page, show an error message, or report the error to an error tracking service like Sentry. I'm subbed to the github issue for this and never saw a fix.
Poor composability of components. Components in svelte are awesome in the general sense, they're just missing this higher-level code organization possibility that react, solidjs, and vuejs users have cozy versions of.
The docs claimed a specific function worked like nuxt's asyncData function. Whoever wrote that has no idea what nuxt's asyncData function does, because that function worked very very very differently.