We have a pretty huge codebase [1] in svelte for Windmill, probably one of the biggest SPA on it. We are an open-source n8n/temporal + retool alternative so we are building both an advanced flow builder and an advanced app builder.
The article is on point. There is 1 caveat to animations that I'd like to add. Everytime we ended up using animation without the `|local` specifier, it broke completely our app, and that's an easy mistake to make. It should be the default imho. That's because svelte is updating the whole DOM instead of that specific component without it, and it waits for the animation to be observably over to re-render the DOM .
For reactivity, it works surprisingly well but for big state updates, and a redux style of having one big state to update, we ended up splitting the state subparts that were independent in reactivity because otherwise you end up very easily into a reactivity hell (reactivity, calling other reactivity). We also have a lot of pattern to keep in check the reactivity on nested objects such as using object comparison checks (using fastEquals) to make sure the input object actually changed and it was not a leaf node unrelated to this component that triggered the change.
Overall, with the small team that we are, we could NOT have build such a complex and blazing fast superapp without svelte. On the other hand, we had to become expert at knowing how svelte would actually compile to otherwise we would have been stuck early at using the reactivity bindings after a certain scale.
On a broader note, does anybody know of any build time comparisons for UI frameworks? Whenever I search for build time speed comparisons, I only find runtime speed comparisons...
I switched my game's UI from Vue2 to Svelte maybe a year ago, and I agree with almost all of the article.
One thing I think the author overlooks: the appeal of Svelte's built-in animations and transitions is that they work correctly when the element's lifecycle is being managed by Svelte. E.g. with code like this:
When `showFoo` changes to false, Svelte will first play a flyout transition and then remove the element from the DOM, and it will correctly handle things if `showFoo` toggles back to true again before the flyout finishes, etc. You could do the same thing with CSS animations, but it would be hairy and you'd need to learn more about svelte internals than you probably want to.
Co-opting my comment to add another thought. For me, Svelte's big superpower is that it does a great job of looking like plain JS sitting next to templated HTML, and the two just magically react to each other.
The reason this is huge is because 90% of my coding is not Svelte. Usually I'm working on app logic, so I might go weeks or occasionally months without touching any UI code. With Vue I used to dread making UI changes, because I always wound up needing to re-learn which properties I needed to put in which return value to which callback (or somesuch, I don't remember the details). I'm sure it's very intuitive if one uses it every day, but it never was for me after a six week gap.
In contrast with Svelte I feel comfortable doing UI work after a long hiatus, even with nontrivially reactive bits, because apart from the templating it's basically just plain JS (or looks like it). It took a bit of bother initially architecting stuff, but I don't think I've checked its docs since I first switched to it.
That said, the big tradeoff is that Svelte's reactivity is quite magical. Personally this doesn't bother me, because as a JS main I find it easy to intuit what Svelte must be doing behind the scenes in order to work the way it does. But if you're an occasional JS user you might hate Svelte's magicalness for the same reason I disliked Vue - e.g. you might keep needing to re-learn when to use $: statements, etc.
Re: magic in Svelte, I haven't used it but that sounds like something I'd be wary of. I like how Vue 3 takes a functional and explicit approach to defining reactivity. It's no longer grouped into buckets ala Vue 2 (data vs computed vs methods etc) but rather you write normal non-reactive JS by default and wrap values in reactive() or computed() when you need reactivity.
The only syntactic downside is reactive values always need to use foo.value to access foo's data which causes occasional bugs when you forget it (and it tends to fail quietly) but it makes sense why it is that way. Maybe better LSP/IDE integration can detect that.
It's good to hear Svelte has .svelte files like .vue SFC. That would be the biggest thing I'd miss with React.
> Usually I'm working on app logic, so I might go weeks or occasionally months without touching any UI code.
This is a very interesting point, because my experience is quite the opposite.
Most of the time changes to the apps that I typically worked on (ERP/CRM platforms) involved both DB migrations, as well as back end and front end work. And with the front end, changes to the logic almost always resulted in changes to the template, even if only within a single component. The only exceptions to this were validation changes (changed logic only) or visual bugs (changed template only).
I wonder what qualities of the system design this points towards, apart from coupling.
I just had to do this in React, and you're correct in that it makes you write logic around the lifecycles in ways that feels like I'm abusing their lifecycle methods. It's a lot of the reason Framer Motion and React Transition Group exist.
However, seeing the way Svelte does it sounds like a dream. I wish that could've been all I reasoned about last week.
It is actually not that hard in CSS plus vanilla JS using stuff like the `animationend` event (https://developer.mozilla.org/en-US/docs/Web/API/Element/ani...). Of course svelte provides a much easier interface, then having to have to deal with event listeners.
given that Svelte aims to be mainly pre-processed, how hard is it to combine it with more real-time solutions like Vue for instance? (you mention that you migrated from Vue2)
is it possible to use Svelte more for client-only or client-mainly views, and use other solutions for stuff that communicates more with the back-end? or do they get into each other's way?
I've been building a medium-scale web application that works as a configurator for 3D models (swapping objects/changing materials) and parsing/storing/syncing those configurations in real-time along with images, and a lot of metadata that needs real-time updates.
To be honest, it's a breeze until it's not, my single file gets very long, lots of declarations, $: reactive = another reactive variable, derived stores, the dependency graph can get really deep really quickly and it's very important to maintain a sort of heading, and plan ahead, because you can really lose yourself building with Svelte because of how little boilerplate there is.
Even then, 100% recommend it, documentation, and existing issues are sometimes lacking and information is hard to come by, but the Discord is helpful, even though it takes a lot of searching their "forums". Have great hopes for its' future, and it's really fun to build tools in Svelte, I remember giving all my Network Security assignments (transposition cipher, DES/AES, KDC) a nice, clean reactive front-end showing intermediate states of the data being passed around even though a simple cpp file would've sufficed, just because of how fun it's to use Svelte.
Ive designed svg based editor systems in svelte & the crucial piece was xstate.
I had editors with 7+ states, that is copy line, edit point of line, split line, draw line, etc.. and with xstate, no matter how much i added features each file would be 25-50 lines with some outliers at 80.
Maybe your case is different, as your app is solving a completely different problem. We have been building a somewhat complex CMS system with Svelte the last two years and haven't had any issues, that couldn't be solved because of the lack of information you are mentioning.
After this time, literally every other framework seems unnecessarily overcomplicated for me lol. It is a BREEZE compared to writing React imo.
I switched from Next.js to Svelte over a year ago. Since then, I have built medium-sized business products, and I can confidently say that Svelte is a joy to use. Their developer experience is on point. I agree with all the points made in the blog above, especially when it comes to working with forms. Svelte makes it easy with its inbuilt store, form actions, pageload, serverload, animations, and all of this results in a blazingly fast app. I even made an open-source version of my blog with SvelteKit.
> Svelte gives you an elegant way to use CSS in your components with <style> tags, why not implement transitions and animations in CSS there?
Because CSS has no hooks into HTML lifecycle. If you want to nimate something that appears in the DOM, or disappears from the DOM elegantly, CSS ain't it.
That's why almost every single framework outside Svelte struggles with animations and employs increasingly bizarre and brittle workarounds to make them work.
Vue handles it just fine with doing the hard work behind the scenes and just passing you some CSS classes to connect your animations to (and there are JS events to use as well if you need a JS animation). Main difference is Svelte gets the benefit of being able to do some fancier stuff like items changing order or doing more than just entering/exiting. Vue has this as well, but not as easy to use.
That being said I overall prefer the Vue CSS approach to animation, it inspired my brother and I to make https://animxyz.com which has been my most successful side project yet. We wanted to make it work for Svelte as well but they don't have the CSS classes so we can't hook into their events the same.
I agree with most of what the author says, except the part about reactivity. I attribute that sentiment to the author being less familiar with Svelte.
I do think that people new to Svelte find it hard. It takes a while to understand how the `$` reactive statements work, and when and when-not to use it. When I first started working with Svelte, I tried to do things the React way and shared similar frustrations. Now that I've been working with Svelte for smaller and bigger projects for nearly 5 years (yes, since 2.0), I find Svelte's reactive pattern simple and intuitive.
There are some aspects I find frustrating with Svelte. One example is being able to pass templates around. With React I'd just pass JSX, but since Svelte is statically compiled, I've had to create components for such scenarios. Slots don't cover all usecases. I can live with this though.
I have built a couple large projects using Svelte and haven't faced issues with scaling. I found Svelte to be quite flexible, which has enabled me to build fast, and maintain a performant codebase.
My recent project is Mathesar, which has a large frontend codebase in Svelte + Typescript [1]. It's also open-source so you can check out the codebase. We use pretty much all of Svelte's features and we even implemented a full component library. Here's an old discussion for deciding which frontend library to use for Mathesar, where we selected Svelte [2].
We have had to establish a number of patterns (including around reactivity) so that new contributors don't break things, which happens more often than you think.
Svelte's primary issue is a lack of established patterns, which makes it easy for new Svelte developers to get things wrong. React has a number of such patterns due to it's massive community. I believe as Svelte's community keeps growing and more projects choosing Svelte, this would be tackled.
Here's more clarity on what I was attempting to say: I had to understand the internal working of the reactive statements inorder to use it the right way and it took me a building a couple smaller projects to completion to get there. I believe this was because at the time I built them, I did not have enough references and projects where similar problems were tackled.
After I understood how it worked, which was about 3 to 6 months into using Svelte v3, I found it rather simple and intuitive. I've been working with Svelte for nearly 5 years overall. It did not take me 5 years to find it intuitive.
I think Svelte/sveltekit (especially) has really pushed a lot of the ecosystem forward and I love the effort made to exposing platform primatives more explicitly while attempting to make the framework disappear. I think the store mechanism is really great but I have noticed a few usability complaints coming from react land.
The main one for me is typing props for a component feels extremely wack. In react I have a function, that function takes a type, I export that type and can import that type. In svelte I'm exporting the props individually? It's annoying to get the type declarations in one spot and make that easy to import for other components to use as intermediate typing. This is one of those things that I didn't even think twice about until my project reached a medium size and had multiple developers building out different portions -- it's inconvenient to scale and none of the workarounds feel good.
> The $ label is one technical reason why I would be hesitant to adopt Svelte for larger projects. It's a core part of Svelte that you can't always avoid, and I think the potential for introducing bugs through it is high to start and very high at scale.
I agree that it can quickly cause confusion, but I can’t really think of a situation where it can’t be avoided.
I find it useful for simple things but try to avoid it when the dependency graph gets more complicated.
I haven’t built any large-scale Svelte applications but since reactive labels are by definition local to the component (it’s a compiler feature, and each component is compiled independently), I’m not sure why it would cause more issues at scale.
EDIT: Maybe they’re thinking of the reactive store syntax, which is harder to avoid but much less of a brainteaser. But that’s really a completely different feature that happens to use the same character.
For the part about increasing potential for bugs at scale, my mind was on scaling one or more teams and projects. Might have been better to use some other word than scale since it's so overloaded.
I find it difficult to think of patterns to introduce that would help teams align on when and how to use reactive `$` statements.
It's not a Svelte-specific problem by any means, but I do think Svelte's reactive statements would cause more pain than it would help ease as teams and projects get larger.
I thought about it some more after writing my reply. I think a first approximation is that $: gets confusing almost as soon as you bring in more than one level of branching control flow. It’s better to do that with stores or encapsulate the logic in plain old functions.
But if you mostly have some values that need to be recomputed when other values change, or an effect that needs to re-run, it’s a convenient tool to use.
Hi there. IMO, there are three issues there: familiarity, mental model, and caveats (using $ and not getting reactive updates in some cases).
Focusing on mental model, maybe my mental model can inspire yours? Here it goes.
- For me, `$: dependent variable = expression(independent variables)`, is an equation that Svelte guarantees will hold across the single-file component (SFC). So whenever an independent variable change, the dependent variable is also updated to maintained the equation.
- Caveat: In the statement `$: dependent variable = expression(independent variables)`, the expression language is JavaScript but the semantics of the statement are Svelte's (i.e. *Svelte's* scoping rules apply, not JavaScript's). SvelteScript is so close from JavaScript that it feels intuitive to use but confusing when the two differ. In a poor analogy, just like using a word that means something in French, another in Spanish, and wrongly guessing the source language (hence the meaning) that applies.
Then:
- `$: {some statements here featuring independent variables}`. *Svelte's* scoping rules apply (only the variables visible in the block are targeted by Svelte's reactivity). This is not an equation anymore, it is the expression of an effect triggered by change in dependent variables.
Why this is natural to me? At the specification level, reactive systems are specified with three core syntactic constructs:
1. event -> reaction
2. dependent variable = function (independent variable)
3. dependent variable <- function (independent variables)
The first item means is where you specify what happens when an event occurs. for instance button click -> (counter <- counter + 1; render new counter)
The second item is the same as lambda abstraction. Say `area = f(length, width)`. That's true all the time and allows using `area` everywhere needed instead of `f(length, width)`. But by referential equality rules, you could absolutely do away with `area` - at the expense of course of less clear and more verbose code (and probably less performant too)
The third item is assignment, and is used to describe changes in the state of the component. As a rule, (reaction, new state) = f(event, current state). So the third item describes how to get new state from current state. The first item describes how to get the reaction from the event and current state. The second item is optional but helps a lot readability, conciseness, and performance (not computing `area` twice if you use it twice).
In Svelte syntax:
1 is $: {reaction code here} (event is some change in value of variables scoped in the code)
1 bis: <some html code here> is the same case as 1 with a different syntax when the reaction is a (re)render. Whenever the dependent variables in scope change, a rerender reaction is executed.
2 is $: x = f(a,b,c,...) (Note that the right hand is a single variable name)
3 is any assignment occurring in the SFC.
Not sure if that helps, but well, that's how I stay away from the pitfalls of mixing SvelteScript and JavaScript. Identify events, state variables, the reaction to the events, and the state changes. Then translate that into SvelteScript.
I've never used it. My first thought is that $ label looks like callback hell, but without being able to step through the code easily to see where handlers are getting executed.
Syntax wise I don't like it because it makes the whole thing look like a simple variable assignment. Something that might be an expensive call looks like something that's usually a cheap operation.
Maybe I just think in terms of Java too much because it's the first language I learned, but I find all of the frameworks that use conventions like that hard to read. You need a ton of knowledge about how the internals work to understand what's happening in those scenarios. With Java, I always found the cost of writing boilerplate and declaring everything was paid back by how easy it was to read and follow existing code.
This mirrors my experience too: use it for simple, component-local things and state, avoid it if things start looking spaghetti-like. Although it was very hard as a newcomer to untangle how exactly '$' works and how it differs from the reactive store API.
The article is on point. There is 1 caveat to animations that I'd like to add. Everytime we ended up using animation without the `|local` specifier, it broke completely our app, and that's an easy mistake to make. It should be the default imho. That's because svelte is updating the whole DOM instead of that specific component without it, and it waits for the animation to be observably over to re-render the DOM .
For reactivity, it works surprisingly well but for big state updates, and a redux style of having one big state to update, we ended up splitting the state subparts that were independent in reactivity because otherwise you end up very easily into a reactivity hell (reactivity, calling other reactivity). We also have a lot of pattern to keep in check the reactivity on nested objects such as using object comparison checks (using fastEquals) to make sure the input object actually changed and it was not a leaf node unrelated to this component that triggered the change.
Overall, with the small team that we are, we could NOT have build such a complex and blazing fast superapp without svelte. On the other hand, we had to become expert at knowing how svelte would actually compile to otherwise we would have been stuck early at using the reactivity bindings after a certain scale.
[1]: https://github.com/windmill-labs/windmill/tree/main/frontend
On a broader note, does anybody know of any build time comparisons for UI frameworks? Whenever I search for build time speed comparisons, I only find runtime speed comparisons...
The build itself takes around 2 minutes, but that's mostly due to monaco and tailwind taking the majority of the time to be bundled.
One thing I think the author overlooks: the appeal of Svelte's built-in animations and transitions is that they work correctly when the element's lifecycle is being managed by Svelte. E.g. with code like this:
When `showFoo` changes to false, Svelte will first play a flyout transition and then remove the element from the DOM, and it will correctly handle things if `showFoo` toggles back to true again before the flyout finishes, etc. You could do the same thing with CSS animations, but it would be hairy and you'd need to learn more about svelte internals than you probably want to.The reason this is huge is because 90% of my coding is not Svelte. Usually I'm working on app logic, so I might go weeks or occasionally months without touching any UI code. With Vue I used to dread making UI changes, because I always wound up needing to re-learn which properties I needed to put in which return value to which callback (or somesuch, I don't remember the details). I'm sure it's very intuitive if one uses it every day, but it never was for me after a six week gap.
In contrast with Svelte I feel comfortable doing UI work after a long hiatus, even with nontrivially reactive bits, because apart from the templating it's basically just plain JS (or looks like it). It took a bit of bother initially architecting stuff, but I don't think I've checked its docs since I first switched to it.
That said, the big tradeoff is that Svelte's reactivity is quite magical. Personally this doesn't bother me, because as a JS main I find it easy to intuit what Svelte must be doing behind the scenes in order to work the way it does. But if you're an occasional JS user you might hate Svelte's magicalness for the same reason I disliked Vue - e.g. you might keep needing to re-learn when to use $: statements, etc.
https://vuejs.org/api/sfc-script-setup.html
Re: magic in Svelte, I haven't used it but that sounds like something I'd be wary of. I like how Vue 3 takes a functional and explicit approach to defining reactivity. It's no longer grouped into buckets ala Vue 2 (data vs computed vs methods etc) but rather you write normal non-reactive JS by default and wrap values in reactive() or computed() when you need reactivity.
The only syntactic downside is reactive values always need to use foo.value to access foo's data which causes occasional bugs when you forget it (and it tends to fail quietly) but it makes sense why it is that way. Maybe better LSP/IDE integration can detect that.
It's good to hear Svelte has .svelte files like .vue SFC. That would be the biggest thing I'd miss with React.
This is a very interesting point, because my experience is quite the opposite.
Most of the time changes to the apps that I typically worked on (ERP/CRM platforms) involved both DB migrations, as well as back end and front end work. And with the front end, changes to the logic almost always resulted in changes to the template, even if only within a single component. The only exceptions to this were validation changes (changed logic only) or visual bugs (changed template only).
I wonder what qualities of the system design this points towards, apart from coupling.
However, seeing the way Svelte does it sounds like a dream. I wish that could've been all I reasoned about last week.
Added an update to the end of the article linking to this comment - https://tyhopp.com/notes/thoughts-on-svelte#update-2023-03-2...
is it possible to use Svelte more for client-only or client-mainly views, and use other solutions for stuff that communicates more with the back-end? or do they get into each other's way?
Even then, 100% recommend it, documentation, and existing issues are sometimes lacking and information is hard to come by, but the Discord is helpful, even though it takes a lot of searching their "forums". Have great hopes for its' future, and it's really fun to build tools in Svelte, I remember giving all my Network Security assignments (transposition cipher, DES/AES, KDC) a nice, clean reactive front-end showing intermediate states of the data being passed around even though a simple cpp file would've sufficed, just because of how fun it's to use Svelte.
Ive designed svg based editor systems in svelte & the crucial piece was xstate.
I had editors with 7+ states, that is copy line, edit point of line, split line, draw line, etc.. and with xstate, no matter how much i added features each file would be 25-50 lines with some outliers at 80.
Id highly recommend it.
After this time, literally every other framework seems unnecessarily overcomplicated for me lol. It is a BREEZE compared to writing React imo.
The dev tools give you a full visual reactive graph.
I like Svelte, but people like to pretend that it's easier than it is.
Deleted Comment
Portfolio - https://www.spikeysanju.com
Source code - https://www.github.com/spikeysanju/spikeysanju.com
I confused vercel with nextjs.
Next.js is a React framework. It does not support Svelte.
Because CSS has no hooks into HTML lifecycle. If you want to nimate something that appears in the DOM, or disappears from the DOM elegantly, CSS ain't it.
That's why almost every single framework outside Svelte struggles with animations and employs increasingly bizarre and brittle workarounds to make them work.
That being said I overall prefer the Vue CSS approach to animation, it inspired my brother and I to make https://animxyz.com which has been my most successful side project yet. We wanted to make it work for Svelte as well but they don't have the CSS classes so we can't hook into their events the same.
Added an update to the end of the article linking to this comment - https://tyhopp.com/notes/thoughts-on-svelte#update-2023-03-2...
:)
I do think that people new to Svelte find it hard. It takes a while to understand how the `$` reactive statements work, and when and when-not to use it. When I first started working with Svelte, I tried to do things the React way and shared similar frustrations. Now that I've been working with Svelte for smaller and bigger projects for nearly 5 years (yes, since 2.0), I find Svelte's reactive pattern simple and intuitive.
There are some aspects I find frustrating with Svelte. One example is being able to pass templates around. With React I'd just pass JSX, but since Svelte is statically compiled, I've had to create components for such scenarios. Slots don't cover all usecases. I can live with this though.
I have built a couple large projects using Svelte and haven't faced issues with scaling. I found Svelte to be quite flexible, which has enabled me to build fast, and maintain a performant codebase.
My recent project is Mathesar, which has a large frontend codebase in Svelte + Typescript [1]. It's also open-source so you can check out the codebase. We use pretty much all of Svelte's features and we even implemented a full component library. Here's an old discussion for deciding which frontend library to use for Mathesar, where we selected Svelte [2].
We have had to establish a number of patterns (including around reactivity) so that new contributors don't break things, which happens more often than you think.
Svelte's primary issue is a lack of established patterns, which makes it easy for new Svelte developers to get things wrong. React has a number of such patterns due to it's massive community. I believe as Svelte's community keeps growing and more projects choosing Svelte, this would be tackled.
[1]: https://github.com/centerofci/mathesar [2]: https://github.com/centerofci/mathesar/discussions/55
Yeah I agree. It's not a big deal but I kinda miss this from JSX.
There was some discussion about adding templates or even components inside other components but it all feels very inelegant and not very Svelty.
https://github.com/sveltejs/svelte/issues/2940
https://github.com/sveltejs/rfcs/pull/34
Here's more clarity on what I was attempting to say: I had to understand the internal working of the reactive statements inorder to use it the right way and it took me a building a couple smaller projects to completion to get there. I believe this was because at the time I built them, I did not have enough references and projects where similar problems were tackled.
After I understood how it worked, which was about 3 to 6 months into using Svelte v3, I found it rather simple and intuitive. I've been working with Svelte for nearly 5 years overall. It did not take me 5 years to find it intuitive.
The main one for me is typing props for a component feels extremely wack. In react I have a function, that function takes a type, I export that type and can import that type. In svelte I'm exporting the props individually? It's annoying to get the type declarations in one spot and make that easy to import for other components to use as intermediate typing. This is one of those things that I didn't even think twice about until my project reached a medium size and had multiple developers building out different portions -- it's inconvenient to scale and none of the workarounds feel good.
In Svelte, HTML/CSS is king, with the bare minimum of JS/TS necessary for any given task.
With that in mind, of course React tends toward type definitions. Also explains why Svelte tends toward markup-oriented definitions.
I agree that it can quickly cause confusion, but I can’t really think of a situation where it can’t be avoided.
I find it useful for simple things but try to avoid it when the dependency graph gets more complicated.
I haven’t built any large-scale Svelte applications but since reactive labels are by definition local to the component (it’s a compiler feature, and each component is compiled independently), I’m not sure why it would cause more issues at scale.
EDIT: Maybe they’re thinking of the reactive store syntax, which is harder to avoid but much less of a brainteaser. But that’s really a completely different feature that happens to use the same character.
For the part about increasing potential for bugs at scale, my mind was on scaling one or more teams and projects. Might have been better to use some other word than scale since it's so overloaded.
I find it difficult to think of patterns to introduce that would help teams align on when and how to use reactive `$` statements.
It's not a Svelte-specific problem by any means, but I do think Svelte's reactive statements would cause more pain than it would help ease as teams and projects get larger.
But if you mostly have some values that need to be recomputed when other values change, or an effect that needs to re-run, it’s a convenient tool to use.
Focusing on mental model, maybe my mental model can inspire yours? Here it goes.
- For me, `$: dependent variable = expression(independent variables)`, is an equation that Svelte guarantees will hold across the single-file component (SFC). So whenever an independent variable change, the dependent variable is also updated to maintained the equation. - Caveat: In the statement `$: dependent variable = expression(independent variables)`, the expression language is JavaScript but the semantics of the statement are Svelte's (i.e. *Svelte's* scoping rules apply, not JavaScript's). SvelteScript is so close from JavaScript that it feels intuitive to use but confusing when the two differ. In a poor analogy, just like using a word that means something in French, another in Spanish, and wrongly guessing the source language (hence the meaning) that applies.
Then: - `$: {some statements here featuring independent variables}`. *Svelte's* scoping rules apply (only the variables visible in the block are targeted by Svelte's reactivity). This is not an equation anymore, it is the expression of an effect triggered by change in dependent variables.
Why this is natural to me? At the specification level, reactive systems are specified with three core syntactic constructs:
1. event -> reaction 2. dependent variable = function (independent variable) 3. dependent variable <- function (independent variables)
The first item means is where you specify what happens when an event occurs. for instance button click -> (counter <- counter + 1; render new counter)
The second item is the same as lambda abstraction. Say `area = f(length, width)`. That's true all the time and allows using `area` everywhere needed instead of `f(length, width)`. But by referential equality rules, you could absolutely do away with `area` - at the expense of course of less clear and more verbose code (and probably less performant too)
The third item is assignment, and is used to describe changes in the state of the component. As a rule, (reaction, new state) = f(event, current state). So the third item describes how to get new state from current state. The first item describes how to get the reaction from the event and current state. The second item is optional but helps a lot readability, conciseness, and performance (not computing `area` twice if you use it twice).
In Svelte syntax: 1 is $: {reaction code here} (event is some change in value of variables scoped in the code) 1 bis: <some html code here> is the same case as 1 with a different syntax when the reaction is a (re)render. Whenever the dependent variables in scope change, a rerender reaction is executed. 2 is $: x = f(a,b,c,...) (Note that the right hand is a single variable name) 3 is any assignment occurring in the SFC.
Not sure if that helps, but well, that's how I stay away from the pitfalls of mixing SvelteScript and JavaScript. Identify events, state variables, the reaction to the events, and the state changes. Then translate that into SvelteScript.
Syntax wise I don't like it because it makes the whole thing look like a simple variable assignment. Something that might be an expensive call looks like something that's usually a cheap operation.
Maybe I just think in terms of Java too much because it's the first language I learned, but I find all of the frameworks that use conventions like that hard to read. You need a ton of knowledge about how the internals work to understand what's happening in those scenarios. With Java, I always found the cost of writing boilerplate and declaring everything was paid back by how easy it was to read and follow existing code.
Dead Comment