tauri-apps/tauri
Plugin system
Plugins extend a Tauri app with reusable Rust + JS + ACL bundles. Almost every "feature" in the Tauri ecosystem (filesystem, http, dialog, store, sql, updater, …) ships as a plugin in the sibling tauri-apps/plugins-workspace repo. This page documents the plugin runtime that lives in this repo and the build-time helpers that make plugins consumable.
What a plugin is
A plugin is a Rust crate that returns a tauri::plugin::TauriPlugin<R> from an init() function:
pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("fs")
.invoke_handler(tauri::generate_handler![read_file, write_file])
.setup(|app, _api| { … Ok(()) })
.on_event(|app, event| { … })
.build()
}Optionally it ships:
- A
permissions/directory of TOML permission files. - A
default.tomlpermission set. - A JS package that calls into the plugin's commands via
invoke('plugin:<name>|<cmd>', …). - Mobile-specific code (
android/Kotlin module,ios/Swift package) wired through the mobile bridge.
Runtime model
graph TD
Init["plugin::init() -> TauriPlugin"] --> AddedTo["tauri::Builder::plugin(...)"]
AddedTo --> Store["AppManager.plugin_store"]
Store -->|"on_event"| Lifecycle["RunEvent dispatched here"]
Store -->|"invoke_handler"| IPC["IPC dispatch"]
Store -->|"navigation"| Webviews["Webviews"]The plugin store (crates/tauri/src/plugin.rs, ~34 KB) holds every registered plugin. It exposes hooks that the rest of the runtime calls:
initialize(&self, app, config)— once, after the app is built and before the run loop starts.created(&self, window)/webview_created(&self, webview)— per window/webview created.on_navigation(&self, webview, url)— gate or react to navigation.on_page_load(&self, webview, payload)— fired when the webview reports a load.on_event(&self, app, event)— forRunEvent(Ready, ExitRequested, …).on_drop(&self)— graceful shutdown.extend_api(&mut self, invoke)— additional command dispatch beyond the plugin'sinvoke_handler.
tauri::plugin::Builder is the canonical fluent builder for these hooks.
ACL integration
When a plugin ships permissions/, its build script calls tauri_plugin::Builder (see tauri-plugin). That generates a manifest in OUT_DIR describing every permission the plugin offers. Downstream apps' tauri-build reads those manifests during ACL resolution; nothing else is needed.
The runtime tags every IPC message from a plugin's commands with plugin:<name>|<cmd> so RuntimeAuthority can match it against the right permission. See systems/acl-and-capabilities.
Mobile
Plugins that need native mobile code use the macros and helpers in crates/tauri/src/plugin/mobile.rs:
- Rust → JNI/Swift: the plugin's
Builderregisters an Android<plugin_class>and an iOS<plugin_swift_module>. - The bridge (
crates/tauri/mobile/) routes plugin commands either to native Rust or native Kotlin/Swift depending on what the plugin registered.
See systems/mobile for the bridge details.
Authorship workflow
cargo new --lib tauri-plugin-foo.- Add
tauri-plugin = { features = ["build"] }as a build-dep,tauri = ...andtauri-plugin = { features = ["runtime"] }as deps. build.rscallstauri_plugin::Builder::new(&[...permission ids...]).build();.- Implement the
Builderreturninginit()insrc/lib.rs. - Add permissions under
permissions/and document them. - Optionally add a JS wrapper package that mirrors the public API.
The Tauri CLI scaffolds all of this with tauri plugin new <name> (crates/tauri-cli/src/plugin/).
Files at a glance
| File | Role |
|---|---|
crates/tauri/src/plugin.rs |
TauriPlugin, Plugin trait, Builder |
crates/tauri/src/plugin/mobile.rs |
Mobile bridge runtime helpers |
crates/tauri-plugin/src/build.rs |
Build-time helper (validates permissions, emits manifest) |
crates/tauri-plugin/src/runtime.rs |
Runtime convenience re-exports |
crates/tauri-cli/src/plugin/ |
tauri plugin new/init/android/ios |
Cross-references
- Build-time helper: crates/tauri-plugin.
- ACL: systems/acl-and-capabilities.
- Mobile bridge: systems/mobile.
- Reusable command pattern: systems/ipc-and-commands.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.