What is Tauri?

Tauri lets you create cross-platform applications with web technologies and Rust. With it, you can quickly deploy apps to desktop and mobile platforms.

This weekend I made 2 mobile apps. Are they good? Well, they’re simple. Do they work? 100%. Can I improve on them? Absolutely. But I wanted to see how quickly I could get something up and running, and Tauri made it easy.

Getting Started

The easiest way to get started is to use cargo create-tauri-app and follow the prompts. You’re going to get set up with a Rust backend and one of a few frontend choices. You can accept all the defaults and use vanilla HTML/CSS/JS with:

# Set up the project
cargo create-tauri-app -t vanilla -y your_app && cd your_app

# Run the app on desktop
cargo tauri dev

From here, you’ll be building your backend inside src-tauri/src/ and your frontend inside the src directory. Tauri will handle the bundling and communication between the two through the use of commands. Functions in Rust can have the macro #[tauri::command] applied to them, and JavaScript can call these commands using the invoke function provided by Tauri.

Commands and Invoke

The full project structure made by create-tauri-app looks like:

Tauri Project Structure

Android Support

To take it one step further, setting up Android support is one more command:

cargo tauri android init

This will create everything under src-tauri/gen/android, which will be everything you need to build your Android app and either run in an emulator or push to your device over USB.

Tauri Android Project Structure

Icons

If you have an icon for your app and you want to generate all the different sizes needed, you can run cargo tauri icon ./your_icon.png. Ideally, this image would be the same size as the largest icon you need, and Tauri will generate all the smaller sizes for you. You’ll find these icons in the src-tauri/icons directory.

My Setup

Justfile

# List available commands
default:
    @just --list

# Run Tauri development server
dev:
    cargo tauri dev

# Run Tauri Android development
android:
    cargo tauri android dev

# Clean existing android structure in case names or package changed
android-clean:
	rm -rf src-tauri/gen/android

# Build and run Tauri in release mode (desktop)
run:
    cargo tauri build --no-bundle && ./src-tauri/target/release/app

# Build and run Tauri Android in release mode
apk:
    # or --apk for production
    cargo tauri android build --debug

# Deploy debug build to android phone over USB
apk-install:
    adb install -r src-tauri/gen/android/app/build/outputs/apk/universal/debug/app-universal-debug.apk

# Build and Deploy debug build to android phone over USB
debug:
    cargo tauri android build --debug
    adb install -r src-tauri/gen/android/app/build/outputs/apk/universal/debug/app-universal-debug.apk

# Run tests
test:
    # This project will be in src-tauri/Cargo.toml under [package]
    cargo test -p app

# Coverage
cov:
    cargo llvm-cov --html --open -p app

# Icon generation for all platforms
icon:
    cargo tauri icon ./icon.png

Then I can:

# Push a new build
just dev

# Run the app in an Android emulator
just android

# Push to my phone over USB
just debug

.vscode/settings.json

For a better development experience allowing rust-analyzer to work with the src-tauri directory, I configure:

{
    "rust-analyzer.linkedProjects": [
        "./src-tauri/Cargo.toml",
    ],
    "rust-analyzer.workspace.symbol.search.scope": "workspace_and_dependencies",
    "rust-analyzer.cargo.buildScripts.enable": true,
    "rust-analyzer.procMacro.enable": true,
    "files.watcherExclude": {
        "**/target/**": true
    },
    "search.exclude": {
        "**/target": true,
        "**/Cargo.lock": true
    },
    "files.associations": {
        "*.toml": "toml"
    }
}

src-tauri/tauri.conf.json

Some window settings I have configured that make sense for my apps:

...
    "app": {
        "withGlobalTauri": true,
        "windows": [
            {
                "title": "your_app",
                "width": 1000,
                "height": 900,
                "minWidth": 400,
                "minHeight": 600,
                "resizable": true,
                "fullscreen": false,
                "visible": true,
                "transparent": false,
                "decorations": true,
                "alwaysOnTop": false,
                "skipTaskbar": false,
                "center": true
            }
        ],
...

root Cargo.toml

So I can: cargo test -p app or just test:

[workspace]
members = ["src-tauri"]
resolver = "2"

Idea 1: Spaced Repetition App

cargo create-tauri-app -t vanilla -y spaced_out && cd spaced_out

and a few hours later…

Spaced Out App

Idea 2: Pomodoro meets Tamagotchi

cargo create-tauri-app -t vanilla -y pomagotchi && cd pomagotchi

and an hour later…

Pomagotchi

Wrapping Up

  1. Tauri is pretty intuitive and easy to work with!
  2. It’s a game changer to go from developing to running on a phone in less than a minute.
  3. Developing for the phone opens up a lot of possibilities for apps that I would never have considered before.

It was a productive weekend, and I’m looking forward to adding some more features to these apps soon!