tauri
Ship the same app to Windows, macOS and Linux as a small Tauri binary on the operating system's webview.
What it is
@kitr/tauri adds a Tauri platform: a small desktop app with Rust behind the window. kitr dev runs the window with hot reload, kitr build makes installers, and defineCommands types every Rust command from TypeScript.
The client code also runs in a plain browser. For most desktop apps we recommend desktop (Electron), which renders the same on every OS.
Install
kitr add tauri appFirst time? Run npm i -g @kitr/kitr once. Inside a project, the global kitr runs your project's own version.
Adds @kitr/tauri with the Tauri CLI, an app platform, the Rust project in platforms/app/src-tauri/ and app/commands.ts. Adds router, platform and storage first if missing. Needs a Rust toolchain. Every change.
Quick start
Run the platform. The first run compiles the Rust crate, which takes a few minutes:
kitr dev appFirst time? Run npm i -g @kitr/kitr once. Inside a project, the global kitr runs your project's own version.
The scaffold wrote one Rust command and its typed mirror:
// platforms/app/src-tauri/src/lib.rs
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {name}!")
}
// app/commands.ts
import { defineCommands } from '@kitr/tauri/client'
export type Commands = {
greet: (args: { name: string }) => string
}
export const commands = defineCommands<Commands>()
Call it from a component, guarded so the web build still runs:
// app/components/welcome.tsx
import { isTauri } from '@kitr/tauri/client'
import { useEffect, useState } from 'react'
import { commands } from '#app/commands'
export function Welcome() {
const [greeting, setGreeting] = useState('Welcome to Acme Orders')
useEffect(() => {
if (isTauri()) void commands.greet({ name: 'Ada' }).then(setGreeting)
}, [])
return <h1>{greeting}</h1>
}
In the Tauri window the heading reads Hello, Ada!, computed in Rust. In the browser it stays Welcome to Acme Orders. Next in the guide: Open your first window.
Built on
kitr adds the platform contract, the generated config and icons, typed commands and events, the query helpers and the drivers.
Problems it solves
- A second codebase for the desktop app. Open your first window.
- Untyped
invoke('command', args)strings. Add a Rust command. - Rust errors arriving as strings. Return an error from Rust.
- Command results with no caching. Read a command with a query.
- Permissions that block the window. Grant the window permissions.
- Installers and signing. Build installers.