DEV Community

Cover image for Tauri - The Flutter killer?
AILI Fida Aliotti Christino
AILI Fida Aliotti Christino

Posted on • Updated on

Tauri - The Flutter killer?

What is Tauri?

Tauri is an open-source framework for building cross-platform desktop applications using web technologies such as HTML, CSS, and JavaScript.

Tauri has been in front of the scene these times and was considered as one of the best option to build desktop apps along Flutter but hasn't get to mobile development yet!

Now a new era begins 👑! Tauri is now able to build with the same codebase, apps for mobile. Through this article i will help you configure a project to build for Android devices.

My environment

For the purpose of this article, i will be using:

  • A macbook pro M1 ARM Chip with MacOS Ventura 13.2
  • A terminal with fish shell and Homebrew installed
  • An android device running on Android 12

Tauri Mobile

On the Tauri Blog, they've announced an alpha release of Tauri mobile. In this article, i will help you create your first app with it! Let's dive in! 🏊‍♀️

Android Pre-requisites

Java Development Kit (JDK)

In order to build our android app, we need to install first the JDK. And again, feel free to select the one that suits your OS.

Android SDK

As we are building an app for android, we need the android SDK tools. It will helps us to build and test Android apps, and to publish your finished app to the Google Play Store or other app markets.

The easiest way to install it is to download Android Studio. Head over to their website 👆 and click on the Download button. Click on the agreement button and select the right version for your computer, in my case for example, i've downloaded the one for the mac with Apple chip.

Android studio download pop-up

When your download is finished, install it by double-clicking on the file. Leave all default option and download the latest SDK as the software ask you. To make sure that everything is ok, let's open the settings represented by a three dot button next to the open button and select SDK Manager.

You should see something like this:

SDK Manager

Download the one corresponding to your Android device if it's not already installed. Then we'll head over to the SDK Tools tab then select:

  • Android SDK Command-line Tools (latest)
  • NDK (Side by side)
  • Android SDK Build-Tools
  • Android SDK Platform-Tools

SDK Tools Tab

Then click on the Apply button.
Now that we've done that, we can close Android Studio for now.

Environment variables

Now we need to specify some environment variables. Please feel free to search on the internet how to do it for your OS.

In my case, i'm using a mac with a fish shell (i can write an article on that if you are interested 😉) installed on it so my command will be code ~/.config/fish/config.fish to add environment variables. My file will be like this:



if status is-interactive
    # Commands to run in interactive sessions can go here
end
if status --is-login
    set -gx ANDROID_SDK_ROOT $HOME/Library/Android/sdk
    set -gx NDK_HOME $HOME/Library/Android/sdk/ndk/25.1.8937393
end


Enter fullscreen mode Exit fullscreen mode

⚠️ After having doing this, i suggest you to close your terminal and open a new one to enable changes.

As you can see, i've added those 2 variables: ANDROID_SDK_ROOT and NDK_HOME. Change these values according to your paths.

Still following 😅? I know this can be frustrating doing all these configs but believe me, good days are coming! Now that we've done the Android specific configuration, let's install tauri 🥵

Install Tauri for mobile

Pre-requisites

The tauri documentation is clear enough to get along yourself without any extra help.

Prepare Tauri for mobile development

Please head over their documentation to prepare your workspace as i think it's already clear and easy to begin with.

Create your application

From here, i'd ask you to follow along carefully to avoid getting lost.

Let's start by creating a simple Vite app:



> pnpm create vite


Enter fullscreen mode Exit fullscreen mode

You will be asked some informations like:

  • the name of your project (i chose "taurituto")
  • the framework you will use (i chose React with TypeScript)

Install required packages with



> pnpm i


Enter fullscreen mode Exit fullscreen mode

You should have something as similar as this:

frontend project structure

Nothing special if you are familiar with Vite apps.

Let's do some configurations before adding our Tauri app.

Vite config

As Tauri will run this Vite app on our mobile app, we need to set it up so it can display our content using our computer port and IP address.

Let's see what we got inside our vite.config.ts file for now:



import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
})



Enter fullscreen mode Exit fullscreen mode

Like mentioned on this documentation, we need to change this file in order to run our Vite into the mobile app. First, we need to install internal-ip, you know the drill:



pnpm i -D internal-ip


Enter fullscreen mode Exit fullscreen mode

And change our vite.config.ts to use it:



import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { internalIpV4 } from 'internal-ip'

// https://vitejs.dev/config/
export default defineConfig(async () => {
  const host = await internalIpV4();
  return {
    // prevent vite from obscuring rust errors
    plugins: [react()],
    clearScreen: false,
    server: {
      host: '0.0.0.0', // listen on all addresses
      port: 5173,
      // Tauri expects a fixed port, fail if that port is not available
      strictPort: true,
      hmr: {
        protocol: 'ws',
        host,
        port: 5183
      },
    },
    // to make use of `TAURI_PLATFORM`, `TAURI_ARCH`, `TAURI_FAMILY`,
    // `TAURI_PLATFORM_VERSION`, `TAURI_PLATFORM_TYPE` and `TAURI_DEBUG`
    // env variables
    envPrefix: ['VITE_', 'TAURI_'],
    build: {
      // Tauri supports es2021
      target: ['es2021', 'chrome100', 'safari13'],
      // don't minify for debug builds
      minify: 'esbuild',
      // produce sourcemaps for debug builds
      sourcemap: 'inline',
    }
  }
})



Enter fullscreen mode Exit fullscreen mode

Ok, now we are ready to add our Tauri app part!

Adding Tauri

Let's add the Tauri CLI as it will help us to install the Tauri app along with our Vite app:



> pnpm add -D @tauri-apps/cli


Enter fullscreen mode Exit fullscreen mode

Now that we've got it installed, run:



