My experience with using Svelte 5 in production the last few months is that while runes are an upgrade to the magic of previous Svelte versions, it's still too much magic to easily reason about complicated state. This seems like it just adds to the mental overhead. Harris says it's "sacrificing a little bit of purity in service of pragmatic goals" but I don't find it very pragmatic to be debugging glitches, lost reactivity etc which I find myself doing exponentially more as our project grows. The compiler definitely makes simple code snippets look pretty but there was a reason the magic syntax didn't find itself in Vue[1], which in my limited experience has a much more intuitive reactivity model.
Agh, I understand why runes were implemented, but I still can't get myself to like them. It feels like Runes take away from what made Svelte Svelte (the simple, concise syntax), and changes like this seem like slow concessions back in that direction anyway.
I felt the same way at first, but even in my small project, I've come to greatly appreciate them—or at least what they seem to enable. I've found deeply nested bindings to work without a hitch, which wasn't always the case in Svelte 4.
You just have to build a big project with Svelte 5 and you will come to like them.
A lot of magic is okay for simple application, but when you want to build anything that scales Svelte before runes was just horrible. With Svelte 5 and Runes you can look at any component and instantly know what it does. You couldn't do that with Svelte 4 unless you wrote the whole code yourself.
I think that's actually the core of the problem. It's the right choice for big projects. But Svelte was an absolute joy to use when brewing up a small or medium size project that you want to just work first time.
Runes are the right choice for the library, but there is still a loss there.
Not sure I agree. I’ve built numerous small projects in Svelte 3 & 4, sharing that same joy many of us had! Stores were generally amazing.
I was highly skeptical of runes upon the original announcement and very cursory usage during beta phase.
When I finally got to porting a couple simple projects, I shrugged “this isn’t too bad, but what’s all the fuss?”.
I ported a mid size project and it really clicked.
Then I went to build a brand new small project, and I found myself in love with runes. Having spent the time to get under the hood (especially using them as classes), being able to leverage them during the design phase really sped me up and facilitated cleaner/better state management.
They really are an improvement. Tracking data flow in a complicated component (bound props going in both directions, derived state, …) was terrible before runes — you just had to rely on compiler magic, which worked until it didn’t. Now it’s more or less obvious.
I wish they had found a way to make the compiler just work. No longer having the ability to update the DOM by updating bound variables eliminates one main reason I wanted to use Svelte in the first place. I still love SFC though.
You can't just set a variable anymore, you need to use runes. Which is silly - I shouldn't need to tell Svelte this is reactive, any variable referred to inside the HTML in the component is logically reactive and Svelte should know this. Like it used to. This is why we had a compiler.
I should point out that indeed (as you're correctly pointing out) updating bound variables looks the same, just that declaring them sucks. I don't really trust they won't do similar things to updating bound variables though.
On the one hand, yes, it's annoying to have to explicitly declare state. On the other hand, it's much easier and clearer to declare derived state now. Pre-Svelte 5 code had a lot of this:
let someState = someOtherState.thing;
$: someState = someOtherState.thing;
Which was awful.
Svelte 5 does still have a compiler, and there's still a lot of "magic" involved — it just asks you to be more explicit about your intentions in some cases. Of course in an ideal world it could just figure it out, but some distinctions (do I want this variable to always update when its dependencies change? or do I just want to set an initial value based on the dependencies?) need to be specified explicitly, and I prefer clear syntax for that explicit specification over the terrible, verbose hacks that you used to have to use in order to prod the compiler "magic" in the right direction.
I was a runes hater, then I bit the bullet and migrated a big app to Svelte 5. Now I get it. You should give them a chance as well.
> Of course in an ideal world it could just figure it out
Yep. We're agreed there.
> I want this variable to always update when its dependencies change? or do I just want to set an initial value based on the dependencies?
Reasonable to default to first, ask the developer to be explicit about the second if needed.
Honestly I still love SFC and Svelte having opinions about CSS and state storage is great. But it feels like this was the wrong direction. The 'magic' is why we used Svelte.
Edit: I think my tone here is a little off due to illness. Sorry if I sound grumbly. Wasn't my intention.
He’s been discussing writable memos for Solid 2.0 off and on for a bit. While the other response is right that you can roll your own, it seems pretty likely this will be a first class thing in Solid too.
I’m currently building the back-end for my startup in C# using EventStoreDB and CQRS. I have an initial front-end application written in Svelte from two years ago as a PoC. It was a treat writing and designing it and I can’t wait to do a second pass with all these awesome Svelte updates!
Since Svelte 5 was announced, we began using our own library for state management as we could not fully understand the semantics and were afraid of potential changes. If you're curious, here it is: https://github.com/okcontract/cells
It is compatible with both Svelte 4/5 and more importantly pure TS libraries.
I'm almost finished with a large, complex app written with Svelte 5, web sockets and Threlte (Three JS) [0]. Previously, I'd written React for about a decade, mostly on the UI side of things.
I vastly prefer Svelte, because of how clean the code feels. There's only one component per file, and the syntax looks and writes deceptively like vanilla JS and HTML. There's a bit of mind-warp when you realize Svelte doesn't want you passing components with props as props into another component. Svelte gives you "Snippets" instead, which work for some reusability, but are limited. It sort of forces simplicity on you by design, which I like. Most of React's deep nesting and state management doesn't exist in Svelte and is replaced with simple, better primitives.
The bigger gain though for me was Svelte(kit) vs. Next JS. It's very clear what is on the server and what is on the client, and there's none of that "use client" garbage with silly magic exports for Next JS things. The docs are great.
Svelte's biggest disadvantage is that the UI library ecosystem isn't as large. For me that wasn't as big of an issue because it was my expertise, but everyone else looking for a drop in UI library will find the Svelte versions a little worse than their React counterparts.
Because svelte is compiled, it also is by default very snappy. I think choosing Svelte would likely give most devs a speed boost vs. the spinner soup that I've seen most React projects become. A lot of that is going to be in the skill of the programmer, but I love how fast my app is.
Yeah, this is SvelteKit's biggest weakness. Easy to write code that seems to work until some unusual confluence of circumstances makes it run on the client when you've always tested it on the server, or vice versa, and it breaks. I still really like it for personal projects, but I think I'd want a clearer client-server separation for anything more complex.
Maybe things have changed now or I was just a bad react dev but the way hooks works kinda force you to have many child one-off components to not trigger rerenders in the whole component when only a small part was connected to that part of the State being updated. Having all these one-offs components in different files was painful.
Unfortunately some of us work with other people, and refusing to let them merge code we don't personally agree 100% with is a great way to stop working with other people :)
I also don't really see why this is a positive. If you have too much in a file, then split it off? It doesn't fundamentally add or subtract and complexity either way.
I think Svelte likely has a lot of benefits over React but I feel like this is a negative. It's easier for locally of code to keep related components together, and they can always be put into their own files later.
I'm not a developer by trade, and have gone from 0 full-stack knowledge to building a MVP for my startup in 18 months using Svelte 4 and SvelteKit. Looking at the JS/TS ecosystem from the outside, it was a total nightmare and Svelte 4 was the only framework that seemed to make logical and aesthetic sense to me.
Currently porting to Svelte 5 and it is less elegant in my opinion, but perhaps the problems it tries to solve are for more sophisticated developers and I don't really come across them or have knowledge of them. I would prefer to stay on 4, but I will take Rich's word for it that it will be better long term.
Admittedly complicated components with lots of reactivity can be confusing to follow data changes with lots of $: lines so I have tried to minimise that from the beginning. The Svelte 5 code looks cleaner to follow for onboarding devs that aren't familiar with our codebase yet.
pretty good. some people in my team don’t like svelte magic and wish we were using react but others say, and i quote, “damn this is clean” or “almost effortless it just works” and i’ve seen again and again engineers ramp up pretty fast compared to my Knockout, Angular, or React times…
Pretty happy! Just wished they didn’t change their “magic” so often, but it’s the price to pay for innovation—if we can even call frontend development that, which I think we should but many frontend haters around here
As much as I appreciate Svelte, the React devex is unmatched. I built a client-side app using Wails with Svelte 5 and I found myself wanting React's seamless devex and vast ecosystem. Once I migrated over to React it was like a huge handicap was lifted.
Svelte is great. But if you're in a time crunch and you don't have a specific technical requirement that makes React a bad match, I don't think Svelte is worth it. A big part of the Svelte ecosystem is still using Svelte stores, and I found the "one component per file" paradigm to be a bit limiting.
> A big part of the Svelte ecosystem is still using Svelte stores
Just a nitpick, with runes in Svelte 5, stores have largely become obsolete. $state, $derived, and $effect replace most of the needs people would normally use stores for.
That's fair. The major libraries I use migrated to runes even before Svelte 5 was officially released. You can use runes with Superforms[0] as any store-based API can have rune-based reactivity passed to it, but it sounds like using runes internally is a V3 milestone.
I'll add devex extends to TSX/JSX itself too, the editor support and language server experience is miles ahead. Alternative formatters/linters like Deno, Biome, oxc etc. all have great support out of the box too, not so much for svelte.
For when react is a bad match; I'm investigating solid instead for this reason.
The svelte ecosystem is in a particularly unfortunate spot right now comprising of single/few author projects that were starting to stabilise but now have a svelte 4 -> 5 migration shaking things up.
I think Syntax.fm mentioned that the automatic migration tool 4->5 was excellent, and even for larger codebases everything almost immediately worked after conversion, with maybe just a few LoC changes they had to do manually.
And for catching up on what a 'rune' is.. that's the `$derived` and `$effect` there, basically $-prefixed built-in things? Has that entirely replaced `$:` or is it as well as? Svelte seems to have got more complicated since I last used it!
Honestly, it's simpler than it was. There were many cases in which `$:` wouldn't work the way you might expect; meanwhile, $derived et all seem to always work without a hitch. It definitely looks less elegant, but I like it much more.
before this change, derived values were readonly (it makes sense because, if you change the derived value, what's going to happen to the underlying value ?) but now they are writable.
My experience with using Svelte 5 in production the last few months is that while runes are an upgrade to the magic of previous Svelte versions, it's still too much magic to easily reason about complicated state. This seems like it just adds to the mental overhead. Harris says it's "sacrificing a little bit of purity in service of pragmatic goals" but I don't find it very pragmatic to be debugging glitches, lost reactivity etc which I find myself doing exponentially more as our project grows. The compiler definitely makes simple code snippets look pretty but there was a reason the magic syntax didn't find itself in Vue[1], which in my limited experience has a much more intuitive reactivity model.
1: https://news.ycombinator.com/item?id=37592471
Agh, I understand why runes were implemented, but I still can't get myself to like them. It feels like Runes take away from what made Svelte Svelte (the simple, concise syntax), and changes like this seem like slow concessions back in that direction anyway.
I felt the same way at first, but even in my small project, I've come to greatly appreciate them—or at least what they seem to enable. I've found deeply nested bindings to work without a hitch, which wasn't always the case in Svelte 4.
You just have to build a big project with Svelte 5 and you will come to like them.
A lot of magic is okay for simple application, but when you want to build anything that scales Svelte before runes was just horrible. With Svelte 5 and Runes you can look at any component and instantly know what it does. You couldn't do that with Svelte 4 unless you wrote the whole code yourself.
I think that's actually the core of the problem. It's the right choice for big projects. But Svelte was an absolute joy to use when brewing up a small or medium size project that you want to just work first time.
Runes are the right choice for the library, but there is still a loss there.
Not sure I agree. I’ve built numerous small projects in Svelte 3 & 4, sharing that same joy many of us had! Stores were generally amazing.
I was highly skeptical of runes upon the original announcement and very cursory usage during beta phase.
When I finally got to porting a couple simple projects, I shrugged “this isn’t too bad, but what’s all the fuss?”. I ported a mid size project and it really clicked.
Then I went to build a brand new small project, and I found myself in love with runes. Having spent the time to get under the hood (especially using them as classes), being able to leverage them during the design phase really sped me up and facilitated cleaner/better state management.
I agree. I ported a non trivial project last year from 4 to 5 and runes are a game changer.
They really are an improvement. Tracking data flow in a complicated component (bound props going in both directions, derived state, …) was terrible before runes — you just had to rely on compiler magic, which worked until it didn’t. Now it’s more or less obvious.
I wish they had found a way to make the compiler just work. No longer having the ability to update the DOM by updating bound variables eliminates one main reason I wanted to use Svelte in the first place. I still love SFC though.
> No longer having the ability to update the DOM by updating bound variables
What do you mean by that?
In Svelte, traditionally, changing the value of a variable updates DOM elements using that variable.
Right, and what makes you think you can't do that in Svelte 5?
The release announcement? https://svelte.dev/blog/svelte-5-is-alive
You can't just set a variable anymore, you need to use runes. Which is silly - I shouldn't need to tell Svelte this is reactive, any variable referred to inside the HTML in the component is logically reactive and Svelte should know this. Like it used to. This is why we had a compiler.I should point out that indeed (as you're correctly pointing out) updating bound variables looks the same, just that declaring them sucks. I don't really trust they won't do similar things to updating bound variables though.
On the one hand, yes, it's annoying to have to explicitly declare state. On the other hand, it's much easier and clearer to declare derived state now. Pre-Svelte 5 code had a lot of this:
Which was awful.Svelte 5 does still have a compiler, and there's still a lot of "magic" involved — it just asks you to be more explicit about your intentions in some cases. Of course in an ideal world it could just figure it out, but some distinctions (do I want this variable to always update when its dependencies change? or do I just want to set an initial value based on the dependencies?) need to be specified explicitly, and I prefer clear syntax for that explicit specification over the terrible, verbose hacks that you used to have to use in order to prod the compiler "magic" in the right direction.
I was a runes hater, then I bit the bullet and migrated a big app to Svelte 5. Now I get it. You should give them a chance as well.
> Of course in an ideal world it could just figure it out
Yep. We're agreed there.
> I want this variable to always update when its dependencies change? or do I just want to set an initial value based on the dependencies?
Reasonable to default to first, ask the developer to be explicit about the second if needed.
Honestly I still love SFC and Svelte having opinions about CSS and state storage is great. But it feels like this was the wrong direction. The 'magic' is why we used Svelte.
Edit: I think my tone here is a little off due to illness. Sorry if I sound grumbly. Wasn't my intention.
I get why runes, but you're right. That simple Svelte I loved feels a bit further away now. Not sure how I feel about it long-term.
Agree. Loved Svelte, but after the update I made the switch to React and can’t imagine going back outside of small, static viz apps.
Wow, the optimistic UI example is so simple: https://svelte.dev/docs/svelte/$derived#Overriding-derived-v...
I wonder what Ryan Carniato, the author of Solid, thinks of it.
Implementing a settable derived primitive like that is already possible in SolidJS userspace. You can roll your own or simply use https://primitives.solidjs.community/package/memo#createwrit....
He’s been discussing writable memos for Solid 2.0 off and on for a bit. While the other response is right that you can roll your own, it seems pretty likely this will be a first class thing in Solid too.
I love runes, I love svelte 5, I love sveltekit.
Together, they offer a seamless entry into development, allowing you to swiftly grasp concepts akin to JS/HTML.
Other options require a significant learning effort.
Wish it came earlier...
I’m currently building the back-end for my startup in C# using EventStoreDB and CQRS. I have an initial front-end application written in Svelte from two years ago as a PoC. It was a treat writing and designing it and I can’t wait to do a second pass with all these awesome Svelte updates!
Since Svelte 5 was announced, we began using our own library for state management as we could not fully understand the semantics and were afraid of potential changes. If you're curious, here it is: https://github.com/okcontract/cells
It is compatible with both Svelte 4/5 and more importantly pure TS libraries.
People who have migrated a large enough production codebase to Svelte 5, what's your devex like?
I'm almost finished with a large, complex app written with Svelte 5, web sockets and Threlte (Three JS) [0]. Previously, I'd written React for about a decade, mostly on the UI side of things.
I vastly prefer Svelte, because of how clean the code feels. There's only one component per file, and the syntax looks and writes deceptively like vanilla JS and HTML. There's a bit of mind-warp when you realize Svelte doesn't want you passing components with props as props into another component. Svelte gives you "Snippets" instead, which work for some reusability, but are limited. It sort of forces simplicity on you by design, which I like. Most of React's deep nesting and state management doesn't exist in Svelte and is replaced with simple, better primitives.
The bigger gain though for me was Svelte(kit) vs. Next JS. It's very clear what is on the server and what is on the client, and there's none of that "use client" garbage with silly magic exports for Next JS things. The docs are great.
Svelte's biggest disadvantage is that the UI library ecosystem isn't as large. For me that wasn't as big of an issue because it was my expertise, but everyone else looking for a drop in UI library will find the Svelte versions a little worse than their React counterparts.
Because svelte is compiled, it also is by default very snappy. I think choosing Svelte would likely give most devs a speed boost vs. the spinner soup that I've seen most React projects become. A lot of that is going to be in the skill of the programmer, but I love how fast my app is.
[0]: https://bsky.app/profile/davesnider.com/post/3lkvum6xtjs2e
>It's very clear what is on the server and what is on the client.
Is it though? Your `+page.svelte` is rendered on the server as well. Not only `.server.` is run on the server.
Yeah, this is SvelteKit's biggest weakness. Easy to write code that seems to work until some unusual confluence of circumstances makes it run on the client when you've always tested it on the server, or vice versa, and it breaks. I still really like it for personal projects, but I think I'd want a clearer client-server separation for anything more complex.
"There's only one component per file"
If you don't do this in React, its your own fault.
Maybe things have changed now or I was just a bad react dev but the way hooks works kinda force you to have many child one-off components to not trigger rerenders in the whole component when only a small part was connected to that part of the State being updated. Having all these one-offs components in different files was painful.
Unfortunately some of us work with other people, and refusing to let them merge code we don't personally agree 100% with is a great way to stop working with other people :)
I also don't really see why this is a positive. If you have too much in a file, then split it off? It doesn't fundamentally add or subtract and complexity either way.
I think Svelte likely has a lot of benefits over React but I feel like this is a negative. It's easier for locally of code to keep related components together, and they can always be put into their own files later.
Well. I think that's sort of what I like about Svelte. There's a lot less opportunity to make bad decisions.
I'm not a developer by trade, and have gone from 0 full-stack knowledge to building a MVP for my startup in 18 months using Svelte 4 and SvelteKit. Looking at the JS/TS ecosystem from the outside, it was a total nightmare and Svelte 4 was the only framework that seemed to make logical and aesthetic sense to me.
Currently porting to Svelte 5 and it is less elegant in my opinion, but perhaps the problems it tries to solve are for more sophisticated developers and I don't really come across them or have knowledge of them. I would prefer to stay on 4, but I will take Rich's word for it that it will be better long term.
Admittedly complicated components with lots of reactivity can be confusing to follow data changes with lots of $: lines so I have tried to minimise that from the beginning. The Svelte 5 code looks cleaner to follow for onboarding devs that aren't familiar with our codebase yet.
pretty good. some people in my team don’t like svelte magic and wish we were using react but others say, and i quote, “damn this is clean” or “almost effortless it just works” and i’ve seen again and again engineers ramp up pretty fast compared to my Knockout, Angular, or React times…
Pretty happy! Just wished they didn’t change their “magic” so often, but it’s the price to pay for innovation—if we can even call frontend development that, which I think we should but many frontend haters around here
I'm guessing Svelte 5 will last many years. Maybe they'll release v6 to drop old stuff but I don't think the runes paradigm will change any time soon.
Plus they need to invest some serious work onto SvelteKit...
As much as I appreciate Svelte, the React devex is unmatched. I built a client-side app using Wails with Svelte 5 and I found myself wanting React's seamless devex and vast ecosystem. Once I migrated over to React it was like a huge handicap was lifted.
Svelte is great. But if you're in a time crunch and you don't have a specific technical requirement that makes React a bad match, I don't think Svelte is worth it. A big part of the Svelte ecosystem is still using Svelte stores, and I found the "one component per file" paradigm to be a bit limiting.
> A big part of the Svelte ecosystem is still using Svelte stores
Just a nitpick, with runes in Svelte 5, stores have largely become obsolete. $state, $derived, and $effect replace most of the needs people would normally use stores for.
That's right; but a lot of packages, like Superforms, use stores.
That's fair. The major libraries I use migrated to runes even before Svelte 5 was officially released. You can use runes with Superforms[0] as any store-based API can have rune-based reactivity passed to it, but it sounds like using runes internally is a V3 milestone.
[0] https://superforms.rocks/examples?tag=runes
I think i'm about a chapter behind you.
I'll add devex extends to TSX/JSX itself too, the editor support and language server experience is miles ahead. Alternative formatters/linters like Deno, Biome, oxc etc. all have great support out of the box too, not so much for svelte.
For when react is a bad match; I'm investigating solid instead for this reason.
The svelte ecosystem is in a particularly unfortunate spot right now comprising of single/few author projects that were starting to stabilise but now have a svelte 4 -> 5 migration shaking things up.
I think Syntax.fm mentioned that the automatic migration tool 4->5 was excellent, and even for larger codebases everything almost immediately worked after conversion, with maybe just a few LoC changes they had to do manually.
Started out great and progressively degraded.
[dead]
As someone who has not used Svelte 5: What is the significance of his change?
https://github.com/sveltejs/cli/issues/487#issuecomment-2743...
And for catching up on what a 'rune' is.. that's the `$derived` and `$effect` there, basically $-prefixed built-in things? Has that entirely replaced `$:` or is it as well as? Svelte seems to have got more complicated since I last used it!
Honestly, it's simpler than it was. There were many cases in which `$:` wouldn't work the way you might expect; meanwhile, $derived et all seem to always work without a hitch. It definitely looks less elegant, but I like it much more.
https://svelte.dev/blog/runes
before this change, derived values were readonly (it makes sense because, if you change the derived value, what's going to happen to the underlying value ?) but now they are writable.