Hacker News new | past | comments | ask | show | jobs | submit login
Thoughts on Svelte (tyhopp.com)
364 points by naansequitur on March 27, 2023 | hide | past | favorite | 189 comments



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


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


When we dev, svelte uses vite which has instant hot-module-reloading. You edit your code and see the change live.

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.


Thanks!


The complexity of the front-end scares me sometimes...


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.


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.


Vue 3 with <script setup /> seems to be much closer to straight JS than Vue 2's boilerplate structure, which sounds more like Svelte.

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.


Oh neat, I hadn't seen Vue3/script-setup, it looks very similar to Svelte. The magic I referred to was basically just wrapping reactive logic around variable assignments, so if you're familiar with Vue3 then you it sounds like you may not consider Svelte magical at all.


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


Yeah, it's very subjective - the above has been my experience, but I wouldn't argue that it will necessarily reflect anyone else's.

But for why I go so long without touching the UI code, it's just because the project is a 3D voxel game and there's a lot of big complicated parts to work on that don't involve any HTML UI.


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.


Missed opportunity...

    {#if showFall}
      <div transition:fly={{ u: 8 }}> Fools! </div>
    {/if}


I have no idea what this guy is Tolkien about.


Kinda rings a bell; just don't make it a hobbit.


Author here, this is a great point.

Added an update to the end of the article linking to this comment - https://tyhopp.com/notes/thoughts-on-svelte#update-2023-03-2...


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.


Yes, great point - I meant to say that using CSS animations is hairy if one is using Svelte, not that they're hairy generally.


Can i ask you what type of game it is? Web or desktop? I wanted to dive into the topic of UI in desktop/native games for a while


Mine is web-based - a bunch of HTML DOM that lives on top of a canvas rendering the game. Afraid I don't know much about desktop/native, sorry!


Did you _need_ to switch your games UI to Svelte because Vue2 really wasn't good enough for you needs, or did you just want to learn Svelte?


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?


Svelte is compiled, but not compiled to html. It is compiled to js. It works like any other client side js framework like react/vue


The important difference to note compared to React, is that Svelte doesn't virtualize the DOM. It works in the same way vanilla JS works when it comes to DOM manipulation.

Even though it is compiled, you are still working closer to the browser. You can still use all vanilla JS DOM manipulation methods in your code and it will work as expected. Which is an enormous advantage over React, at least for me.


Depends on whether or not the following is set:

    export const prerender = true;
If it is, it IS in fact compiled to HTML. :-) https://kit.svelte.dev/docs/page-options#prerender

Compilers are awesome.


This assumes you are using SvelteKit, not vanilla Svelte


    npm create svelte my-app
Creates a SvelteKit app now, not plain Svelte. That said, you can easily disable the server-side portion.

    export const ssr = false;


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.


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.


Xstate looks very interesting, certainly going to take a look, thanks!


Is xstate something like redux or mobx?


it's like a much more structured, and observable version of redux. observable in the sense that not only can you tell what has happened, you can also tell (and visualise) what can happen next


Yeah, the first time you realise you can set the disabled state of a button using `state.can('submit')` it feels like magic!


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 wonder if this is a visualization problem. Imagine if you could see the dependency graph visually.


In my opinion, this is yet another area where SolidJS is clearly the better option.

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.


I think this is what you're talking about ? https://chrome.google.com/webstore/detail/solid-devtools/kmc...


Yep, that's it. It's in early development, and you have to install an additional library. But, it works wonderfully.


Is there something similar for Vue?


I don’t think vue devtools have this capability. But if you are facing issues with large Vue components, then you should split it into smaller components. And use composables(vue hooks) to split js logic. That will get you quite far


> full visual reactive graph

Is there actually a graph view? Or is it only the graph as a tree? I couldn't see it in the demo.


which solid-dev-tool shows are graph?


I wasn't aware there were multiple. This one has Ryan Carniato's seal of approval. He talks about it on stream often.

Here you go: https://github.com/thetarnav/solid-devtools


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


[deleted]

I confused vercel with nextjs.


Vercel, the hosting platform that created Next.js, employs Rich Harris who created Svelte. You can host Svelte on Vercel.

Next.js is a React framework. It does not support Svelte.


Wait where do you see this? I haven't heard of this and cant find any reference in the docs. Are you referring to the Vercel support?


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


Author here, thanks for the context.

Added an update to the end of the article linking to this comment - https://tyhopp.com/notes/thoughts-on-svelte#update-2023-03-2...


Hacker News comments and "fun to read". Who are you, sir?

:)


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


> 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



I think if something is intuitive after 5 years then it wasn’t intuitive, you’ve just adapted.


