Porting a medium-sized Vue application to Svelte 5
Jun 27 2024

Porting a medium-sized Vue application to Svelte 5

The short version: porting from Vue to Svelte is pretty straightforward and Svelte 5 is nice upgrade to Svelte 4.

Why port?

I’m working on Edna, a note taking application for developers.
It started as a fork of Heynote. I’ve added a bunch of features, most notably managing multiple notes.
Heynote is written in Vue. Vue is similar enough to Svelte that I was able to add features without really knowing Vue but Svelte is what I use for all my other projects.
At some point I invested enough effort (over 350 commits) into Edna that I decided to port from Vue to Svelte. That way I can write future code faster (I know Svelte much better than Vue) and re-use code from my other Svelte projects.
Since Svelte 5 is about to be released, I decided to try it out.
There were 10 .vue components. It took me about 3 days to port everything.

Adding Svelte 5 to build pipeline

I started by adding Svelte 5 and converting the simplest component.
In the above commit:
In the next commit:
Here replacing was easy because the component was a stand-alone component. All I had to do was to replace Vue’s:
app = createApp(AskFSPermissions);
app.mount("#app");
with Svelte 5:
const args = {
    target: document.getElementById("app"),
};
appSvelte = mount(AskFSPermissions, args);

Overall porting strategy

Next part was harder. Edna’s structure is: App.vue is the main component which shows / hides other components depending on state and desired operations.
My preferred way of porting would be to start with leaf components and port them to Svelte one by one.
However, I haven’t found an easy way of using .svelte components from .vue components. It’s possible: Svelte 5 component can be imported and mounted into arbitrary html element and I could pass props down to it.
If the project was bigger (say weeks of porting) I would try to make it work so that I have a working app at all times.
Given I estimated I can port it quickly, I went with a different strategy: I created mostly empty App.svelte and started porting components, starting with the simplest leaf components.
I didn’t have a working app but I could see and test the components I’ve ported so far.
This strategy had it’s challenges. Namely: most of the state is not there so I had to fake it for a while.
For example the first component I ported was TopNav.vue, which displays name of the current note in the top upper part of the screen.
The problem was: I didn’t port the logic to load the file yet. For a while I had to fake the state i.e. I created noteName variable with a dummy value.
With each ported component I would port App.vue parts needed by the component

Replacing third-party components

Most of the code in Edna is written by me (or comes from the original Heynote project) and doesn’t use third-party Vue libraries.
There are 2 exceptions: I wanted to show notification messages and have a context menu.
Showing notifications messages isn’t hard: for another project I wrote a Svelte component for that in a few hours. But since I didn’t know Vue well, it would have taken me much longer, possibly days.
For that reason I’ve opted to use a third-party toast notifications Vue library.
The same goes menu component. Even more so: implementing menu component is complicated. At least few days of effort.
When porting to Svelte I replaced third-party vue-toastification library with my own code. At under 100 loc it was trivial to write.
For context menu I re-used context menu I wrote for my notepad2 project. It’s a more complicated component so it took longer to port it.

Vue => Svelte 5 porting

Vue and Svelte have very similar structure so porting is straightforward and mostly mechanical.
The big picture:

Svelte 5

At the time of this writing Svelte 5 is Release Candidates and the creators tell you not use it in production.
Guess what, I’m using it in production.
It works and it’s stable. I think Svelte 5 devs operate from the mindset of “abundance of caution”. All software has bugs, including Svelte 4. If Svelte 5 doesn’t work, you’ll know it.
Coming from Svelte 4, Svelte 5 is a nice upgrade.
One small project is too early to have deep thoughts but I like it so far.
It’s easy to learn new ways of doing things. It’s easy to convert Svelte 4 to Svelte 5, even without any tools.
Things are even more compact and more convenient than in Svelte 4.
{#snippet} adds functionality that I was missing from Svelte 4.
svelte programming

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you: