top | item 35324430

Thoughts on Svelte

364 points| naansequitur | 3 years ago |tyhopp.com | reply

189 comments

order
[+] rubenfiszel|3 years ago|reply
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.

[1]: https://github.com/windmill-labs/windmill/tree/main/frontend

[+] swsieber|3 years ago|reply
What are your build times like?

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...

[+] kirso|3 years ago|reply
The complexity of the front-end scares me sometimes...
[+] fenomas|3 years ago|reply
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:

    {#if showFoo}
      <div transition:fly={{ y: -50 }}> Foo! </div>
    {/if}
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.
[+] fenomas|3 years ago|reply
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.

[+] varrock|3 years ago|reply
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.

[+] h4ch1|3 years ago|reply
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.

[+] marcelr|3 years ago|reply
I wouldnt say this is a problem unique to 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.

[+] can_center_divs|3 years ago|reply
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.

[+] vaughan|3 years ago|reply
I wonder if this is a visualization problem. Imagine if you could see the dependency graph visually.
[+] spikey_sanju|3 years ago|reply
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.

Portfolio - https://www.spikeysanju.com

Source code - https://www.github.com/spikeysanju/spikeysanju.com

[+] nailer|3 years ago|reply
[deleted]

I confused vercel with nextjs.

[+] illiarian|3 years ago|reply
> 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.

[+] The5thElephant|3 years ago|reply
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.

[+] pavish|3 years ago|reply
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.

[1]: https://github.com/centerofci/mathesar [2]: https://github.com/centerofci/mathesar/discussions/55

[+] pier25|3 years ago|reply
> One example is being able to pass templates around.

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

[+] wibblewobble124|3 years ago|reply
I think if something is intuitive after 5 years then it wasn’t intuitive, you’ve just adapted.
[+] davidjfelix|3 years ago|reply
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.

[+] ttfkam|3 years ago|reply
It's what you consider central in a framework. For React, JS/TS is king. All markup and all CSS is subsumed in JS/TS.

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.

[+] tobr|3 years ago|reply
> 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.

[+] naansequitur|3 years ago|reply
Author here, those are fair points.

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.

[+] donmcronald|3 years ago|reply
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.

[+] thegeomaster|3 years ago|reply
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.
[+] pkalinowski|3 years ago|reply
I picked up Svelte to build my first non-trivial app, which is flying navigation aid for hot air balloon pilots[1].

Svelte is much, much easier to grasp than React or Vue, especially when it comes to state management. I like that it’s super lean and it never confuses me what’s native Javascript and what’s the framework (pretty important for a non-developer me). And I love not having to write huge amounts of boilerplate code.

Reactivity sometimes gets more complicated than advertised on docs. For example, I have a bunch of functions where I manipulate an object and need to reassign it to itself (feature = feature) to trigger refresh on reactivity block. Sometimes it’s easy to miss and not know why reactive statements are not being updated.

Also, docs are pretty barebones. For comparison, I think Vue docs are explaining details in better and clearer way.

[1]: https://balloonnavigator.com

[+] shanehoban|3 years ago|reply
I work with React (NextJS) and from working on things in Vue, and Nuxt - the one thing I absolutely hate about React is state management. If you have never used Pinia[0] (Vuex) with Vue, it's just so, so, so much easier.

I'm using Zustand[1] with React as it is as similar as I can find to Pinia, but the whole hook system is just painful to work with... OK rant over.

I haven't built anything substantial with Svelte, but it's definitely on the radar, and I like how similar it is to Vue single file components (SFC). Hoping state management will be as nice to work with as Pinia is with Vue.

[0] https://pinia.vuejs.org/

[1] https://github.com/pmndrs/zustand

[+] azangru|3 years ago|reply
I don't get it. From the example on Stackblitz[0], Pinia looks pretty much like redux, only with multiple stores instead of a single one. As far as I recall, Zustand is similar. What are the advantages of these libraries over redux (especially, the modern and opinionated redux-toolkit)?

0 - https://stackblitz.com/github/piniajs/example-vue-3-vite

[+] artdigital|3 years ago|reply
I went through similar troubles, then ended up trying [react-query](https://tanstack.com/query/v3/) and now I don't bother anymore. React Query does everything I need, and if for some reason I still need separate state management, I use useContext for those parts

React Query is a joy to use and clicks very nicely with how I am structuring my apps, building around interacting with async things like APIs

[+] agumonkey|3 years ago|reply
It's a strange feel with the vue world. There's a natural simplicity to it. While react often creates slightly(or a lot) complex entities that cause a lot of friction. Vue is often criticized for not being true js in the end etc etc but it doesn't seem to be important when creating something.
[+] koch|3 years ago|reply
I agree about pinia. After redux and selectors and reducers and spread syntax and immer and all that stuff, using pinia with vue3 was an absolute joy.
[+] sergioisidoro|3 years ago|reply
I have used MobX state tree (MST) with react, and a lot of the concepts are the same with Pinia. Pinia still looks better, I totally agree here.
[+] Rapzid|3 years ago|reply
I use MobX with Vue and React; works great; decoupled from any UI library ecosystem and is transferable knowledge.
[+] tsp|3 years ago|reply
Vue 3 and Svelte feel very similar to use. I prefer Vue because of the ecosystem. Using it with TypeScript and Pinia is pure joy! Surely, Svelte will catch up, but it will take a while.
[+] pier25|3 years ago|reply
I've been using Svelte exclusively for the past 3 years or so. I love it and will keep using it as my main solution for interactivity. It's fast to use and execute, produces small apps, and it's extremely economical in how you express components.

The confusion the author expresses with $: reactive statements and store auto subscription with the $ are unwarranted IMO. It's really just a lack of familiarity but this kind of stuff becomes intuitive very quickly.

My criticism of Svelte is rather that they haven't gone deep enough into the compiler-based approach.

Would be great if there were something like .svelteStore files where you had all the automatic reactivity tracking without having to use a component. Or some kind of improvements into writing styles. With a compiler you can do anything you want and I think Svelte has been a bit timid, maybe to not scare people away.

For example Imba[1] also bet on a compiler-based approach (years before Svelte existed) and created their own language/framework/compiler. They have come up with amazing solutions to many problems. It's a shame they bet on Ruby aesthetics though and also that they aren't investing into marketing/docs.

Of course, one might argue that using a compiler is a bad idea for a number of reasons. And yeah of course there are objective issues to any approach, but you have to pick your poison. All in all, Svelte has made me tremendously productive compared to using other solutions for years (React, Vue, Mithril, Inferno, etc).

I will say though that I would rather use a solution that doesn't have any reactivity at all. Mithril and Imba have this concept of just "redrawing the whole thing" like a game GUI without having to worry about reactivity. Cognitively speaking, no reactivity is the best mental model IMO. With any reactive solution, it's very easy to fall into complex reactive dependencies which can be hard to track. The author of Imba has a video from 2018 where he talks about this[2].

[1] https://imba.io/

[2] https://www.youtube.com/watch?v=jwoApTLvRdQ

[+] ttfkam|3 years ago|reply
Totally agree. I fully expect Svelte to start adding things like Nuxt 3's not requiring import statements for components. Hell, I could see in a couple years the script block allowing Rust with WebAssembly seamlessly generated but attribute binding logic looking exactly the same.

Compilers open up more avenues for productivity than most people in the web dev community realize.

[+] codelikeawolf|3 years ago|reply
I've been using Svelte at the day job for almost 3 years (coming from a React background). We're using it for a pretty large application that's probably going to end up being at least 400K lines of code. I love how you can leverage CSS to visually indicate state changes:

  <script>
    export let selected;
  </script>

  <style>
    [aria-selected] {
      background-color: blue;
    }
  </style>

  <button aria-selected={selected}>Click Me</button>
You can't do that with React. The lack of a VDOM is incredibly refreshing and I don't notice any performance issues.

I occasionally come across articles expressing concern that it won't scale up for large applications and I find that confusing. React has considerably more footguns than Svelte. I've ported over several personal projects from React to Svelte and it always shaves quite a bit off the line count and makes the code less confusing (at least in my opinion). Granted, it's not perfect. Forwarding props is kind of a pain in the butt and the docs advise against using `$$restProps`. There's also some trickiness when it comes to overriding styles. The only way to override a certain style in a custom `<Button>` component is via a `style` prop, using CSS Modules, or a CSS-in-JS library like Emotion. I've been using Vite's built-in CSS Modules and it's working pretty well.

The scoped styles are really nice. If you structure your components right, make sure you're adhering to accessibility guidelines, and use semantic HTML, you can usually get away with styling the markup based on the element type or attribute without having to define classes on the elements.

[+] georgefrick|3 years ago|reply
I've been building an app with Sveltekit (ok, two); and I've proposed a talk at THAT conf in the summer. I agree with the author's positive and negative assessments, but really for me the developer experience outweighs the negatives.

In VS Code I turn on seeing short directories in the tabs, which prevents file confusion. Beyond that it's been a joy to use and pretty easy to get going with. Any confusion or learning comes from not doing next.js first and having to learn about which things happen where in terms of client and server. It's eye opening though and it isn't forced learning.

I give Sveltekit a "you should certainly consider it" vote.

[+] yawnxyz|3 years ago|reply
I've been using Svelte and Sveltekit daily for a few years (back when it was Sapper!). I consider myself a product designer and not an engineer.

With the new direction of Sveltekit, the absolutely worst thing is the documentation. The new server-side endpoints have confusingly similar nuances (certain things like fetch can be used on certain server-side files, but another kind of fetch can only be used on another). The documentation style makes these nuances next to impossible to find, and I find myself having to Google or ask Chat GPT to help me figure those problems.

Otherwise, it's been a breeze to build with!

[+] h4ch1|3 years ago|reply
Ah the good old days of Sapper :'), the changes to the filesystem based routing to +page.ts +page.svelte +page.server.ts was really annoying to figure out initially, and +hooks as well, where to use what, what's the best way to do protected routes, took some re-learning, but it is what it is, would take the plunge to avoid React xd
[+] seanwilson|3 years ago|reply
What's a good frontend setup right now if you want strong static typing? I know Vue 3 supports TypeScript for example but it doesn't look like that's their core audience?

I don't get the appeal of frameworks introducing template tags like `{#if showFoo}` vs JSX personally. You have the learn new syntax for things you already know how to do in JavaScript but with less expressibility, and JSX can at least be type checked so you don't have runtime problems like an `<input>` sneaking a string in a number field.

[+] CharlieDigital|3 years ago|reply
Really interesting observation about the context of React being JS and the context of Svelte (and Vue, similarly) being HTML.

Makes so much sense once it's pointed out.

[+] dimmke|3 years ago|reply
This is really why I love Svelte so much. To me, the way components are formatted is how the HTML spec should have evolved over the last 10 years. It's absurd to me that HTML is still "documents" with a head and body wrapped inside an <html> tag.

This is a good pattern that builds on the existing foundational technologies of the web but acknowledges that how we build websites (and apps) has changed quite a bit.

[+] nailer|3 years ago|reply
As a Svelte user, and someone who definitely prefers it over the old frameworks, the praise and the criticisms seem accurate:

> In the end I found it was difficult to determine reliably when to reach for the $ label. I'd use it in one scenario and it seemed to work like I expect, then throw it at another scenario and it didn't work like I expect.

Yep. There's a bunch of different syntaxes and I can't find a documentation page that lists all of them. I use it, but I don't have confidence to always know when it's appropriate.

> Rip out {#await ...} and put it in the <script> logic, then use local variables when rendering.

Yep. Handling promises isn't something to be done in the HTML. HTML should deal with values.

I think even given these Svelte is still the obvious choice for new apps. Particularly the cleaner syntax, less code, batteries-included handling of CSS, and stores. But the two points above would be great to improve for future versions.

[+] codeptualize|3 years ago|reply
Great article, it's good to read a nuanced take on a hot topic.

I think the $ shows the tradeoff of reactivity. It makes updates sort of automatic which is great, until it's not. React on the other hand is a bit more explicit and cumbersome, until it's not. Rules of hooks vs rules of reactivity, it's all about managing triggers and dependencies, which easily gets complex. I think there might be a possibility for a mix, reactivity with escape hatches, idk.

[+] wildrhythms|3 years ago|reply
Every time I go back and try Svelte I get put off by the $ paradigm for this reason: it's less explicit than React or Angular (rxjs). The Svelte 'state' kind of stands in as an observable, but simply managing a UI plus reactive state is already difficult, so I find the hand-wavey "reactive code block" to only add to the confusion and side effects.
[+] synergy20|3 years ago|reply
I used Vue in the past and decided to use Svelte early this year, I do not need SEO or anything SSR, just the original SPA with CSR.

then I found out Sveltekit is really a SSR-first design, and Svelte itself has no client side routing etc. While Vercel sells Sveltekit(and Next.js) to be CSR ready, I don't buy it, I don't need the complexity of SSR in the code when I just need a clean CSR, however you paint the SSR-is-for-all picture.

So I switched to React, now React is also favoring SSR-first(next.js etc) approach. I'm back to Vue for future projects.

Vue by default remains to be the sole and true CSR SPA, if you need SSR, add Nuxt will do, but, at least it does not force me into a SSR-first default (and recommended) framework.

[+] bananapub|3 years ago|reply
This is a pretty bizarre comment, given svelte isn’t intended to be a web framework and sveltekit makes it extremely simple to do client side rendering.
[+] sonicgear1|3 years ago|reply
We had the same problem. Svelte would have been perfect if it only had a true SPA router. SvelteKit is too complicated for a simple SPA.