understanding-tauri-architecture
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTauri Architecture
Tauri 架构
Tauri is a polyglot toolkit for building desktop applications that combines a Rust backend with HTML/CSS/JavaScript rendered in a native webview. This document covers the fundamental architecture concepts.
Tauri是一个多语言工具包,用于构建桌面应用,它将Rust后端与在原生Webview中渲染的HTML/CSS/JavaScript相结合。本文档涵盖了其核心架构概念。
Architecture Overview
架构概览
+------------------------------------------------------------------+
| TAURI APPLICATION |
+------------------------------------------------------------------+
| |
| +---------------------------+ +---------------------------+ |
| | FRONTEND (Shell) | | BACKEND (Core) | |
| |---------------------------| |---------------------------| |
| | | | | |
| | HTML / CSS / JavaScript | | Rust Code | |
| | (or any web framework) | | (tauri crate + app) | |
| | | | | |
| | - React, Vue, Svelte, | | - System access | |
| | Solid, etc. | | - File operations | |
| | - Standard web APIs | | - Native features | |
| | - Tauri JS API | | - Plugin system | |
| | | | | |
| +-------------+-------------+ +-------------+-------------+ |
| | | |
| | IPC (Message Passing) | |
| +<------------------------------->+ |
| | Commands & Events | |
| |
| +------------------------------------------------------------+ |
| | WEBVIEW (TAO + WRY) | |
| |------------------------------------------------------------| |
| | - Platform-native webview (not bundled) | |
| | - Windows: WebView2 (Edge/Chromium) | |
| | - macOS: WKWebView (Safari/WebKit) | |
| | - Linux: WebKitGTK | |
| +------------------------------------------------------------+ |
| |
+------------------------------------------------------------------+
|
v
+------------------------------------------------------------------+
| OPERATING SYSTEM |
| - Windows, macOS, Linux, iOS, Android |
+------------------------------------------------------------------++------------------------------------------------------------------+
| TAURI APPLICATION |
+------------------------------------------------------------------+
| |
| +---------------------------+ +---------------------------+ |
| | FRONTEND (Shell) | | BACKEND (Core) | |
| |---------------------------| |---------------------------| |
| | | | | |
| | HTML / CSS / JavaScript | | Rust Code | |
| | (or any web framework) | | (tauri crate + app) | |
| | | | | |
| | - React, Vue, Svelte, | | - System access | |
| | Solid, etc. | | - File operations | |
| | - Standard web APIs | | - Native features | |
| | - Tauri JS API | | - Plugin system | |
| | | | | |
| +-------------+-------------+ +-------------+-------------+ |
| | | |
| | IPC (Message Passing) | |
| +<------------------------------->+ |
| | Commands & Events | |
| |
| +------------------------------------------------------------+ |
| | WEBVIEW (TAO + WRY) | |
| |------------------------------------------------------------| |
| | - Platform-native webview (not bundled) | |
| | - Windows: WebView2 (Edge/Chromium) | |
| | - macOS: WKWebView (Safari/WebKit) | |
| | - Linux: WebKitGTK | |
| +------------------------------------------------------------+ |
| |
+------------------------------------------------------------------+
|
v
+------------------------------------------------------------------+
| OPERATING SYSTEM |
| - Windows, macOS, Linux, iOS, Android |
+------------------------------------------------------------------+Core vs Shell Design
Core与Shell设计
Tauri follows a Core-Shell architecture where the application is split into two distinct layers:
Tauri遵循Core-Shell架构,应用被拆分为两个不同的层:
The Core (Rust Backend)
Core(Rust后端)
The Core is the Rust-based backend that handles all system-level operations:
- System access: File system, network, processes
- Native features: Notifications, dialogs, clipboard
- Security enforcement: Permission validation, capability checking
- Plugin management: Extending functionality through plugins
- App lifecycle: Window management, updates, configuration
The Core NEVER exposes direct system access to the frontend. All interactions go through validated IPC channels.
Core是基于Rust的后端,负责处理所有系统级操作:
- 系统访问:文件系统、网络、进程
- 原生功能:通知、对话框、剪贴板
- 安全执行:权限验证、能力检查
- 插件管理:通过插件扩展功能
- 应用生命周期:窗口管理、更新、配置
Core绝不会直接向前端暴露系统访问权限,所有交互都通过经过验证的IPC通道进行。
The Shell (Frontend)
Shell(前端)
The Shell is the user interface layer rendered in a webview:
- Web technologies: HTML, CSS, JavaScript/TypeScript
- Framework agnostic: Works with React, Vue, Svelte, Solid, or vanilla JS
- Sandboxed execution: Runs in the webview's security sandbox
- Tauri API access: Calls backend through
@tauri-apps/api
Shell是在Webview中渲染的用户界面层:
- Web技术:HTML、CSS、JavaScript/TypeScript
- 框架无关:可与React、Vue、Svelte、Solid或原生JS配合使用
- 沙箱执行:在Webview的安全沙箱中运行
- Tauri API访问:通过调用后端
@tauri-apps/api
Key Ecosystem Components
关键生态系统组件
tauri Crate
tauri Crate
The central orchestrator that:
- Reads at compile time
tauri.conf.json - Manages script injection into the webview
- Hosts the system interaction API
- Handles application updates
- Integrates runtimes, macros, and utilities
核心协调器,负责:
- 编译时读取
tauri.conf.json - 管理向Webview注入脚本
- 托管系统交互API
- 处理应用更新
- 集成运行时、宏和工具
tauri-runtime
tauri-runtime
The glue layer between Tauri and lower-level webview libraries. Abstracts platform-specific webview interactions so the rest of Tauri can remain platform-agnostic.
Tauri与底层Webview库之间的粘合层。抽象了平台特定的Webview交互,使Tauri的其余部分保持平台无关。
tauri-macros and tauri-codegen
tauri-macros 和 tauri-codegen
Generate compile-time code for:
- Command handlers ()
#[tauri::command] - Context and configuration parsing
- Asset embedding and compression
生成编译时代码,用于:
- 命令处理器()
#[tauri::command] - 上下文和配置解析
- 资源嵌入和压缩
TAO (Window Management)
TAO(窗口管理)
Cross-platform window creation library (forked from Winit):
- Creates and manages application windows
- Handles menu bars and system trays
- Supports Windows, macOS, Linux, iOS, Android
跨平台窗口创建库(从Winit分叉):
- 创建和管理应用窗口
- 处理菜单栏和系统托盘
- 支持Windows、macOS、Linux、iOS、Android
WRY (WebView Rendering)
WRY(WebView渲染)
Cross-platform WebView rendering library:
- Abstracts webview implementations per platform
- Handles webview-to-native communication
- Manages JavaScript evaluation and event bridging
跨平台WebView渲染库:
- 抽象各平台的Webview实现
- 处理Webview到原生的通信
- 管理JavaScript执行和事件桥接
Webview Integration
Webview集成
Tauri uses the operating system's native webview rather than bundling a browser engine:
+-------------------+---------------------------+
| Platform | WebView Engine |
+-------------------+---------------------------+
| Windows | WebView2 (Edge/Chromium) |
| macOS | WKWebView (Safari/WebKit) |
| Linux | WebKitGTK |
| iOS | WKWebView |
| Android | Android WebView |
+-------------------+---------------------------+Tauri使用操作系统的原生Webview,而非捆绑浏览器引擎:
+-------------------+---------------------------+
| 平台 | WebView引擎 |
+-------------------+---------------------------+
| Windows | WebView2 (Edge/Chromium) |
| macOS | WKWebView (Safari/WebKit) |
| Linux | WebKitGTK |
| iOS | WKWebView |
| Android | Android WebView |
+-------------------+---------------------------+Benefits of Native WebViews
原生WebView的优势
- Smaller binary size: No bundled browser engine (~600KB vs ~150MB)
- Security: OS vendors patch webview vulnerabilities faster than app developers can rebuild
- Performance: Native integration with the operating system
- Consistency: Users see familiar rendering behavior
- 更小的二进制体积:无需捆绑浏览器引擎(约600KB vs 约150MB)
- 安全性:操作系统供应商修复Webview漏洞的速度快于应用开发者重新构建的速度
- 性能:与操作系统原生集成
- 一致性:用户看到熟悉的渲染行为
Considerations
注意事项
- Slight rendering differences between platforms
- Feature availability depends on OS webview version
- Testing should cover all target platforms
- 不同平台之间存在轻微的渲染差异
- 功能可用性取决于OS Webview版本
- 测试应覆盖所有目标平台
Inter-Process Communication (IPC)
进程间通信(IPC)
Tauri implements Asynchronous Message Passing for communication between frontend and backend. This is safer than shared memory because the Core can reject malicious requests.
Tauri实现了异步消息传递,用于前端与后端之间的通信。这比共享内存更安全,因为Core可以拒绝恶意请求。
IPC Flow Diagram
IPC流程图
+------------------+ +------------------+
| Frontend | | Rust Backend |
| (JavaScript) | | (Core) |
+--------+---------+ +--------+---------+
| |
| 1. invoke('command', {args}) |
+---------------------------------------->|
| |
| [Request serialized as JSON-RPC] |
| |
| 2. Validate request |
| 3. Check permissions |
| 4. Execute command |
| |
| 5. Return Result<T, E> |
|<----------------------------------------+
| |
| [Response serialized as JSON] |
| |+------------------+ +------------------+
| Frontend | | Rust Backend |
| (JavaScript) | | (Core) |
+--------+---------+ +--------+---------+
| |
| 1. invoke('command', {args}) |
+---------------------------------------->|
| |
| [Request serialized as JSON-RPC] |
| |
| 2. Validate request |
| 3. Check permissions |
| 4. Execute command |
| |
| 5. Return Result<T, E> |
|<----------------------------------------+
| |
| [Response serialized as JSON] |
| |Two IPC Primitives
两种IPC原语
Commands (Request-Response)
命令(请求-响应)
Type-safe, frontend-to-backend function calls:
rust
// Rust backend
#[tauri::command]
fn greet(name: String) -> String {
format!("Hello, {}!", name)
}
// Register in builder
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![greet])javascript
// JavaScript frontend
import { invoke } from '@tauri-apps/api/core';
const greeting = await invoke('greet', { name: 'World' });
console.log(greeting); // "Hello, World!"Key characteristics:
- Built on JSON-RPC protocol
- All arguments must be JSON-serializable
- Returns a Promise that resolves with the result
- Supports async Rust functions
- Can access app state, window handle, etc.
类型安全的前端到后端函数调用:
rust
// Rust backend
#[tauri::command]
fn greet(name: String) -> String {
format!("Hello, {}!", name)
}
// Register in builder
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![greet])javascript
// JavaScript frontend
import { invoke } from '@tauri-apps/api/core';
const greeting = await invoke('greet', { name: 'World' });
console.log(greeting); // "Hello, World!"关键特性:
- 基于JSON-RPC协议
- 所有参数必须可JSON序列化
- 返回一个Promise,解析后得到结果
- 支持异步Rust函数
- 可访问应用状态、窗口句柄等
Events (Fire-and-Forget)
事件(即发即弃)
Bidirectional, asynchronous notifications:
javascript
// Frontend: emit event
import { emit } from '@tauri-apps/api/event';
emit('user-action', { action: 'clicked' });
// Frontend: listen for events
import { listen } from '@tauri-apps/api/event';
const unlisten = await listen('download-progress', (event) => {
console.log(event.payload);
});rust
// Backend: listen for events
use tauri::Listener;
app.listen("user-action", |event| {
println!("User action: {}", event.payload());
});
// Backend: emit events
app.emit("download-progress", 50)?;Key characteristics:
- No return value (one-way)
- Both frontend and backend can emit/listen
- Best for lifecycle events and state changes
- Not type-checked at compile time
双向异步通知:
javascript
// Frontend: emit event
import { emit } from '@tauri-apps/api/event';
emit('user-action', { action: 'clicked' });
// Frontend: listen for events
import { listen } from '@tauri-apps/api/event';
const unlisten = await listen('download-progress', (event) => {
console.log(event.payload);
});rust
// Backend: listen for events
use tauri::Listener;
app.listen("user-action", |event| {
println!("User action: {}", event.payload());
});
// Backend: emit events
app.emit("download-progress", 50)?;关键特性:
- 无返回值(单向)
- 前端和后端都可以发送/监听
- 最适合生命周期事件和状态变化
- 编译时不进行类型检查
Security Model Overview
安全模型概览
Tauri implements multiple layers of security to protect both the application and the user's system.
Tauri实现了多层安全机制,以保护应用和用户系统。
Trust Boundary Model
信任边界模型
+------------------------------------------------------------------+
| UNTRUSTED ZONE |
| +------------------------------------------------------------+ |
| | WebView Frontend | |
| | - JavaScript code (potentially from remote sources) | |
| | - User input | |
| | - Third-party libraries | |
| +------------------------------------------------------------+ |
+------------------------------------------------------------------+
|
[TRUST BOUNDARY]
[IPC Layer validates all requests]
|
+------------------------------------------------------------------+
| TRUSTED ZONE |
| +------------------------------------------------------------+ |
| | Rust Backend | |
| | - Your Rust code | |
| | - Tauri core | |
| | - System access (gated by permissions) | |
| +------------------------------------------------------------+ |
+------------------------------------------------------------------++------------------------------------------------------------------+
| 不可信区域 |
| +------------------------------------------------------------+ |
| | WebView前端 | |
| | - JavaScript代码(可能来自远程源) | |
| | - 用户输入 | |
| | - 第三方库 | |
| +------------------------------------------------------------+ |
+------------------------------------------------------------------+
|
[信任边界]
[IPC层验证所有请求]
|
+------------------------------------------------------------------+
| 可信区域 |
| +------------------------------------------------------------+ |
| | Rust后端 | |
| | - 你的Rust代码 | |
| | - Tauri核心 | |
| | - 系统访问(受权限限制) | |
| +------------------------------------------------------------+ |
+------------------------------------------------------------------+Security Layers
安全层
- WebView Sandboxing: Frontend code runs in the webview's security sandbox
- IPC Validation: All messages crossing the trust boundary are validated
- Capabilities: Define which permissions each window can access
- Permissions: Fine-grained control over what operations are allowed
- Scopes: Restrict command behavior (e.g., limit file access to specific directories)
- CSP: Content Security Policy restricts what frontend code can do
- WebView沙箱:前端代码在Webview的安全沙箱中运行
- IPC验证:所有跨越信任边界的消息都会被验证
- 能力(Capabilities):定义每个窗口可以访问的权限
- 权限:对允许的操作进行细粒度控制
- 作用域:限制命令行为(例如,将文件访问限制到特定目录)
- CSP:内容安全策略限制前端代码的行为
Capabilities System
能力系统
Capabilities control which permissions are granted to specific windows:
json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-window-capability",
"description": "Permissions for the main application window",
"windows": ["main"],
"permissions": [
"core:path:default",
"core:window:allow-set-title",
"fs:read-files",
"fs:scope-app-data"
]
}Capabilities are defined in as JSON or TOML files.
src-tauri/capabilities/能力控制特定窗口被授予的权限:
json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-window-capability",
"description": "主应用窗口的权限",
"windows": ["main"],
"permissions": [
"core:path:default",
"core:window:allow-set-title",
"fs:read-files",
"fs:scope-app-data"
]
}能力在目录中定义为JSON或TOML文件。
src-tauri/capabilities/Permission Structure
权限结构
Capability
|
+-- windows: ["main", "settings"] // Which windows
|
+-- permissions: // What's allowed
|
+-- "plugin:action" // Allow specific action
+-- "plugin:scope-xxx" // Scope restrictionsCapability
|
+-- windows: ["main", "settings"] // 适用的窗口
|
+-- permissions: // 允许的操作
|
+-- "plugin:action" // 允许特定操作
+-- "plugin:scope-xxx" // 作用域限制Default Security Posture
默认安全策略
- Deny by default: Commands must be explicitly permitted
- No remote access: Only bundled code can access Tauri APIs by default
- Window isolation: Each window has its own capability set
- Compile-time checks: Many security configurations are validated at build time
- 默认拒绝:必须显式允许命令
- 无远程访问:默认只有捆绑代码可以访问Tauri API
- 窗口隔离:每个窗口有自己的能力集
- 编译时检查:许多安全配置在构建时会被验证
Rust Backend Structure
Rust后端结构
A typical Tauri backend follows this structure:
src-tauri/
+-- Cargo.toml # Rust dependencies
+-- tauri.conf.json # Tauri configuration
+-- capabilities/ # Permission definitions
| +-- main.json
+-- src/
+-- main.rs # Entry point (desktop)
+-- lib.rs # Core app logic
+-- commands/ # Command modules
| +-- mod.rs
| +-- file_ops.rs
+-- state.rs # App state management典型的Tauri后端遵循以下结构:
src-tauri/
+-- Cargo.toml # Rust依赖
+-- tauri.conf.json # Tauri配置
+-- capabilities/ # 权限定义
| +-- main.json
+-- src/
+-- main.rs # 入口点(桌面)
+-- lib.rs # 核心应用逻辑
+-- commands/ # 命令模块
| +-- mod.rs
| +-- file_ops.rs
+-- state.rs # 应用状态管理Entry Point Pattern
入口点模式
rust
// src-tauri/src/lib.rs
mod commands;
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_shell::init())
.invoke_handler(tauri::generate_handler![
commands::greet,
commands::read_file,
])
.manage(AppState::default())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}rust
// src-tauri/src/lib.rs
mod commands;
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_shell::init())
.invoke_handler(tauri::generate_handler![
commands::greet,
commands::read_file,
])
.manage(AppState::default())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}Command Patterns
命令模式
rust
// Basic command
#[tauri::command]
fn simple_command() -> String {
"Hello".into()
}
// With arguments (camelCase from JS, snake_case in Rust)
#[tauri::command]
fn with_args(user_name: String, age: u32) -> String {
format!("{} is {} years old", user_name, age)
}
// With error handling
#[tauri::command]
fn fallible() -> Result<String, String> {
Ok("Success".into())
}
// Async command
#[tauri::command]
async fn async_command() -> Result<String, String> {
tokio::time::sleep(Duration::from_secs(1)).await;
Ok("Done".into())
}
// Accessing app state
#[tauri::command]
fn with_state(state: tauri::State<'_, AppState>) -> String {
state.get_value()
}
// Accessing window
#[tauri::command]
fn with_window(window: tauri::WebviewWindow) -> String {
window.label().to_string()
}rust
// Basic command
#[tauri::command]
fn simple_command() -> String {
"Hello".into()
}
// With arguments (camelCase from JS, snake_case in Rust)
#[tauri::command]
fn with_args(user_name: String, age: u32) -> String {
format!("{} is {} years old", user_name, age)
}
// With error handling
#[tauri::command]
fn fallible() -> Result<String, String> {
Ok("Success".into())
}
// Async command
#[tauri::command]
async fn async_command() -> Result<String, String> {
tokio::time::sleep(Duration::from_secs(1)).await;
Ok("Done".into())
}
// Accessing app state
#[tauri::command]
fn with_state(state: tauri::State<'_, AppState>) -> String {
state.get_value()
}
// Accessing window
#[tauri::command]
fn with_window(window: tauri::WebviewWindow) -> String {
window.label().to_string()
}No Runtime Bundled
无捆绑运行时
Tauri does NOT ship a runtime. The final binary:
- Compiles Rust code directly into native machine code
- Embeds frontend assets in the binary
- Uses the system's native webview
- Results in small, fast executables
This makes reverse engineering Tauri apps non-trivial compared to Electron apps with bundled JavaScript.
Tauri不附带运行时。最终的二进制文件:
- 将Rust代码直接编译为原生机器码
- 将前端资源嵌入到二进制文件中
- 使用系统的原生Webview
- 生成体积小、速度快的可执行文件
这使得逆向工程Tauri应用比捆绑JavaScript的Electron应用更困难。
Summary
总结
| Component | Role |
|---|---|
| Core (Rust) | System access, security, business logic |
| Shell (Frontend) | UI rendering, user interaction |
| WebView (TAO+WRY) | Platform-native rendering bridge |
| IPC (Commands/Events) | Safe message passing between layers |
| Capabilities | Permission control per window |
The architecture prioritizes:
- Security: Multiple layers of protection, trust boundaries
- Performance: Native code, no bundled runtime
- Size: Minimal binary footprint
- Flexibility: Any frontend framework, powerful Rust backend
| 组件 | 角色 |
|---|---|
| Core (Rust) | 系统访问、安全、业务逻辑 |
| Shell (Frontend) | UI渲染、用户交互 |
| WebView (TAO+WRY) | 平台原生渲染桥接 |
| IPC (Commands/Events) | 层间安全消息传递 |
| Capabilities | 按窗口控制权限 |
该架构优先考虑:
- 安全性:多层保护、信任边界
- 性能:原生代码、无捆绑运行时
- 体积:最小二进制占用
- 灵活性:支持任意前端框架、强大的Rust后端