DEV Community

loading...
Cover image for Svelte vs. Vue.js

Svelte vs. Vue.js

jesperhoy profile image Jesper Høy Originally published at jesperhoy.dk Updated on ・6 min read

I have been using Vue.js for client side browser stuff for a few years and I am very happy with it. However, I have been curious about Svelte for a while, and as I had an idea for a new project where Svelte might be a better fit than Vue, I decided to take a closer look.

Also, I have a number of ongoing projects in Vue 2, and with the significant breaking changes in Vue 3, now might be a good time to explore alternatives, as moving to a different framework might not be much more work than the Vue upgrades that I am facing anyway.

I recently did a small SPA (Danish budget calculator) based on Vue, and figured that it would be a nice test to convert this to Svelte.
I copied the .vue files to a new Svelte project, renamed the files .svelte, and then manually massaged them into the Svelte syntax.
The source code (Vue + Svelte) is available at: https://github.com/jesperhoy/Mit-Budget.dk

Minified and gzipped, the javascript for the original Vue version (https://mit-budget.dk/vue) is 9.2kb + 23.6kB Vue runtime = 32.8kB total. The Svelte version (https://mit-budget.dk/svelte) is 19.2kB.

The following is based on my experience converting this project:

In favor of Svelte

  • No runtime
    The Vue runtime is not that big, but still significant for smaller "apps".
    Consider, for example, the code to validate a simple contact form. Here the Vue runtime would be disproportional huge for the functionality provided.
    Small Svelte apps compile to just a few kBs and need no runtime.

  • No this... this... this...
    Unlike Vue, in Svelte you don't need to prefix everything with this. in code blocks to get at anything else within the same component.
    This is also a constant cause of errors in Vue for me. Template in-line script does not need this, and so whenever you move code between template and code blocks and forget to fix this - boom.
    A big part of the project conversion was removing this. all over the place.

  • Straight forward, readable javascript
    Unlike Vue where everything in an app or component must be expressed as one big object.
    The Svelte way, where you declare variables (let x=...) and write functions (function xyz(...) {...}) in the root of a <script> tag - just like good old fashioned straight forward javascript - is just easier to work with and much easier to read.

  • Zero indentation / no curly brace mess
    Vue requires at least 2-3 levels of indentation before you write any actual program code.
    Keeping track of all those curly braces can be a real pain - especially for larger component files.
    Reflecting back on my time with Vue, I often found myself moving functions to a separate global .js file, just to avoid the curly brace mess.
    This is not a problem in Svelte, and so I find it easier to keep code where it belongs.

Vue:

<script>
export default {
    methods: {
        MyFunction() {
            actual program code...
Enter fullscreen mode Exit fullscreen mode

Svelte:

<script>
actual program code...
Enter fullscreen mode Exit fullscreen mode
  • Less boilerplate
    No <template>...</template>, no export default {...}, no data: {...}, no methods: {...}, etc.

  • Two-way property binding
    In Svelte this is simple (bind:propname={variable}) which I found very convenient. In Vue.js it requires emitting events and more code.
    Beware though - a warning from the Vue.js documentation:

    Unfortunately, true two-way binding can create maintenance issues, because child components can mutate the parent without the source of that mutation being obvious in both the parent and the child.

  • Feels "closer to the metal"
    Based on the way code is written and the knowledge that there is no virtual DOM. Just a feeling.

  • Raw html rendering not tied to an HTML element
    Vue: <div v-html="HtmlString"></div>
    Svelte: {@html HtmlString}

  • Multiple root elements in components - a.k.a. "fragments"
    This is also possible in Vue 3 - but I am still on v. 2.

  • Better VS Code extension / integration
    Using the "default" VS Code extensions (Vetur / Svelte for VS Code), it appears that I am getting more assistance with Svelte files - like catching undefined variables inside {...} blocks in the HTML.

  • Performance (?)
    Svelte is supposedly faster at updating the display because it doesn't use a "virtual DOM" (like Vue, React, Angular, etc.).
    I never had any problems with display update speed in Vue (or Svelte) so I can neither confirm nor deny.
    However, I do imagine this being an advantage when coding for low powered devices.

In favor of Vue

  • Client side template compilation
    Smaller Vue "apps" can be included as source on a web-page directly without any pre-processing. Svelte apps cannot.
    For web-pages (not "apps") where you need just a little bit of reactivity (like order forms), this is perfect. No need to run a compiler/bundler etc.
    Another cool thing about this is, that it allows you to put dynamically server side rendered html/data directly inside a Vue template, mixing server and client side processing very nicely.
    I have personally used this quite a lot, and the beauty of this was exactly the thing got me started with Vue in the first place.

  • Smaller bundle size for large apps
    Svelte apps start out small (no runtime), but they grow faster than Vue apps.
    This became quite obvious as I was progressing through the project conversion.
    It would seem that at some point (around "medium sized" app), compiled Svelte apps become bigger than Vue apps including runtime.

  • Better browser DevTools
    Browser (Chrome/Firefox) "DevTools" are available for both Svelte and Vue.js, and with both tools, you can browse the live component hierarchy and see and change component property values.
    However that's it for the Svelte DevTools. The Vue.js DevTools also includes "Vuex" (for state), Events, Routing, Performance and Setting.

  • More flexible loops in templates
    In Svelte, the loop construct ({#each...}) only works with arrays.
    In Vue (v-for="...") it also works with iterables and numbers (v-for="x in 5").
    In the project conversion I especially missed the latter, and had to use less optimal workarounds for this.

  • Ecosystem
    Vue is more established and enjoys a much larger selection of component libraries, StackOverflow answers, blogs posts, etc.

Tie

  • Single file components (SFC)
    Both have this - which is just awesome.

  • Great documentation web-sites
    Both have this.

  • Reactivity
    In Vue, anything under data and props is reactive - including object and array children. And any code (anywhere) that reads those items will automatically re-run when the items are updated. This makes it pretty simple to work with.
    In Svelte you need to be more explicit about when you want reactivity. Variables declared at a script block root are reactive and so are explicitly defined "stores". But code that read these values will only be re-run automatically if the code is in a statement prefixed with a $: label.
    I haven't encountered any real problems/challenges related to this with Svelte so far, but I imagine that it at the very least requires a different way of thinking about reactivity.
    This Svelte $: label takes a little getting used to, but is kinda cool once you do get it. It works similar to the Vue computed and watch blocks, but different.

Things not considered

  • Routing
    I believe that Vue has an "official" routing library while Svelte "only" has 3rd party ones.
    This appears to be important to others, but doesn't make a difference to me, as I have never used any of them.
    I have done SPA page routing, but always found that using simple hash based routing was plenty (hashchange event / set location.hash).

  • Server side rendering (SSR)
    I believe that both can do this (through "Sapper" / "Nuxt.js" ?), but this is not something that I had any need for so far.

Conclusion

Someone asked the question "Does this code spark joy?"
Back when I discovered Vue - this really was a game changer for me - and it did spark a lot of joy :-)
I imagine many programmers feel this way when they first "get" the reactive UI model (be it in Vue, React, Angluar, etc.).

Vue still sparks joy, but I'm inclined to say that Svelte does so even more :-)

I really like the simpler Svelte syntax - including the "missing" this. prefixes and curly braces.
I also like the idea of not having a runtime.

However, for me, client side template compilation (see "In favor of Vue" above) and the fact that I am already heavily invested with Vue.js on existing projects, outweigh the advantages Svelte has.

So I am staying with Vue.js for now.

Discussion (0)

pic
Editor guide