Svelte Native - First Impressions



Like anyone with a passing interest in front end technologies I've come across the new hotness known as Svelte. It's so simple and pleasant to use and I completely get why it's taken off.

Less well known is the Svelte Native project, an attempt to occupy the same space as the popular React Native. I've used React Native and prefer it to the other alternative I tried for cross platform mobile development, Xamarin. But it's still React which has its own pitfalls and I'm always looking for new things to try. So I've been playing with Svelte Native for a few days and thought I'd jot my thoughts down.


The first thing you need to do is install NativeScript. This is the underlying technology for calling native mobile APIs in much the same way as happens with React Native. There are pros and cons with both technologies and if I was making a business decision for a company I'd probably go with React Native because it has a much bigger eco system. But NativeScript has improved a lot and it's compatability with other frameworks is a big win.

I installed it globally like so:

npm install -g nativescript

That was all the setting up I needed to do with NativeScript. One thing of note though is I use pnpm instead of npm as it works with all the same commands but uses symlinks and prevents your drive getting bloated with Node packages. NativeScript works fine but I couldn't use pnpm with Svelte Native itself and it took me a few attempts to realise this as sometimes the project would build. I followed the instructions on the main Svelte Native website and created a quick basic app:

ns create myapp --svelte

To get it running it was a case of running the following command:

npm run

I did hit some problems. The first issue was the Svelte template that was packaged with NativeScript was out of date. As a result the libraries being loaded were all old and I spent a bit of time working out what worked with what.

SvelteNative has been updated and the correct template now loads but then the next issue popped up. The default app setup doesn't work correctly. It throws an error on iOS if you try and save anything:

Sometimes it will restart correctly but Hot Module Replacement simply will not work. In the app.ts file svelteNativeNoFrame component is imported:

import { svelteNativeNoFrame } from 'svelte-native'
import App from './App.svelte'

svelteNativeNoFrame(App, {})

There were problems with this component and I had to use svelteNative instead:

import { svelteNative } from 'svelte-native'
import App from './App.svelte'

svelteNative(App, {})

This meant the App.svelte root component required changing from:

  <Home />

<script lang="ts">
  import Home from './components/Home.svelte'

To the following:

<page actionBarHidden="true">
  <frame id="rootFrame" defaultPage={Home}></frame>

  import Home from './components/Home.svelte'

The actionBarHidden attribute is optional but adding this made it look consistent across Android and iOS.

Now npn run will work. Depending on what simulators you have running it will try and run the app in one of them. The only caveat being it wouldn't automatically start the Android simulator and I had to start Android Studio and then manually start the simulator. The iOS simulator started automatically.

There's a tutorial for a todo app on the main website here and I decided to give this a go. After configuring my setup like above I managed to get things running fairly easily. My working repo can be found here.

The todo app is useful but I wanted to check the full power of the library and I noticed some other demo apps which I thought I'd try and get running:

The first was the set of examples that came with the main library here. I obviously ran into the same issues described above but I also had a problem loading the menu icon, particularly the svg file. I switched to using a good old simple png file. My working repo is here .

I also came across the related svelte-native-nativescript-ui library. I'm not sure how active this project is, the last commit was in October but I thought I'd give it a try as well. Here are the demo apps I tried to get working. I had an annoying formatting error to fix first:

Unfortunately there were some things I just could not get to work. Some properties with the radDataForm component won't work. I have highlighted the two I came across in the DataFormPage.svelte markup:

<!-- Crashes if the following attribute is added:
 converter={movieConverter} -->
<entityProperty name="movie" 
  displayName="Movie Name" 

And here:

<!-- Crashes if agreeTerms is selected -->
<entityProperty name="agreeTerms" displayName="I Agree with Terms" index="9">
  <propertyEditor type="Switch" />

Most other things worked although using the radListView wasn't as smooth an experience as it should have been. As I say, I don't know if the project is active and I'd suggest using the NativeScript components only at this stage.

My working repo is here.

In Summary

All my projects listed above were tested successfully on an iPhone 12 simulator running iOS 15 and the Pixel 5 Android simulator. I didn't investigate but the Pixel 2 did not work.

The Good

Svelte Native works! You can defintely use this to build native phone apps with the same code base and once you're past the rough edges the development is reasonably straightforward. HMR works pretty well and I didn't have issues different from those I already experience on other platforms.

The Not So Good

For me this is still beta software and not a 1.0 release. Getting up and running isn't simple and requires some effort. Someone who is not an experienced developer will not like it even though it does have a lot of promise.