My experience with Svelte
Svelte is the fourth framework by popularity, highly praised for its DX. I had a chance to build a sizeable app with it. In this post I will reflect on this experience, and why, despite liking it, I moved back to Vue a bit over a year later.
Why Svelte
When a few years ago I decided to rewrite Things To Have, my wishlist app, from a friends-only pet project to a full-featured app, I realised that I would need SSR for discovery and marketing needs.
Back then the app was written in Vue, and considering that the only mainstream SSR framework for Vue was Nuxt, which I personally see as a bad framework both in terms of ideas and general reliability, adding proper SSR was a demoralizing task.
At the time React frameworks were in a weird state of incomprehensible Remix/Router dichotomy, TanStack Start wasn’t a thing and Vercel-bound Next.js didn’t resonate with me at all. Also most of the code was written by hand back then, so choosing React, which famously neglects DX, didn’t seem appealing to me.
I always wanted to try Svelte, v5 seemed promising, and SvelteKit addressed everything I disliked about Nuxt.
So I rewrote the whole app in it, using SvelteKit as a fullstack framework. It went smoothly, as I already had an MVC-like approach on the backend. As a result, client-side code was drastically reduced, and the app got proper SSR.
I carried the app this way from late 2024 to early 2026, but once Inertia V3 was released I decided to return to Vue. Agentic coding allowed me to tailor a dream SSR experience in the form of hono-inertia, and also made the switch a matter of hours.
The biggest reason behind the return was the poor support of most testing tooling – most prominently, Storybook – which made tracking app stability too hard.
But let’s get into the details:
What I liked
- You can write proper api-less MVC and move most of your code to the server, clearly separating client- and server-side code. This is how, I believe, every fullstack framework must operate, and sadly it is misunderstood by many, for example Nuxt.
- SSR just works. You just write code, and it renders everything on the server, unless you do something extravagant. This was the smoothest SSR experience I ever had.
- A lot of basics done right: Vue-like SFC approach, sane reactive hooks aka runes, proper CSS tooling like clsx-like class and scoped styles
- Handy async template conditionals
- Fullstack & SSR and Stores are an integral part of the framework
- It has animation hooks!
What I disliked
-
Poor support of 3rd party tooling. Storybook 9 didn’t work for me despite being “supported”, and the Storybook 10 announcement urged Svelte users to try again, but I wasn’t able to make it work again.
I also had experience with the first-party eslint plugin taking minutes to run and reporting mistakes that were impossible to fix.
-
Docs are too scattered. Basically there are three docs destinations, which have both unique information and overlap – Svelte, SvelteKit and Tutorial.
Inside, docs are structured in a random way – some non-important topics are documented with two paragraphs covering small part of available APIs, some are long thoughtfully written docs covering many topics at once, making them easy to learn, but hard to use as a reference.
-
Ambient types, clean differentiation between server and universal, .svelte.ts files – all of these make your DX extremely smooth, and give you unusual confidence about how and where your code runs.
But this is also a curse of this framework. All this stuff is hard to mock and integrate with all sorts of testing libs.
Sometimes these prevention measures lead to situations where you can’t connect one piece of code to another, while you 100% could do it in any other framework. This constant cavediving-like fear of going too far, only to realise that it wouldn’t work because of foolproof measures, is frustrating.
-
While being in many ways Vue-like, Svelte passes data to the parent via drilling callbacks. This verbose approach comes straight from React, and results in either hard-to-read HTML templates or overreliance on state managers.
-
Svelte’s implementation of slots called snippets is confusing.
-
Form actions sound nice, but result in bizarre looking code and a lot of in-template coding.
-
This was well before agentic coding, but back then AI was bad at writing Svelte as 4 and 5 differed a lot. There is a lot of back and forth happening in general.
Conclusion
I enjoyed my time using Svelte. It helped me understand how great moving code out of the frontend can be, and validated many of my ideas on how a good fullstack framework should operate.
While I recommend exploring Svelte and SvelteKit on a small project, I doubt it is suitable for big apps.
Compared to the most popular frameworks like React and Vue, it has a small ecosystem and limited tooling support. Stability is also questionable, with large syntax changes between versions (it is already version 5 of a young framework).
A lot of people come to it from React in search of better DX, but on DX it lags behind Vue.
Most importantly Svelte fails to do what Vue nails: in Vue every DX improvement or other magic piece just works and never interferes with your work. But writing Svelte feels like you are trapped in a DX dream, where you always think about being footgunned by some magic stuff. Interfering magic is worse than no magic.
If you ask me what is the best way to write fullstack apps, my answer will be whatever backend framework you have glued to Vue via Inertia.