Project Two
August 23, 2025Creating Mobile app using Tauri + Svelte
The goal of Project Two is to get familiar with Tauri, a Rust framework for creating cross-platform apps.
This project focuses on the Android and iOS platforms.
Functionality of the app
It helps users memorize contacts from their phone’s contact book. That said, the functionality itself isn’t the main focus here, as the primary goal is to gain familiarity with creating mobile apps using Tauri and Svelte.”
The app has only two screens:
Contacts list | Card |
---|---|
![]() | ![]() |
- Contacts that are wanted to be learned selected from the contacts list.
- Card shows a contact and expects to a phone be entered. After submit it checks and shows a correct phone.
What I learned
Palete
Pantone colors
To choose colors for the app I used The complete color harmony book.
In color theory, each color or combination of colors influences human emotions. I chose a palette from the book to create a casual mood.
This what I choose.
1 | 2 | 3 | 4 |
---|---|---|---|
![]() | ![]() | ![]() | ![]() |
CSS
In css colors can be represented as hsl() function.
This function is based on Munsell color system
- h - Hue
- s - Saturation ( Chroma )
- l - Lightness ( Value )
This representation is very convenient: hue defines the base color, while saturation and lightness enable easy creation of monochromatic variations, which is particularly useful in UI development.
In my case I was only changing saturation. Using Pantone color as a middle value and changing saturation with a step of 5%.
Code could be found here Colors.svelte.
This is the final color set vars.css
--bgColor-primary: var(--color-2566CP-1);
--bgColor-primary-light: var(--color-2566CP-7);
--bgColor-second: var(--color-2311CP-3);
--color-primary: var(--color-2311CP-3);
--color-second: var(--color-2566CP-1);
--accentColor-primary: var(--color-1535UP-10);
--accentColor-second: var(--color-1535UP-10);
--btnColor-primary: var(--accentColor-primary);
--borderColor-primary: var(--color-1535UP-2);
For a layout I used approach based on Every Layout book. (This book is fantastic).
Svelte
Svelte is a great way to build user interfaces (UIs). It feels so natural, like actual vanilla web development.
Here are a few resources that I used as references for Svelte UI development:
- Leo - it is Brave web browser ui components.
- Svelte 5 github topic
- Svelte 5 router
- Component Library
One thing I struggled with was state management in Svelte (I mean it is easy I just did’t know).
I wanted to load contact lists from the phone book or a stored file and manage that state across the entire app.
Here’s the approach I took:
- contacts.svelte.js - file responsible for contacts management logic across the app. Svelte in its name allows to use svelte runners in may case it was
$state()
- contactsState is created here. Loaded here layout.js (load function is called by svelte before component is created). Initialised here +layout.svelte . Then it can be used across the app in the reactive way. One thing to mention is when I want to update contactState I delete all values from the
value
state and add all new values. If just replacevalue
incontactState.value
with a new array reactance is gone.
Tauri
This is my first experience with Tauri.
My initial impression is that it’s a great way to build cross-platform apps.
I won’t explain the core Tauri concepts or project bootstrapping here, as that’s covered in the Tauri quick start. I’ll just share what I did.
To interact with the native OS (in my case, Android and iOS), I used Tauri plugins. Tauri has a solid list of plugins.
For example, I used the file system plulgin to store the app’s state in the file system.
I also created a custom plugin to access the contacts list on each mobile platform. What I found challenging was developing and debugging the plugins’ native code on these mobile platforms.
Here I will highlight some parts that were not very obvious for me.
Start developing a project with a plugin these commands should be run
pnpm create tauri-app project-name
cd project-name
pnpm tauri android init
pnpm tauri ios init
pnpm tauri plugin new --directory /full-path/project-name/plugins/plugin-name plugin-name
cd plugin-name
pnpm tauri plugin android init
pnpm tauri plugin ios init
Access users sensitive content on the phone
For android
add to AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
For iOS
add to Info.plist
<key>NSContactsUsageDescription</key>
<string>This app needs access to your contacts to show them in your contact list.</string>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
</array>
</dict>
</plist>
This was a confgs part.
Apps also need to obtain permissions at runtime. Tauri already provides two commands
for this purpose, which we need to expose: check_permissions
and request_permissions
.
Look into these files
- commands.rs
- mobile.rs
- index.ts - expose commands to javascript
- default.toml
In android part - plugin should have permissions annotation ContactsPlugin.ktl
In iOS part - ContactsPlugin.swift checkPermissions
and requestPermissions
should be overwritten.
Permission state has three types prompt
| denied
| granted
This is example how these commands are used in contacts.svelte.js
Commands
pnpm tauri info
- gives the info about the project.pnpm tauri ios dev --open
- run project on ios emulator. If it is already open omit--open
pnpm tauri android dev --open
- run project on android emulator. If it is already open omit---open
Resources
- For iOS development xcode is required
- For Android development android studio is required
- Android API reference
- Apple developer documentation
- tauri ios plugins - this repo holds a bunch of ios related plugins.