Finding official Tauri plugins
To find existing plugins, first check if they are listed in the Tauri Guides documentation under the Plugins menu—these are officially maintained by Tauri. If not found there, search crates.io using the pattern 'tauri-plugin-<plugin-name>'.
Manual plugin initialization in lib.rs
For community plugins found on crates.io, add the dependency with cargo add tauri-plugin-<name>, then initialize it in src-tauri/src/lib.rs by calling .plugin(tauri_plugin_<name>::init()) in the tauri::Builder::default() chain before .run(tauri::generate_context!()).
Plugin setup with pnpm tauri add command
Official plugins from the Tauri workspace can be added using pnpm tauri add <plugin-name>. For example, pnpm tauri add fs adds the file-system plugin to a project.
Frontend command invocation with camelCase parameters
When invoking commands from frontend JavaScript/TypeScript, parameter names must use camelCase. For example, a Rust parameter named user_input should be invoked as userInput in frontend code.
Plugin creation with Tauri CLI
To create a new Tauri plugin, use the Tauri CLI command: mkdir -p tauri-learning && cd tauri-learning && cargo tauri plugin new test && cd tauri-plugin-test && pnpm install && pnpm build && cargo build. Verify that tauri-cli version is 2.x by running cargo tauri info.
Adding commands to COMMANDS array in build.rs
In src/build.rs, add command names to the COMMANDS const array to trigger automatic permission generation. For example: const COMMANDS: &[&str] = &["ping", "write_custom_file"];
Plugin structure with example app
The default plugin structure created by Tauri CLI includes an examples/tauri-app folder containing a ready-to-use Tauri application for testing the plugin.
Exposing commands in TauriPlugin builder
Register commands in the invoke_handler using tauri::generate_handler! macro. Example: Builder::new("test").invoke_handler(tauri::generate_handler![commands::ping, commands::write_custom_file,])
@tauri-apps/api/tauri renamed to core
The @tauri-apps/api/tauri module was renamed to @tauri-apps/api/core. Update imports from import { invoke } from "@tauri-apps/api/tauri" to import { invoke } from "@tauri-apps/api/core".
Rust api module removed in v2
The tauri::api module was eliminated. Each API is now in a Tauri plugin: api::dialog → tauri-plugin-dialog, api::file → std::fs, api::http → tauri-plugin-http, api::path and PathResolved → tauri::Manager::path, api::process::Command and api::shell → tauri-plugin-shell, api::process::current_binary and restart → tauri::process, api::version → semver crate.
JavaScript API modules moved to plugins in v2
@tauri-apps/api only exports core, path, event, and window modules. All other modules moved to plugins: cli → @tauri-apps/plugin-cli, clipboard → @tauri-apps/plugin-clipboard-manager, dialog → @tauri-apps/plugin-dialog, fs → @tauri-apps/plugin-fs, global-shortcut → @tauri-apps/plugin-global-shortcut, http → @tauri-apps/plugin-http, os → @tauri-apps/plugin-os, notification → @tauri-apps/plugin-notification, process → @tauri-apps/plugin-process, shell → @tauri-apps/plugin-shell, updater → @tauri-apps/plugin-updater.
@tauri-apps/api/window renamed to webviewWindow
The WebviewWindow API now exports from @tauri-apps/api/webviewWindow instead of @tauri-apps/api/window.
HTTP plugin setup with Cargo.toml
To manually set up the HTTP plugin, run `cargo add tauri-plugin-http` in the `src-tauri` folder to add it to Cargo.toml dependencies.
HTTP plugin initialization in lib.rs
Initialize the HTTP plugin in `src-tauri/src/lib.rs` by adding `.plugin(tauri_plugin_http::init())` to the tauri::Builder chain in the run function.
HTTP plugin npm package installation
To use HTTP requests from JavaScript, install the npm package `@tauri-apps/plugin-http` using npm, yarn, pnpm, deno, or bun.
Persisted Scope automatic setup command
The Persisted Scope plugin can be automatically installed using the tauri add command. The commands are: npm run tauri add persisted-scope, yarn run tauri add persisted-scope, pnpm tauri add persisted-scope, deno task tauri add persisted-scope, bun tauri add persisted-scope, or cargo tauri add persisted-scope.
Persisted Scope manual setup in Cargo.toml
To manually set up the Persisted Scope plugin, run 'cargo add tauri-plugin-persisted-scope' in the src-tauri folder to add the dependency to Cargo.toml.
Persisted Scope initialization in lib.rs
To initialize the Persisted Scope plugin in Rust, add .plugin(tauri_plugin_persisted_scope::init()) to the tauri::Builder::default() chain in src-tauri/src/lib.rs.
Menu API changes in Tauri 2.0
Use 'tauri::menu::MenuBuilder' instead of 'tauri::Menu'. Use 'tauri::menu::PredefinedMenuItem' instead of 'tauri::MenuItem'. Use 'tauri::menu::MenuItemBuilder' instead of 'tauri::CustomMenuItem'. Use 'tauri::menu::SubmenuBuilder' instead of 'tauri::Submenu'. The Builder::menu method now takes a closure.
JavaScript API modules moved to plugins in Tauri 2.0
The @tauri-apps/api package no longer exports non-core modules. Only 'tauri', 'path', and 'event' are exported. All other APIs have moved to individual plugins: app, cli, clipboard, dialog, fs, global-shortcut, http, os, notification, process, shell, updater, and window each have corresponding @tauri-apps/plugin-* packages.
Version API removed in Tauri 2.0
The api::version module has been removed. Use the semver crate instead for version parsing and comparison.
Plugin API configuration in Tauri 2.0
Plugin::PluginApi now receives a plugin configuration as a second argument. Plugin::setup_with_config has been removed and replaced by the updated Plugin::PluginApi.
Core API modules moved to plugins in Tauri 2.0
In Tauri 2.0, the 'api' module has been removed. Each API module can now be found in individual Tauri plugins. Specifically: api::dialog moved to tauri-plugin-dialog, api::file removed (use std::fs), api::http moved to tauri-plugin-http, api::shell moved to tauri-plugin-shell, api::process moved to tauri-plugin-process, and other APIs moved to corresponding plugins.
App plugin setup in Tauri 2.0
Add 'tauri-plugin-app = "2"' to Cargo.toml. Register with plugin. In JavaScript: import { show, hide } from '@tauri-apps/plugin-app'; await hide(); await show();
Store plugin Rust API - app.store method
In Rust, create or load a Store using let store = app.store('store.json')?. This adds the Store to the app's resource table so subsequent store calls from both Rust and JavaScript reuse the same Store.
Store plugin purpose and use cases
The Store plugin provides persistent key-value storage. It allows applications to save and persist application state to a file, which can be saved and loaded as needed including during app restarts. The process is asynchronous and must be handled in code. The Store works in both WebView and Rust.
Store plugin automatic setup command
To automatically set up the Store plugin, use one of these commands in your project: npm run tauri add store, yarn run tauri add store, pnpm tauri add store, deno task tauri add store, bun tauri add store, or cargo tauri add store.
Store plugin manual setup in Cargo.toml
To manually set up the Store plugin, run 'cargo add tauri-plugin-store' in the src-tauri folder to add the dependency to Cargo.toml.
Store plugin initialization in Rust lib.rs
Initialize the Store plugin in src-tauri/src/lib.rs by adding .plugin(tauri_plugin_store::Builder::new().build()) to the tauri::Builder chain.
Store plugin JavaScript bindings installation
Install JavaScript bindings using: npm install @tauri-apps/plugin-store, yarn add @tauri-apps/plugin-store, pnpm add @tauri-apps/plugin-store, deno add npm:@tauri-apps/plugin-store, or bun add @tauri-apps/plugin-store.
Store plugin JavaScript API - load function
Load or create a Store in JavaScript using: const store = await load('store.json', { autoSave: false }). If a Store with the same path already exists, option settings are ignored.
Store plugin JavaScript API - set and get
In JavaScript, set a key-value pair using await store.set('some-key', { value: 5 }). Retrieve a value using const val = await store.get<{ value: number }>('some-key').
Store plugin JavaScript API - save method
Save Store changes manually by calling await store.save(). If autoSave is not used, changes are saved on normal application exit. If autoSave is set to a number or left empty, changes are automatically saved to disk after a debounce delay (default 100 milliseconds).
Store plugin import statement
Import the Store load function using: import { load } from '@tauri-apps/plugin-store'. Alternatively, if using 'withGlobalTauri': true, use: const { load } = window.__TAURI__.store.
Store plugin Rust API - set and get
In Rust, set a value using store.set('some-key', json!({ 'value': 5 })). Get a value using let value = store.get('some-key').expect('Failed to get value from store'). Values must be serde_json::Value instances for JavaScript compatibility.
Store plugin Rust API - close_resource method
Remove a Store from the resource table in Rust using store.close_resource().
LazyStore high-level JavaScript API
The LazyStore API is a high-level JavaScript API that loads the Store only on first access. Create a LazyStore using: const store = new LazyStore('settings.json'). Import it with: import { LazyStore } from '@tauri-apps/plugin-store'.
Store plugin migration from v1/v2 beta - JavaScript
To migrate from Store v1 or v2 beta in JavaScript, change the import from 'import { Store }' to 'import { LazyStore }'.
Store plugin migration from v1/v2 beta - Rust
To migrate from Store v1 or v2 beta in Rust, replace the with_store function pattern with: let store = app.store(path)?; store.set('some-key'.to_string(), json!({ 'value': 5 }));
Http plugin scopes filter allowed URLs
The HTTP plugin uses scopes to filter which URLs are permitted to be accessed by the application.
Add menu items to tray in Rust
In Rust, create menu items with MenuItem::with_id(app, id, text, enabled, accelerator), create a Menu with Menu::with_items(app, &[items]), then pass it to TrayIconBuilder::new().menu(&menu).
Handle tray menu clicks in JavaScript
In JavaScript, add an action handler directly to menu items: { id: 'quit', text: 'Quit', action: (itemId) => { /* handle click */ } }. Multiple items can share the same handler function or have individual handlers.
Handle tray menu clicks in Rust
In Rust, use TrayIconBuilder::on_menu_event(|app, event| match event.id.as_ref() { "quit" => { /* handle */ } _ => {} }) to respond to menu item clicks.
Tray icon mouse events
The tray icon emits five types of mouse events: Click (with button and buttonState information), DoubleClick, Enter (when cursor enters icon area), Move (when cursor moves within icon area), and Leave (when cursor leaves icon area). Click and Enter events include rect position information.
Handle tray events in JavaScript
In JavaScript, pass an action handler to TrayIcon.new(options) that receives event objects with type property ('Click', 'DoubleClick', 'Enter', 'Move', or 'Leave'), button, buttonState, and rect.position information.
System tray feature requires tray-icon in Cargo.toml
To use the system tray feature in Tauri, update src-tauri/Cargo.toml to include the tray-icon feature: tauri = { version = "2.0.0", features = [ "tray-icon" ] }
TrayIcon.new creates tray icon in JavaScript
In JavaScript, create a new tray icon using the static function TrayIcon.new(options) from @tauri-apps/api/tray. The options object can include tray menu, title, tooltip, and event handlers.
TrayIconBuilder creates tray icon in Rust
In Rust, create a tray icon using TrayIconBuilder::new().build(app) in the setup closure of tauri::Builder::default(). Detailed customization options are available through TrayIconBuilder methods.
Set tray icon from default window icon
In JavaScript, use TrayIcon.new({ icon: await defaultWindowIcon() }). In Rust, use TrayIconBuilder::new().icon(app.default_window_icon().unwrap().clone()).build(app).
Tray menu displays on both left and right click by default
By default, the tray menu appears on both left click and right click. To disable the menu on left click, set menuOnLeftClick to false in JavaScript options or call menu_on_left_click(false) on TrayIconBuilder in Rust.
Handle tray events in Rust
In Rust, use TrayIconBuilder::on_tray_icon_event(|tray, event| match event { TrayIconEvent::Click { button: MouseButton::Left, button_state: MouseButtonState::Up, .. } => { /* handle */ } _ => {} }) to respond to tray events.
Add menu items to tray in JavaScript
In JavaScript, create a menu with Menu.new({ items: [{ id: 'quit', text: 'Quit' }] }) and pass it to TrayIcon.new({ menu, menuOnLeftClick: true }).
Tauri's extensibility design goal
Tauri is designed with extensibility as an objective. The platform aims to be extended through plugins and community contributions.
Tauri plugin and formula resources
Tauri provides documentation organized into two main sections: built-in Characteristics (features and functionalities incorporated into Tauri) and Community Resources (additional plugins and formulas created by the Tauri community).