> pnpm tauri init


Enter fullscreen mode Exit fullscreen mode

It will except you to answer a bunch of questions:



> ? What is your app name? <yourappname>
> ? What should the window title be? <you can leave it the same as your app name>
> ? Where are your web assets (HTML/CSS/JS) located, relative to the "<current dir>/src-tauri/tauri.conf.json" file that will be created? ../dist
> ? What is the url of your dev server? › http://localhost:5173
> ? What is your frontend dev command? › pnpm run dev
> ? What is your frontend build command? · pnpm run build


Enter fullscreen mode Exit fullscreen mode

You should now see a folder called src-tauri as the root of your project.

Then navigate to src-tauri directory then run these commands:



> cargo add tauri@2.0.0-alpha.4
> cargo add tauri-build@2.0.0-alpha.2 --build
> cargo install tauri-cli --version "^2.0.0-alpha"


Enter fullscreen mode Exit fullscreen mode

Ok, we need to adapt our project file in order to launch it on mobile. Open your Cargo.toml file located inside src-tauri and add these lines:



[package]
name = "snapchat"
version = "0.0.0"
description = "A Tauri App"
authors = ["you"]
license = ""
repository = ""
edition = "2021"

[lib]
crate-type = ["staticlib", "cdylib", "rlib"]

...


Enter fullscreen mode Exit fullscreen mode

Now go inside your src folder on the same level and add 2 files lib.rs and mobile.rs with those lines:



// lib.rs

use tauri::App;

#[cfg(mobile)]
mod mobile;
#[cfg(mobile)]
pub use mobile::*;

pub type SetupHook = Box<dyn FnOnce(&mut App) -> Result<(), Box<dyn std::error::Error>> + Send>;

#[derive(Default)]
pub struct AppBuilder {
  setup: Option<SetupHook>,
}

impl AppBuilder {
  pub fn new() -> Self {
    Self::default()
  }

  #[must_use]
  pub fn setup<F>(mut self, setup: F) -> Self
  where
    F: FnOnce(&mut App) -> Result<(), Box<dyn std::error::Error>> + Send + 'static,
  {
    self.setup.replace(Box::new(setup));
    self
  }

  pub fn run(self) {
    let setup = self.setup;
    tauri::Builder::default()
      .setup(move |app| {
        if let Some(setup) = setup {
          (setup)(app)?;
        }
        Ok(())
      })
      .run(tauri::generate_context!())
      .expect("error while running tauri application");
  }
}


Enter fullscreen mode Exit fullscreen mode



// mobile.rs

#[tauri::mobile_entry_point]
fn main() {
  super::AppBuilder::new().run();
}


Enter fullscreen mode Exit fullscreen mode

Then replace our main.rs file to use the AppBuilder struct:



//main.rs

#![cfg_attr(
    all(not(debug_assertions), target_os = "windows"),
    windows_subsystem = "windows"
)]

pub fn main() {
    app::AppBuilder::new().run();
}


Enter fullscreen mode Exit fullscreen mode

Now we are ready to initiate our android project. Let's run go back to our root project and run this:



pnpm add -D @tauri-apps/cli@next @tauri-apps/api@next && pnpm tauri android init


Enter fullscreen mode Exit fullscreen mode

With this command, the cli tool will do some configuration for us so let's sit back and wait for it to complete 🧋

✅ When the cli has finished, go to src-tauri, you should now see a folder called gen with some android relative files in it. It means that the tool has correctly generated an android project for you 👍.

One last thing before we run this on our device. Open tauri.conf.json file inside src-tauri and change the bundle identifier to a custom one following this pattern com.$developeralias.$appname. For example, for me, i've changed it into: com.yourname.appname.

Ok, now let's run our app 😁, run the command: pnpm tauri android dev [--open]

What this command will do is trying to launch our app on android emulator and if it doesn't find one, it will open Android Studio for you. In my case, i want to run it on my real device so i'll wait the Android Studio to pop up.


❌ I had to change this line in the build.gradle.kts file to match my configuration:



// Change this
implementation("com.android.tools.build:gradle:7.3.1")

To this
implementation("com.android.tools.build:gradle:7.2.1")


Enter fullscreen mode Exit fullscreen mode

⚠️ If you stumble across an error saying that @tauri-apps/cli-darwin-x64 is missing, then install the required dependency by pnpm i --save @tauri-apps/cli-darwin-x64


Test

android studio

Time to run our app! As you can see, it opened up Android Studio and detected my device perfectly. Just go on and click on the "Run app" button and wait for the app to run.


If the app doesn't run on the first time, try to close Android Studio and re-run the command:



> pnpm tauri android dev [--open]


Enter fullscreen mode Exit fullscreen mode

android app running

Yay! 🎉🎉🎉

Now try to change something inside src/App.tsx and save it. Changes are directly taken into account and update your app! 🤯🤩

As Tauri uses your favorite framework to load, you can use our favorite tools with it!

You can also build your app by doing this command:



> pnpm tauri android build

Enter fullscreen mode Exit fullscreen mode




Final words

Tauri for mobile is still in alpha release so i do not recommend using it on production but i think that it's already pretty cool 😎. Next time we will discuss about the interaction with Rust and mobile plugins! 😀

Let me know if you want me to do more tutorial about it! 😊

Thank you for sticking with me till the end! See y'all! 👋

Buy Me A Coffee

Top comments (3)

Collapse
 
careuno profile image
Carlos Merchán

too many things to do, in flutter is much easier

Collapse
 
yansenlei profile image
Ray

so cooool!
look forward to “Next time we will discuss about the interaction with Rust and mobile plugins! 😀”

Collapse
 
drumm profile image
Sam J.

Nice post! Looking forward to seeing an iOS app as well, using almost the same codebase 😉