# How to Build and Run the Routa Desktop App with Tauri

> Learn to build and run the Routa desktop app with Tauri. Follow simple steps to bundle your Next.js frontend into a native application for development or production.

- Repository: [Fengda Huang/routa](https://github.com/phodal/routa)
- Tags: how-to-guide
- Published: 2026-05-26

---

**Routa uses Tauri v2 to bundle its Next.js frontend into a native desktop application, requiring you to build the static frontend with `npm run build:static`, prepare the Tauri source tree using `scripts/prepare-frontend.mjs`, and execute `npm run dev` for development or `npm run build` for production binaries.**

The **phodal/routa** repository ships a complete desktop application stack that transforms the web-based Next.js UI into a native binary. To successfully build and run the Routa desktop app with Tauri, you must orchestrate three distinct layers: the statically exported frontend, a TypeScript bridge that forwards API calls, and the Rust backend that handles file system, database, and process operations. This guide walks through the exact commands, configuration files, and architectural patterns implemented in the source code.

## Prerequisites

Before attempting to build the desktop application, ensure your environment meets these requirements:

- **Node.js ≥ 18** and npm (`npm install -g npm`)
- **Rust toolchain** (`rustup default stable`)
- **Tauri CLI v2** (`cargo install tauri-cli@2`)
- Platform-specific system libraries for Tauri (refer to the official Tauri documentation for Linux, Windows, or macOS dependencies)

## Understanding the Desktop Architecture

The desktop workflow splits into three logical layers that communicate through well-defined boundaries:

- **Frontend Layer**: Next.js pages are statically exported into the `out/` directory, then copied into the Tauri source tree by the preparation script.
- **Tauri Bridge Layer**: Located at [`src/core/platform/tauri-bridge.ts`](https://github.com/phodal/routa/blob/main/src/core/platform/tauri-bridge.ts), this TypeScript façade forwards file-system, Git, database, and process calls to the native Rust side via Tauri plugins.
- **Rust Backend Layer**: The native implementation lives in the `crates/` workspace (defined in the root [`Cargo.toml`](https://github.com/phodal/routa/blob/main/Cargo.toml)) and includes the Axum server and SQLite database engine that Tauri links into the final binary.

The [`apps/desktop/src-tauri/tauri.conf.json`](https://github.com/phodal/routa/blob/main/apps/desktop/src-tauri/tauri.conf.json) file configures the build pipeline, specifying `frontendDist: "../../../out"` to locate the built UI, dev server ports, and enabled native plugins including SQL, shell, and dialog.

## Step-by-Step Build Instructions

### Clone and Install Dependencies

Start by cloning the monorepo and installing JavaScript dependencies:

```bash
git clone https://github.com/phodal/routa.git
cd routa
npm ci

```

This installs all Node.js dependencies required for the Next.js frontend and Tauri desktop wrapper.

### Build the Static Frontend

Generate the static export that Tauri will bundle:

```bash
npm run build:static

```

This command renders the Next.js application to the `out/` directory. The `scripts/prepare-frontend.mjs` script (automatically invoked during the Tauri build process) copies this `out/` folder into `apps/desktop/src-tauri/frontend/` and bundles the feature-tree generator to ensure release builds remain self-contained.

### Run in Development Mode

Launch the desktop app with hot-reload capabilities:

```bash
npm run dev

```

Defined in [`apps/desktop/package.json`](https://github.com/phodal/routa/blob/main/apps/desktop/package.json), this script executes `tauri dev`, which:
1. Runs the `beforeDevCommand` from [`tauri.conf.json`](https://github.com/phodal/routa/blob/main/tauri.conf.json) (`cd ../.. && npm run dev`) to start the Next.js dev server on `http://localhost:3000`
2. Opens a native window pointing at `http://localhost:3000/?runtime=tauri&backend=http://127.0.0.1:3210`
3. Proxies API calls to the Rust backend running on port 3210 (configured in [`src/client/config/backend.ts`](https://github.com/phodal/routa/blob/main/src/client/config/backend.ts))

### Create a Production Binary

Generate a signed installer or standalone executable:

```bash
npm run build

```

This command, defined in [`apps/desktop/package.json`](https://github.com/phodal/routa/blob/main/apps/desktop/package.json), executes `tauri build` which:
1. Runs the `beforeBuildCommand` (which triggers `prepare-frontend.mjs`)
2. Compiles the Rust backend using Cargo with release optimizations
3. Bundles the static UI and native binaries into platform-specific installers

After completion, find the output in `apps/desktop/src-tauri/target/release/bundle/`.

## Key Implementation Details

### The prepare-frontend.mjs Script

The `scripts/prepare-frontend.mjs` file handles the critical handoff between the Node.js build pipeline and the Rust/Cargo system. It ensures the `out/` directory exists and copies the statically generated assets into the Tauri source tree, making the frontend available for embedding in the native binary.

### The Tauri Bridge (tauri-bridge.ts)

The [`src/core/platform/tauri-bridge.ts`](https://github.com/phodal/routa/blob/main/src/core/platform/tauri-bridge.ts) file implements the **TauriPlatformBridge** class, which exposes native capabilities to the UI layer:

```typescript
import { TauriPlatformBridge } from '@/core/platform/tauri-bridge';

const bridge = new TauriPlatformBridge();
await bridge.initialize();
await bridge.fs.writeTextFile('config.json', JSON.stringify({ theme: 'dark' }));
const content = await bridge.fs.readTextFile('config.json');

```

This bridge forwards file-system operations, Git commands, database queries, and native dialogs to the corresponding Rust implementations via Tauri's IPC mechanism.

### Tauri Configuration (tauri.conf.json)

The [`apps/desktop/src-tauri/tauri.conf.json`](https://github.com/phodal/routa/blob/main/apps/desktop/src-tauri/tauri.conf.json) file controls the build process, specifying:
- `frontendDist`: Points to the `out/` directory containing the exported Next.js build
- `beforeDevCommand` and `beforeBuildCommand`: Hooks that ensure the frontend is prepared before Rust compilation begins
- Plugin activation: Enables the SQL, shell, and dialog plugins required by the bridge

## Verifying the Installation

The repository includes an end-to-end Playwright test that validates the complete desktop stack:

```bash
npx playwright test e2e/homepage-open-board-tauri.spec.ts

```

This test opens a board inside the Tauri window and confirms the UI loads correctly, verifying that the frontend, bridge, and Rust backend are communicating properly. The test file lives at [`e2e/homepage-open-board-tauri.spec.ts`](https://github.com/phodal/routa/blob/main/e2e/homepage-open-board-tauri.spec.ts) and serves as the definitive validation that you have successfully built the Routa desktop app with Tauri.

## Summary

- **Routa** bundles a Next.js frontend into a native desktop app using **Tauri v2**, with the build logic split across JavaScript preparation scripts and Rust compilation.
- Run **`npm run build:static`** to export the frontend, then **`npm run dev`** to launch a development window with hot-reload, or **`npm run build`** to create production installers.
- The architecture relies on **`scripts/prepare-frontend.mjs`** to stage assets, **[`src/core/platform/tauri-bridge.ts`](https://github.com/phodal/routa/blob/main/src/core/platform/tauri-bridge.ts)** to communicate between TypeScript and Rust, and **[`tauri.conf.json`](https://github.com/phodal/routa/blob/main/tauri.conf.json)** to configure the build pipeline.
- Production binaries are output to **`apps/desktop/src-tauri/target/release/bundle/`** after successful compilation.

## Frequently Asked Questions

### What Node.js and Rust versions are required to build Routa?

Routa requires **Node.js ≥ 18** and the **stable Rust toolchain** managed via `rustup`. You must also install the Tauri CLI version 2 using `cargo install tauri-cli@2` to ensure compatibility with the Tauri v2 configuration used in the repository.

### How does the TypeScript bridge communicate with the native backend?

The **`TauriPlatformBridge`** class in [`src/core/platform/tauri-bridge.ts`](https://github.com/phodal/routa/blob/main/src/core/platform/tauri-bridge.ts) forwards method calls to the Rust side through Tauri's IPC layer. When you call methods like `bridge.fs.readTextFile()`, the bridge invokes the corresponding Tauri command that executes native file-system operations in the Rust runtime compiled from the `crates/` workspace.

### Where are the production binaries located after building?

After running `npm run build`, platform-specific installers and executables are placed in **`apps/desktop/src-tauri/target/release/bundle/`**. This directory contains `.dmg` files for macOS, `.msi` or `.exe` for Windows, and `.AppImage` or `.deb` for Linux, depending on your host platform.

### Can I run the desktop app without building the static frontend first?

No, the static frontend build is mandatory. The [`tauri.conf.json`](https://github.com/phodal/routa/blob/main/tauri.conf.json) references `frontendDist: "../../../out"`, which expects the `out/` directory generated by `npm run build:static`. The `prepare-frontend.mjs` script automatically handles this during production builds, but for development, ensure you have run the static build at least once or the Tauri window will fail to locate the UI assets.