The other day I received an email from a reader with a few interesting questions and I thought I would share my answer as a blog post. Hope you find it interesting as well. It's about Svelte, Sapper, SSR vs SPA and Svelte router recommendations. Raw and unedited.
I found your blog about Svelte and Js development really well written.
It seems that you’re liking Svelte a lot. My company uses VueJS for now but was trying to use Nuxt because of the SSR aspects.
However I found the SSR part to be brittle, like if it was an add on not well thought out.
Would you recommend Svelte and what Router do you like? We’re a small team of 3 so we do need some structure and some “best practices “.
And thank you for the kind words! I will try to answer your question in detail. These are, of course, my personal thoughts.
Correct, I like Svelte because it "fits" in my head. Its simplicity is what attracted me in the first place. I've used both React and Vue at work. While both are fine, we never clicked. Call me old school, but while I understand the concept and the need behind JSX, I find it weird. It's not for me. The Vue model fits "my style" better than React, but I find some of its design and architecture decisions weird. But let us not deviate from your question!
Second reason I like Svelte is that it doesn't use virtual DOM, which I always thought is pure overhead. Svelte is not a framework, but a compiler, right? You can do so much more with a compiler, than with a virtual machine, which React actually is. For example, one obvious thing is that a compiler catches compile time errors. Add Typescript to the mix and you just halved your potential runtime errors. Also, with compiler you end up with smaller bundles, as all the code is optimized at compile time and you don't have to bake in a Virtual DOM machine.
Now, back to the first part of your question - Would you recommend Svelte?
Definitely! It's stable and is used successfully in production by many companies. Now when it finally has official Typescript support hopefully more developers will start taking it seriously.
And for the second part of your question - What router do you like?
I am a big fan of DYI, but up to a certain degree. If something takes me a few hours to implement, I will often do it instead of using some library. For my projects I use Page.js as my router. It's a battle-tested library that I've used before and that I trust. I've created a simple Svelte wrapper on top of it that fits my needs. If you are interested, here is the link to the article - Svelte routing with Page.js, Part 1.
Routify seems to be a popular option, but I haven't had the chance to try it yet. Spontaneously, I don't like a library that forces you to use it in a certain way. With Routify you have to start your app from Routify, so to say. I understand the reason behind. It's a file-based router, it needs to use the file system in order to build up its router tree. Routify also supports SSR if that's important to you.
With that said, one Svelte router I've been digging lately is svelte-navigator. It's actively maintained, has an intuitive API and seems to be feature complete. Check it out!
Just like Vue has Nuxt and React has Next, Svelte also has an official SSR solution - Sapper. But Sapper's development haven't been very active for the past year. It's currently on version 0.28, but looks like the development is picking up again. I don't know when and if it will reach version 1.0, but expect a few breaking API changes on the way. With that said, many companies are already using it successfully in production today.
Let's talk a bit about SSR vs SPA debate. Why and when should you use SSR instead of a SPA?
In my opinion, if you are building an app that needs to be crawlable by search bots, SSR is the way to go. Blogs, forums and news apps come to mind. The rest is a grey area.
There are pros and cons when it comes to SSR apps. Sapper in Svelte's case.
Some of the pros:
- Because of code splitting, your app will load faster. Sapper has a router built-in, so you get the routing for free. When you first load the page it loads only necessary JS code and then starts to hydrate the rest of the application. Each application page has its own JS and CSS bundle.
- Sapper has a cool prefetch feature built-in. When you hover over a link or touch the link on you phone screen, you can start prefetching the page ahead of time.
- If you know that your app will grow in terms of features, SSR helps you to keep the page load times small, because of code splitting, unlike SPA where your total bundle size will increase.
- In Sapper, like other SSR apps, the router is file-based. This is a nice constraint that makes it easy to understand the mapping between Svelte files and pages.
- In Sapper you can build a JSON API as part of your app, which can be really helpful to keep separation of concerns at bay.
- Sapper has support for service workers built-in, which when used correctly can help you cache effectively and make your app work offline.
Some of the cons:
- SSR is more complex than SPA. You end up with more generated code that can be hard to debug when something breaks.
- SSR is more expensive to operate. You have the server costs vs just serving a JS bundle from a CDN. The costs might be marginal, but still.
- Your page can be rendered on the server and on the client. You don't know when and you have to anticipate both scenarios. The line is blurred, which can lead to weird code.
- Authentication flow is more complex in a SSR app than in SPA, because of the point above.
- Because of Sapper's router you have to be smart on how and where you cache your data when navigating between pages, otherwise you can end up with a lot of unnecessary data calls.
- Service workers can be complex to understand and implement correctly.
What about SPA's pros and cons?
Some of the pros:
- You often end up with less generated code, which can be invaluable if something breaks and you need to debug.
- You serve the app from a CDN, which can be cheaper than involving a server.
- You are free to structure your app in any way you like.
Some of the cons:
- When your app grows, so does your final JS bundle size.
- Your app is usually not SEO friendly out-of-the-box.
- Your app's perceived load speed will be slower because you have to load the whole app first.
- You are not forced to use any specific app structure. Sometimes constraints aka best practices can be good.
- Your templates are bundled together with JS, which leads to increased final bundle size.
I just realized that this was a very long answer to your email, so I will stop here, even though I love talking about these topics!
- Svelte is a safe bet. It's successfully used in production by many companies already, and it's growing in popularity every day.
- Sapper, Svelte's SSR solution, hasn't reached 1.0 yet, but that doesn't stop companies from successfully using it in production.
- If your app is small (final bundle size below 1MB), will not grow bigger and doesn't need SEO, I would build it as an SPA.
- If you build it as SPA and later decide to re-write it as SSR, you can reuse almost all of your Svelte components.
Good luck! I am sure you will have lots of fun and "no, it can't be that easy" moments on the way if you choose Svelte!
All the best, Ilia