I think I didn't phrase my statement correctly.

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.


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.


React doesn’t care where or how you have your CSS.


Right, because it has very poor component-level isolation for styling. React basically punted on CSS, and that's truly not a blessing in its favor.


Doesn't it? I can't put a class name on a HTML Element and then style the said class inside the same file. It seems to me that it cares more about where you have it, than Svelte


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


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.


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.


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


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


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


I don't get it either. Plus, what exactly is so hard about using hooks? Hooks are awesome.


> what exactly is so hard about using hooks

Oh, this I can tell. For one thing, it's very easy to get stale closures if one isn't careful. For another, hooks are a reactivity mechanism that is tied to the re-rendering of the whole component (what if you don't want to re-render the component? what if you only want to perform a side effect when a particular value changes?). Third, the docs are sowing confusion by discouraging the very natural, and often inevitable, concept of side effects, as well as by removing the concept of component's lifecycle (there is no idiomatic way of telling react to please run certain logic only once when the component mounts)[0].

0 - https://react.dev/learn/reusing-logic-with-custom-hooks#keep...


> what if you only want to perform a side effect when a particular value changes?

https://react.dev/reference/react/useEffect

That is literally what useEffect is for! Describe your side effect, provide a list of values that you want the hook to watch for when they change. `useEffect(someEffect, [value1, value2, value3])`

> the very natural, and often inevitable, concept of side effects

React uses a functional programming model. Always has. Watch the Honeypot React documentary and notice how many times the earliest adopters say they were excited to have way to express UIs functionally. Functional programmers believe in minimizing side effects. If you don't like the paradigm, there are 1000 other UI frameworks that use an imperative model. Complaints like yours read like someone complaining that their screwdriver isn't a hammer.


> That is literally what useEffect is for!

No, sorry; for useEffect to fire, a prop or a state needs to change; which means that the component is going to re-render. My point is that sometimes we want to observe properties passed to the component for side-effect purposes without re-rendering the component.

> Functional programmers believe in minimizing side effects.

In order to do something — anything — in the real world, we need side effects. Even Haskellers know this :-)


>> Functional programmers believe in minimizing side effects.

> In order to do something — anything — in the real world, we need side effects. Even Haskellers know this :-)

Hence the use of the word "minimize"


Sounds like the prop shouldn't be getting passed to the component then if the component isn't using it to render itself? Maybe it should be getting sent straight to your "store" perhaps? Let the components take care of the rendering, let your "store"/"state machine"/whatever take care of the side effects.


I beg to differ here. Or let's say that the React "functional programming" model has very little to do with the actual functional programming done by actual functional programmers. What is true is that React components are functions. But functional programming and programming with functions are two different things.

Second, side effects are just about in every React component where you use a hook.

Third, (hypothesis) `useEffect` is probably a misnomer that stick there because it would be a breaking change to rename it to something more proper.

Words and bickering aside, you can write great applications with React, that's fact. It is also a fact that a lot of folks are using it wrong, which shows either a problem with React learnability itself, or with its documentation, or well, with the programmers themselves.


> side effects are just about in every React component where you use a hook.

I would expect most of your side effects to happen as a result of user interaction, i.e. in an event handler. Data fetching would probably be at the top of the tree. What side effects are you including in every component?

> a problem with React learnability itself, or with its documentation, or well, with the programmers themselves

All three!

- Most programmers dont learn FP before adopting React, which means they aren't going have a more difficult time working with React's functionalish model.

- Lots of blog posts, tutorials and even docs of popular libraries feature poorly written React code. It's just reality. Lots of people use this library, and there's no barrier to entry to write a tutorial post. IMO, the new React docs are a step in the right direction and should be a primary learning material for most.


useEffect is an abstraction leak. You're defending boilerplate that a compiler can identify and eliminate for you.

Let computers do what they're good at so that we devs can concentrate on the actual problems being solved.


I think that when you work with a framework like Vue/Nuxt where hooks aren't needed, they are not so awesome when you transition to working with React/Next. Everything just works as expected (with Vue/Nuxt).


I guess my main gripes are not with the libraries for state management themselves, but how managing rendering after state mutations occur. Pinia and Vue/Nuxt just do this effortlessly. Having to deal with hooks and useEffect in React is just a pain... in my opinion.


You shouldn't use useEffect just to bring state mutations from the store into the component or to calculate "view model" from your state. Have a look at the new react docs.

https://react.dev/learn/you-might-not-need-an-effect


