I gotta say, the “vibe” of the new $props syntax, to me, is awful.
I love that I can just use
export let prop;
because it’s just JavaScript.
The new runes syntax
let { prop } = $props
Is not. This just makes me incredibly sad.
Like all things, everyone is going to switch to the new syntax because it’s shiny, even though it objectively has a greater cognitive load (and IMO, looks ugly). My components are going to start looking like Svelte, rather than JavaScript.
The reason I prefer svelte over Vue is because there’s less to remember. Looks like I’ll be looking for a new framework after Svelte 5. Just like I did after Vue 3.
Also,
> Snippets are more powerful and flexible, and as such slots are deprecated in Svelte 5.
Removing slots, which feel really natural in HTML, with snippets - that are expressed as JavaScript values passed to a component - honestly, I don’t see the prioritisation of vibe, here.
These changes are going to make it so, so much harder to teach Svelte that I honestly feel despondent. I feel like svelte 5 has just totally forgotten that Svelte is supposed to feel like JavaScript. Super sad.
Because it’s introducing a magic global compiler directive - $props - that’s unique to Svelte.
Everyone knows what
export let prop = 10
means. But what’s $props? It’s a magical invocation (literally, a rune) of a compiler directive. So while it’s valid JS, it’s actually a signal to the compiler, with special behaviour. It’s something you need to learn and understand beyond just JavaScript.
Also, to your point, it’s not actually destructuring. This statement is declaring “prop” as a new property.
And finally, this statement actually does export “prop” to a user of the component. But that’s no longer explicit.
What? I mean that's technically syntactically correct JavaScript but it makes no sense outside of Svelte, and if the prop is not literally named prop like in your example here, it's much harder to understand what this is doing compared to taking a prop value out of a $props object (or rune or whatever), like you would in many other frameworks.
I'm just a bit surprised because while I like Svelte I feel like all of is like this, it's all technically JavaScript syntax but all of it is magic that only works through the Svelte compiler, and this new syntax actually looks slightly less so to me, although I wouldn't say I prefer it.
work in any JS module? I thought it was quite standard. Maybe I'm mistaken, JS/TS is not my first language, but I think it's pretty obvious what it's doing.
In any case,
let { myProp = 10 } = $props
does not even remotely work like it would in JS. It's literally a compiler directive.
That is, $props is not an object. The string "$props" is a compile-time directive that declares myProp to be a prop. It's not destructuring $props, it's declaring myProp. "$props" is a magic incantation defined within the Svelte compiler.
I mean, this is my point really. It's using JS syntax but it's no longer obvious what it's doing.
To your point, given that Svelte compiles the code anyway, I don't understand why they couldn't have kept the existing syntax ("vibe") and just changed the semantics. Why come up with some brand new, syntactically-compatible- but semantically-incompatible-with-JS, syntax?
What do you mean by "work"? You can export a mutable variable yes, but why would you? It makes no sense outside of Svelte and it doesn't relate to the rest of the code where you presumably use that variable as if it was set from the outside at the moment you were exporting it or something along those lines.
In the end it is also just a compiler directive for svelte, it doesn't end up in the code the svelte compiler outputs.
If you check the JavaScript output tab on right, this prop declaration in Child.svelte
> export let count = 0;
Has become
> let { count = 0 } = $$props;
Which looks a lot closer to this new rune syntax, so
> does not even remotely work like it would in JS.
Is not true at all, it works a lot like this in JS, or at least a lot more than the "export let" syntax.
Edit:
I want to add to your point here:
> That is, $props is not an object. The string "$props" is a compile-time directive that declares myProp to be a prop. It's not destructuring $props, it's declaring myProp. "$props" is a magic incantation defined within the Svelte compiler.
I get you on this!
I wasn't aware it worked like this and replaces the $$Props interface [1] which I am using to declare component props at the moment. I understand your point and I agree that parsing required props and such out of this destructuring assignment is a bit magical, but to be honest in my view not significantly more magical than the rest of Svelte.
> parsing required props and such out of this destructuring assignment is a bit magical, but to be honest in my view not significantly more magical than the rest of Svelte.
I think this is the only place we really disagree. To me, the export syntax is obvious and consistent, even if under the covers the behaviour is magical.
On the other hand, the $props syntax is not obvious; for a putative assignment to result in a declaration has no basis in my previous experience. Both the syntax and the behaviour is magical.
If Svelte is about the vibe, Svelte 4 was perfect for me - it’s why I moved from Vue, which I found had too many magic objects, and then doubled down on it with Vue 3 (I think) and refs. With Svelte 5, I feel it’s making the same mistake - the vibe no longer gels with me, and I gotta say, in addition, that pushing reactive behaviour into pure JS feels like a huge mistake to me. Sadly, I think I’ll be getting off this particular train.
Edit: I think my reaction to this is because $props - and the other runes - are effectively svelte-specific keywords added to JavaScript. I'm sure the Svelte folks have their reasons for this; but I hate it. They could have just introduced a new actual keyword, like "prop myProp = 5". I honestly can't see myself ever adopting Svelte 5.
Interesting, because now that I'm looking at them a little closer, it seems to me runes are reduction of magic objects in Svelte
> At first glance, this might seem like a step back — perhaps even un-Svelte-like. Isn't it better if let count is reactive by default?
> Well, no. The reality is that as applications grow in complexity, figuring out which values are reactive and which aren't can get tricky. And the heuristic only works for let declarations at the top level of a component, which can cause confusion. Having code behave one way inside .svelte files and another inside .js can make it hard to refactor code, for example if you need to turn something into a store so that you can use it in multiple places.
If the vibes are subjectively off for you with the new syntax that's fair, I just can't get it to align with what you are saying because at the end of the day, they are removing some Svelte magic and replacing it with regular JavaScript, apparently even the "$" label dependency tracking stuff, which I find to currently be the most magical thing in Svelte
To me that looks like a step to making Svelte more easy to reason with, but vibes are subjective in the end.
I get that runes are in some sense a reduction of magic, I just don’t see the point. Svelte 4 feet, to me, incredibly natural to write, because the choice of idioms matched so closely with the behaviour I’d expect from JavaScript. Going into Svelte 5, I hoped to see fixes for the things that bit me - missing transitive reactivity in $:, for example. But not wholesale changes to the way you declare and use the framework.
Anyway I certainly agree that the vibe is subjective, but I for one am bitterly disappointed by Svelte 5. It’s yet another framework that can’t make up its mind, and stick to it.
I love that I can just use
because it’s just JavaScript.The new runes syntax
Is not. This just makes me incredibly sad.Like all things, everyone is going to switch to the new syntax because it’s shiny, even though it objectively has a greater cognitive load (and IMO, looks ugly). My components are going to start looking like Svelte, rather than JavaScript.
The reason I prefer svelte over Vue is because there’s less to remember. Looks like I’ll be looking for a new framework after Svelte 5. Just like I did after Vue 3.
Also,
> Snippets are more powerful and flexible, and as such slots are deprecated in Svelte 5.
Removing slots, which feel really natural in HTML, with snippets - that are expressed as JavaScript values passed to a component - honestly, I don’t see the prioritisation of vibe, here.
These changes are going to make it so, so much harder to teach Svelte that I honestly feel despondent. I feel like svelte 5 has just totally forgotten that Svelte is supposed to feel like JavaScript. Super sad.