But then again, you might need an effect. The behind the scenes (or behind the hooks) complexity that react adds in order to the make DOM thing work then makes it difficult when you do need an effect. Things like WebRTC or sockets or some such. useRef? useState? I have found this to be extremely difficult. If someone knows a good resource for doing things like this in React (and not a one page file, but with multiple components etc) I would appreciate knowing about it.


I'd say pull that logic out of your components and put it in some central place like an XState machine exposed to your components through Context.


That's the case for useSyncExternalStore.


Thanks! Just what I needed.

On a side note, is there a place that talks about this issue in React and explains why this is needed? There is a hint in the doc. It says "... that hold state outside of React".

Using web sockets, events come in and some (and only some )affect components. When a socket is connected there is an explicit state that changes, but how that gets into React-Land is difficult. The same issue exists with WebRTC. What I don't really get is why useRef, useState and useEffect are so difficult to get right.


Or… y'know… just stop worrying about niggling details like this and just use Svelte.

Svelte out of the box is much faster than React. You have to be well down the road of optimization before you hit parity, and optimized is almost never easier to understand.

Computers don't care about code. They're satisfied with 1s and 0s. Code is for humans. The cleaner, the simpler, and the less of it, the better. More code = more bugs.


I won't use Svelte for the simple reason that I don't like templating languages. Same reason I switched from Vue to React.


You mean you like your templates to be explicitly defined as a JS/TS render function.

JSX is a templating language.


> JSX may remind you of a template language, but it comes with the full power of JavaScript. [0]

That's the difference. I don't want to relearn how to do for and if-statements.

[0] https://legacy.reactjs.org/docs/introducing-jsx.html


> I don't want to relearn how to do for and if-statements.

…so you'll learn the weird details of render(…), learn how to manage updating a whole extra DOM on top of the existing browser DOM, learn to deal with the abstraction leaks of shouldComponentUpdate, React.PureComponent, useMemo, useCallback, and concurrent mode…

…just so you can avoid learning {#if}{/if} and {#each}{/each}. Got it. TOTALLY makes sense.

#StockholmSyndrome

Do you put onclick handlers on your divs to go to other URLs too?


Do you understand that JSX is not React-specific? Vue and Solid both have it. Solid for example does not use a VDOM, and I'm quite happy with React as it conforms to a functional style unlike the vast majority of JS frameworks out there that have some random version of reactivity thrown in that makes it hard to manage local state, so yes, it TOTALLY makes sense. If you like Svelte, good for you, but again, I won't learn yet another templating language and have to go through yet another way of working out how `map`s and `fold`s work in this new DSL. Perhaps you should lay off the snark, but it looks like you have some specific fascination with JSX, as listed in your profile, so I don't think this will be a fruitful conversation.


That's kind of funny considering you can't use `for` and `if` in JSX. I think you meant `.map` and the surprising rules of the `&&` operator.


Not OP but I think this is exactly the point. With Vue/Pinia it just works as expected without having to think about these things.


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


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.


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.


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.


I use MobX with Vue and React; works great; decoupled from any UI library ecosystem and is transferable knowledge.


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.


+1 for Vue3's <script setup> offering a lot of the simplicity that svelte is praised for while having much better tooling and being more polished.


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


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.


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.


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.


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!


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


I love Svelte but I've found myself disappointed by SvelteKit. Yeah it helps with rendering Svelte in the server and client but that's it.

And there are many weird architectural decisions forced on you such as file-based routing which IMO are a deal breaker for anything but trivial projects. Even as a SSG, SvelteKit still lacks fundamental features such as easy to configure permalinks at the page level (which Jekyll had almost 15 years ago).

I've started experimenting with integrating Svelte with Fastify using Vite to get a good backend framework instead of using SvelteKit. It's still a bit ugly but it works:

https://github.com/PierBover/fastify-vite-svelte-template


I was also confused when migrating from Sapper 0.27 to SvelteKit 1.0.

The syntax changes were straightforward enough, but it left me with a project that didn't compile.

I started a new project and copied the source files there and it worked.


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.


"you have the learn new syntax" is a really weird argument. Every approach, be it Vue, Svelte or React introduces a new alien syntax. In my personal opinion React approach is the most alien.

React's "it's just Javascript" mantra is a manipulation that only gullible folks will fall for: you can't just add a bunch of stuff to Javascript and then claim "it's just Javascript". If I throw a piece of steak in your coffee, you won't consider it "just coffee" anymore. And certainly you can't claim you're still a vegetarian after consuming that "cup of coffee".

I personally find it much harder to reason about the weird

  condition && <element>
  
syntax, compared to perfectly reasonable

  {#if condition}
    <element>
  {/if}
The latter so readable that it can even be understood by a non-engineer. The "new syntax" is as close to natural language as it gets.

Understanding the final layout is much harder in React.

That said, custom template syntax has indentation issue (you typically want indent both HTML elements and custom template tags, so anything inside conditions/loops has double indentation), so I actually think Vue template syntax (<element v-if="condition">) offers the best tradeoffs.

But regardless, at least when I'm looking at all 3 options, I see their tradeoffs and making an informed choice. React folks typically fail to even understand that there are tradeoffs. Even if you buy the "it's just Javascript" mantra, Javascript was never a good option represent a document layout.


For Vue 3(at least for the composition api) ts support is very good and handles typing in templates and between components in a way that was a bit lacking in Vue 2.

As for the other ones React seems to be pretty good with TS and obviously Angular is TS only.

As for using templating logic over JSX, that is of course a matter of taste, but i find code becomes much cleaner when there is a clear separation of templates and logic, and with jsx its a bit too easy to blur that line.


React has very good support for TypeScript at this point. Not sure about the other frameworks.


Solid does too.


I don’t know if there was an implicit “besides Svelte” in there, but if you’re open to it, Svelte works well with TypeScript. The types flow into the HTML expressions too. I also like how little boilerplate there is compared to e.g. adding types to React component props. With Svelte, the prop typing is as simple as:

export let name: string;

export let age: number;

FWIW I kinda agree with you about the #if syntax. I like that you can still use a ternary with plain JS values like {Math.random() < 0.5 ‘heads’ : ‘tails’} though, and I would say I very much don’t miss having to use nested ternaries in React.


In Svlete (which doesn't use JSX?), are your templates type checked? Non-JSX approaches have to reinvent not only JavaScript loops and control-flow, but also the type checking that TypeScript gives? This feels like a big downside to me.


Yep, templates are type-checked, even though it's not JSX. Svelte is already running a compiler on the components anyway, to figure out the reactive stuff and to generate the minimal code required to update those specific spots in the HTML, so it can pass that code through TypeScript's checks. I'm almost certain they haven't reinvented their own TypeScript compiler here; I believe it's just passing off the type checking work to the existing TS checker.

One thing to mention or clarify maybe, is that Svelte's special syntax for {#if}'s and {#each}'s have real JS in the meat of them. Doing something like {#if a === 5}, the `a === 5` is parsed as actual JS. I really appreciated this after having used AngularJS (the 1.x versions) back in the day where it had its own half-baked flavor of JS for those embedded expressions and I was never sure if what I was writing would actually work.

I would say, if you've got a handful of minutes to spare, give the first few steps of the Svelte tutorial a try if you haven't (https://svelte.dev/tutorial). I think it does a good job of giving a feel for how it works.

It's written as a series of interactive examples where they teach a concept and you can try it in the editor on the page. I had a lot of aha moments when I initially went through it, having started off skeptical about the whole idea of going backwards to templates after React. There are just a lot of little things that worked "as they should", and moments that made me go "ohhh of course that just works, it's plain JS, I see."


To be pedantic, TS is statically typed but not strongly typed.

The React ecosystem has embraced TS it seems. Angular is another obvious candidate, I think it had a strong focus on TS since quite a while. Lit/lit-html is just JS, so there are no surprises if you use TS as far as I know.

I agree with the JSX issue though. It's the one thing that React does better than some of these other frameworks except to for example Lit/lit-html which is literally just JS with template literals and doesn't require a build step.


You could look at Rust and Dioxus https://dioxuslabs.com/


Eh? Svelte supports TS and integrates it throughout, even type checking your request locals etc.


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.


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.


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.


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.


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.


It’s still explicit, just at the language level rather than the library level. (Svelte components aren’t written with JavaScript, but a language that extends JavaScript, repurposing $ labels and $-prefixed identifiers. Not appreciating that Svelte is a language and not just a library is a common cause for discomfort at the Svelte approach.)

The only part that is less explicit than some reactivity libraries is which variables’ changes will trigger re-evaluation.

Some libraries go full-explicit with the likes of foo.observe(foo => …) or computed(([foo]) => …, ["foo"]), requiring that you enumerate the properties to depend on. This is easy to get wrong, leading to bad reactivity.

Some libraries go full-implicit, tracking which properties were accessed during the call. This can be functionally perfect (provided you only use observable objects or primitive values—no Array, for example, leading to the amusing situation of some common patterns being syntactically heavier), but harder to reason about, and makes static analysis impossible in the general case, since property access can be non-local.

Svelte lies between the two extremes, needing no special syntax for it, but just noting which local variables are touched inside the block. This makes bad reactivity quite possible (non-local effects aren’t observed, including object nesting), but the language semantics of $ blocks are easy to learn, which mitigates this (though it’s still the most common sort of beginner error, when people try just using it rather than learning it). Static analysis and reasoning aren’t quite as simple as full-explicit, but are still straightforward in sanely-written code.


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.


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.


"extremely simple"? I disagree. I had to read its document and most of them are unrelated to CSR, why do I need to do that? the kit by design is absolutely SSR-first, it does let you tweak for CSR, but I don't need that complexity, not at all.

If Svelte provides a built-in client side router, and do not try to point everyone who wants to use Svelte to Sveltekit, I may reconsider, for now, Svelte is no longer in my projects.


+page.js: export const ssr = false;

https://kit.svelte.dev/docs/page-options#ssr

I don't get why so many people seem to think SvelteKit is SSR-only or that it's some kind of Rubik's Cube of configuration to disable.

FYI: There's also export const prerender = true;

https://kit.svelte.dev/docs/page-options#prerender


You can totally use SvelteKit without SSR.

https://kit.svelte.dev/docs/single-page-apps


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.


I used https://github.com/EmilTholin/svelte-routing with great success, though it looks like the maintainer has recently stopped maintaining it, and recommending sveltekit.

Still, I'd give try, it looks like people are still using it, and perhaps someone else will pick up the burden of maintenance, since there's clearly a ton of demand: https://github.com/EmilTholin/svelte-routing/issues/236


https://github.com/ItalyPaleAle/svelte-spa-router seems good too.

but it's not official, and Svelte project seems careless for client routing, instead it tries to convince everyone use its SSR-first kit, that "can do CSR too", which means you have to carry the whole SSR code base and its documentation into your CSR project totally unnecessarily.

I get it Vercel needs SSR for its business, I don't get it why it keeps selling everyone that "my SSR-first framework is great for CSR SPA too", it is NOT, not at all.


> I'd use it again for personal projects, maybe not for large company projects if I was the architect.

Questions about large projects always arise when talking about Svelte. Did you / would you use it and why not?

I would certainly NOT suggest using Svelte on enterprise projects. Why not?

Because other people don’t do it, and that means that it is very likely that there are no (not many anyway ) experienced Svelte devs that are willing to work at/for some large company. React and Angular are safe bets in THAT space.

On the other hand, would I use it for personal projects or in a startup - absolutely. It's simple, it is fast and it is fun to work with.


With all due respect, the majority of large React projects I've encountered devolved into non-uniform big balls of mud that only the original authors can (sometimes) understand. React's "non-opinionated" stance constantly leads to a non-opinionated code base without a strong technical lead with a very firm hand.

When talking about other frameworks (sorry, "libraries"), React folks should really avoid throwing stones from their glass house.

I'm not fan of Angular by any means, but I totally respect how opinionated it is and how that translates out to development teams in the wild.


> Because other people don’t do it

This isn't true, I build enterprise software with Svelte (and have for years), and I know others who do too. We just don't contribute to the technology hype cycle.


> React and Angular are safe bets in THAT space.

But they weren't always. And a lot of people that 'know' React don't feel entirety comfortable using React because of complexity - ever seen someone want to know how to store a variable and watched the life drain out their eyes as they read a Dan Abramov essay on what true reactivity means?


React never was truly reactive. Even according to its devs.

https://legacy.reactjs.org/docs/design-principles.html#sched...


I share your view that Svelte is a great framework for small projects. It is also really useful if you want to build small standalone javascript widgets. I've used it at work to build a fast video testimonial slider for Shopify [1]. I really liked the component format as we could quickly integrate our code in the existing HTML layout. The Svelte built-in store has also been useful for us to manage the current state of the application. Overall development with Svelte has been really quick.

[1] https://vimonial.com


What makes something good for small projects? Does that mean it's not good for big projects? What's the difference between big and small projects that makes Svelte good for one and bad for the other?


Svelte doesn't use a virtual DOM and when it compiles, it only targets what you are specifically using it for.

The thing with Svelte is that for a big project (like an SPA) you're going to end up using SvelteKit, because that's where all the development focus is for things like routing etc... and SvelteKit isn't nearly as settled. As in, there aren't developed "patterns" for doing a lot of things yet so it's a lot of trailblazing. There's also some features that are missing and on the roadmap but SvelteKit just hit 1.0 in December (these are usually more obscure things but you will still likely encounter them if you're building something of moderate complexity.)

I still think overall it would be fine to use for a big project, but a year from now I think it will be a much easier choice. Something that is happening right now is a lot of big players in the wider JS ecosystem are transforming from being React specific to framework agnostic:

- NextJS -> Auth.js: https://twitter.com/balazsorban44/status/1603082914362986496

- React Table / React Query -> TanStack Table, TanStack Query: https://tanstack.com/

This has all happened in the last few months. So it's still new, and they're still improving as they move away from being React specific. People rely on those projects. As more move in that direction I think it will become easier and easier.


Honestly, SvelteKit is pretty solid. They took their time trying to make consistent decisions rather than rushing 1.0 out the door and trying to backtrack later. All design decisions were out in the open on GitHub issues, and they spent a really long time looking at other frameworks and what they got right and wrong. The lack of navel gazing was refreshing.


I wasn't dissing SvelteKit. But I've been using it for about 6 months now. It's not perfect. There are currently some things that are very hard to do in SvelteKit that are not hard in other frameworks. It is what it is. That will change over time.


Can you give one or two examples? I'm not trying to start an argument. I genuinely want to know where folks are running into speed bumps.


I also noticed that facebook's Lexical, the successor to Draft.JS, is framework agnostic.


I think experimentation is one of them. being able to easily break backwards APIs to try new things in each version may not be nice for large scale projects. It's nice to try new things, but it can be a maintenance effort in terms of sustainability. and such projects are usually used for a large project so core development can go a certain line. (like google products for angular, facebook products for react). it doesn't seem to apply to this svelte. It is debatable, of course, that it is a negative thing. But I think it's a shortcoming.


The only real argument could be maturity, and Svelte seems pretty mature by now (at least by JS ecosystem standards).

And even that is a flawed argument: almost every React codebase uses numerous immature extensions. I haven't seen a conservative React developer.

The counterintuitive truth is that if something is a good fit for small projects, it is most likely a good fit for big ones too.


One thing that makes Svelte great for embeds is that it has no runtime dependencies, no equivalent of react.js and react-dom.js. It just compiles down to vanilla JS.


May I ask you how did you find the process of programming a Shopify app using Svelte? I have some experience with Svelte and am currently in process of starting development of a new Shopify app, but I basically decided to go with React as they have a lot of documentation and libraries (Polaris, AppBridge) available for it, while on Svelte I would have to do everything from scratch (or at least that's how I understood it from their docs)

EDIT: after reading your comment one more time, I assume you've used Svelte only for a small part of the app, not the app as a whole?


We are using next.js for the admin interface of the app. Works great with Polaris and AppBridge. Svelte is only used for the widget we are providing to the merchants.


> I like the idea, but in practice I always ended up refactoring it out. There was always something else I needed to do after the Promise resolved or rejected prior to rendering, and I didn't want to run that logic every time I used the service.

> The logic also didn't belong inline in the rendering code, though. So where does it go?

I think the idea would normally be that you would handle loading the data in +page.ts and do any transformations there, and only deal with rendering and ui elements in the +page.svelte file.


Yep! And to modify the data you use form actions :) it really is very beautiful once you get the full data flow


For performance reasons, you might not want to wait for promises to resolve in your load function, though. My app got way faster once I switched to streaming promises.


I'm admittedly a JS/TS and Svelte novice, but I think you can still do the transformations within your load function, just making sure they're part of a promise you return.


I'm a React dev, I recently rewrote my websitein Svelte. Svelte is my favorite by far, it does so many things in a smarter way so its really hard to go back.


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

At work, we use Svelte throughout our entire FE platform in many SPA micro-frontends, on both the web and mobile (w/ Cordova). We have 10,000+ daily active users. Our team has used Svelte in production for a few years. All of our developers learned it during the coding interview project, and on the job. It's fun and enjoyable to use.

I disagree strongly with this statement (not using it in production because of the reactive syntax). Reactive-blocks will trigger an update if their direct top-level dependencies change, not if one of their dependencies change from within a new scope/block (e.g. function-call) - that's all. Also, we only use reactive statements when we need to - we typically use data-binding instead.


Now I notice I was doing:

    Rip out {#await ...} and put it in the <script> logic, then use local variables when rendering.
intuitively and without realizing. Thanks for writing about it.


We don't use {#await because it has several issues. We use this utility to access promises in Svelte components, converting promises to stores:

    export type PromiseState<T> =
        | { status: 'loading'; value?: undefined; error?: undefined }
        | { status: 'resolved'; value: T; error?: undefined }
        | { status: 'rejected'; value?: undefined; error: Error };
    
    export function fromPromise<T>(promise: Promise<T>): Readable<PromiseState<T>> {
        return readable<PromiseState<T>>({ status: 'loading' }, (set) => {
            void promise
                .then((value) => set({ status: 'resolved', value }))
                .catch((error) => set({ status: 'rejected', error }));
        });
    }


I agree with pretty much everything the author said. I'll also add that one of my biggest complaints is that you can't use typescript inside the "markup section" (eg. for type casts or null assertions).

I still don't fully understand reactivity, or how to handle complex reactivity use cases, but it's not like the story in react is much better.

Overall it was a joy to work with even though I don't think it's a perfect framework and may not have what it takes to unseat react as king.


The author had a completely different experience from mine.

I adored the $: reactive variables, I liked the await blocks, and I found built in stores difficult.

This was as of a year ago, but still interesting.


Last year I wrote a comparison between Sveltekit and React with focus on Typescript and Graphql. What I didn't like particularly was that for-loops had no type inference [1]. Until this changes there is no reason for me to use Sveltekit in big projects. Typesafety is very important and nothing beats react on that.

[1]: https://www.nvegater.info/blog/SvelteKit#bad


A lot of the pluses mentioned are things I really enjoyed about Vue. The bind system works great for syncing inputs to arbitrary reactive objects(or not reactive), the in-built transition support, the event system, and I don't know if Svelte has this but Vue's async component factory support is fantastically useful.

Just can't get on board with yet another compiler and string template language. Towards the end of my time with Vue I was favoring JSX more and more. The VSCode Vue extension of choice at the time(this was a couple years ago) was Vetur and they really struggled with performance regressions and great intellisense support.

These libraries with their custom string templates I expect to really struggle to achieve and maintain the level of tooling support I've come to expect. And even if they can; why god, why another custom language requiring a pre-compiler? Felt like we were finally getting out of that a bit with fall of coffeescript, SASS falling out of favor due to the performance issues, babel falling by the wayside in favor of fast SWC or Esbuild with the death of IE and the rise of greenfield browsers.

IMHO MobX has shown us how fine grain reactivity can be accomplished with proxies ages ago; with great DX. SolidJS is showing us what can be done without a compiler(it does some light JSX transformation but AFIAK it doesn't have too and there is no custom language). Vue has made most of the goodness of their string template syntax available in JSX via the newish attribute extensions.

Why do we need another string template language? Why another compiler? React Optimizing Compiler? This is not the way.


I recommend you to have a look at Phoenix Elixir LiveView next.



And if you still want to use Svelte in LiveView for client side state management, and keep all the server side reactivity (while using Svelte!), I've made a library for it :)

https://github.com/woutdp/live_svelte


Thanks for releasing this, saw it earlier this week and am excited to try it! Kind of wish we had had it for the start of our current project 6 months ago, but seems like with SSR Svelte is a great fit for LiveView.


I'm a huge fan of svelte because the developer experience is pretty great when you first build something but also when you revisit something you haven't touched for a year or two.

Another thing that svelte and similar tools get right IMO is that if you have someone dedicated to design, then the HTML/CSS are maintainable by them throughout the lifetime of the project. A lot of times we'll have a dev do a rough pass on basic functionality and then a web designer come back and make it look good and it rarely requires much back and forth or coordination. Or later in life the project will get a revamped design and it gets implemented without the dev having to do anything. No doubt the JSX-based frameworks have figured out a way to make these scenarios work just fine, but I've been really happy with how naturally the division of labor works out with svelte.


After having used all of the big libs/framesworks I honestly only care about DX. They all get the job done, are fast enough and have some major or minor gotchas.

Svelte/Sveltekit has the best DX by far and only some minor gotchas, esp. reactive expressions as described in the article. Once you get how it works, Sveltekit is such an empowering experience, I can't imagine being more productive with anything else.

BTW, I'm using Sveltekit for an SPA, which is well documented, and skeleton.dev, a young but promising UI Tookit. Integration with native libs like echarts or three without any issues.


the problem that the transition api solves is that if you want to animate a dom node on removal you have to delay the actual removal until its animations are done. you even need this feature if you do all animations with pure css.



That is a Javascrpt API, not pure CSS


I use Svelte for all the project under my supervision and the biggest problem I encountered is that functions defined in a component <script> section are all executed when the component is created. This is painful sometimes, especially for new team members. Never used ``` {#await} ``` SvelteKit works. Reactivity is not a problem, but we use stores a lot, however (means global variables of a kind?).


So basically, using $ with expressions and no side-effects within the expression will not cause the issue the article is having?


I'm pretty sure there are still people building really awesome things with Ember or JQuery or Angular or Backbone.

Oh have you heard of luxpop.js all the cool people are using it, it has bitransitional anti-mutation mega-flip data binding so you regain a microsecond rendering that p tag.

You haven't heard of it? You dinosaur!


rewritten an nuxt+vue2 svelte like 2 months ago, and I love it, it just works, no gotchas

bind:this is amazing, just lack of IDE support


Anyone transitioned from Vue 3 to Svelte? Worth it, regrets?


I wonder how many JS/TS fronted frameworks are there.


Really only 10 or so (well "families" of JS frontend frameworks anyway) being actively used for new projects.

I mean if you consider React/Next/Gatsby separate frameworks then there are more, but generally it's Angular, React, Vue, Svelte, Solid, Qwik, Ember, Redwood, HTMX. If you include other programming languages (Elm, elixir ?) then there are definitely many more


Whoops. Too late to edit, but redwood is react on the frontend also. It's more of a "full-stack" framework too, but a "serverless" full-stack framework.

I'm sure I missed one or two actual front-end frameworks though


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

The reactivity system in Svelte is really a joy to use, once you get used to it there's no turning back.

But the author did hit one of the ugliest pain points about it. Svelte can NOT correctly infer transitive dependencies when the variable being updated is inside a function. Meaning that the variable itself will be reactive (it will be invalidated every time it's assigned, even inside a function) but Svelte is not using that information to build the dependency graph, and falls back to the order in which the reactive blocks were defined, which may or may not be right.

I created this issue https://github.com/sveltejs/svelte/issues/5190 a couple years ago documenting it.

It's not so common, but when it bytes you it's pretty nasty.

The workarounds I found are the following

These are the workarounds I found:

- a repl with the issue: https://svelte.dev/repl/640736d3c91d40d3971afcc3eef8b25e?ver...

- workaround 1: manually reorder statements, need to figure out by yourself (and maintain!) the dependency graph: https://svelte.dev/repl/3ecd6aa918e045999db32d379270fc1c?ver...

- workaround 2 (my favorite): provide a redundant update as "hint" to tell the compiler that setY updates y: https://svelte.dev/repl/cbf98bb35f5e4dd4b037d13254853c90?ver...

(thanks to TylerRick for this: https://github.com/sveltejs/svelte/issues/5190#issuecomment-...)

in practice it means to do something like: `$: { setY(x); y = y };`

- workaround 3: put the update operations in order in a single block (it's just the workaround 1 with improved legibility, IMHO): https://svelte.dev/repl/074df362bb934312bbe6fd3aeccab771?ver...

I still think we could do better, at least explaining the issue and how avoid to fall into it (perhaps some linting warning?)

But I really hope svelte developers start considering this an issue to solve, it's inconsistent (meaning the variable is reactive but that reactivity is not taken into account to order the operation in "topological order" (Hey, I learnt about that from one of Rich's presentations, see https://rethinking-reactivity.surge.sh/#slide=19) and as I said before, in the rare occasions you stumble upon it is not so easy to understand what's going on.


Interesting, my memory of reading about the Svelte magic reactivity was that it was pretty well explained that the only things 'reactive' would be things which were assigned to in the reactive statement.

So if you want to update y on some changes to x, you do

    $: y = x

And if you need something more complicated, a transformation perhaps, you put the logic in a function and assign y to the result of that

    function parseX(val) { ... }
    $: y = parseX(x)


top level variables are reactive even when updated inside a function, just give it a try:

https://svelte.dev/repl/44e3aece18294ddb834bcdfb4394af48?ver...

` <script>

  let name = 'world';

  const flip = () => name = name === name.toUpperCase() ? name.toLowerCase() : name.toUpperCase()

  $: console.log({ name })
</script>

<h1>Hello {name}!</h1>

<button on:click={flip}>flip!</button> `


the inconsistency comes from the fact that this reactivity, triggered from inside a function, is not taken into account to build the dependency graph and ultimately decide in which order to process the statements


Use the platform!


Thanks for this overview, I definitely had some svelte fomo and now I’m feeling better in a react land.


So rather than fearing you're missing out, you went back to React to make sure you were missing out? ;-)

Life is too short for constantly writing boilerplate and performance analysis on a virtual DOM. Don't fall victim to Stockholm Syndrome.


Mostly agree with the article but cringed a bit when I read this:

> This subtlety led to more than one case where I didn't understand why a component didn't update. ... 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.

OK, that's like you're used to using an old donkey for transport and then someone hands you a brand new car and you start complaining about it not having seat heaters.

The $-based reactiveness of Svelte is great! Just don't expect that every possible side case is covered 100%. Same as with just about any other technology.


Well ya, your old donkey was essentially a cozy self driving seat that refueled itself by mowing your grass. Not having the heated seats at the same time as having to adjust to all the changes can be hard, to matter how nice the car/framework is.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: