Filesystem plugin write example
Example TypeScript code to write to a text file using the fs plugin: import { writeTextFile, BaseDirectory } from '@tauri-apps/plugin-fs'; async function write(message: string) { await writeTextFile('test.txt', message, { baseDir: BaseDirectory.Home }); }
Install filesystem plugin with automated setup
For official Tauri workspace plugins, use the command: pnpm tauri add fs. This automatically adds the plugin as a dependency and initializes it.
Install filesystem plugin manually
To manually install the filesystem plugin from crates.io: run 'cargo add tauri-plugin-fs', then modify src-tauri/src/lib.rs to initialize the plugin by adding .plugin(tauri_plugin_fs::init()) to the tauri::Builder::default() chain.
Add commands to plugin invoke handler
In src/lib.rs, add commands to the invoke_handler using `tauri::generate_handler![commands::ping, commands::write_custom_file]` to expose them to the frontend and allow IPC requests to reach the command implementations.
Tauri CLI command to create new plugin
Run `cargo tauri plugin new test` to scaffold a new Tauri plugin source code structure with the CLI.
Plugin command implementation example
Example plugin command that writes user input to a file:
```rust
#[command]
pub(crate) async fn write_custom_file<R: Runtime>(
user_input: String,
app: AppHandle<R>,
) -> Result<String> {
std::fs::write(app.path().temp_dir().unwrap(), user_input)?;
Ok("success".to_string())
}
```
This command takes a string from the frontend, writes it to the system temp directory, and returns a success message.
Plugin example application location
When you create a Tauri plugin using `cargo tauri plugin new`, it includes a ready-to-use example Tauri application in the `examples/tauri-app` folder for testing the plugin.
Plugin frontend API wrapper example
Example TypeScript wrapper for exposing a plugin command to frontend code:
```typescript
import { invoke } from '@tauri-apps/api/core'
export async function writeCustomFile(user_input: string): Promise<string> {
return await invoke('plugin:test|write_custom_file', {userInput: user_input});
}
```
The invoke signature is `plugin:<plugin_name>|<command_name>` with parameters in camelCase.
Listen to tray events in JavaScript
In JavaScript, listen to tray events by passing an 'action' function to TrayIcon.new(). The event object has a 'type' field (Click, DoubleClick, Enter, Move, Leave), and Click/DoubleClick events include 'button' and 'buttonState' properties, while positional events include 'rect.position.x' and 'rect.position.y'.
Tray icon mouse events unsupported on Linux
On Linux, tray icon mouse events are not emitted even though the icon is shown and will still show a context menu on right click.
Create tray icon in Rust
In Rust, create a tray icon using TrayIconBuilder::new().build(app) in the setup closure of tauri::Builder::default().
Listen to tray events in Rust
In Rust, listen to tray events using TrayIconBuilder::on_tray_icon_event(|tray, event| { ... }). The event is a TrayIconEvent enum with variants like Click that include button and button_state fields. Access the app handle via tray.app_handle().
Use application icon as tray icon in JavaScript
To use the application icon as the tray icon in JavaScript, import defaultWindowIcon from '@tauri-apps/api/app' and pass it to TrayIcon.new({ icon: await defaultWindowIcon() }).
Create tray icon in JavaScript
In JavaScript, create a tray icon using TrayIcon.new(options) function from '@tauri-apps/api/tray'. Options can include tray menu, title, tooltip, and event handler.
Add menu to tray icon in Rust
To add a menu to a tray icon in Rust, create a Menu using Menu::with_items(app, &[items]) and pass it to TrayIconBuilder::new().menu(&menu).
Tray menu displays on both left and right clicks by default
By default, the menu attached to a tray icon is displayed on both left and right clicks. To prevent the menu from popping up on left click, call show_menu_on_left_click(false) in Rust or set menuOnLeftClick to false in JavaScript.
System tray feature in Cargo.toml
To enable system tray functionality in Tauri, add the 'tray-icon' feature to the tauri dependency in src-tauri/Cargo.toml: tauri = { version = "2.0.0", features = [ "tray-icon" ] }
Add menu to tray icon in JavaScript
To add a menu to a tray icon in JavaScript, create a Menu using Menu.new({ items: [...] }) and pass it to TrayIcon.new({ menu, menuOnLeftClick: true/false }).
Tray icon mouse events
Tray icons emit the following mouse events: Click (triggered on single left, right, or middle click with button state information), DoubleClick (triggered on double click), Enter (triggered when cursor enters tray icon area), Move (triggered when cursor moves around tray icon area), and Leave (triggered when cursor leaves tray icon area).
Use application icon as tray icon in Rust
To use the application icon as the tray icon in Rust, call TrayIconBuilder::new().icon(app.default_window_icon().unwrap().clone()).build(app).
Listen to tray menu click events in Rust
In Rust, attach a tray menu click event listener using TrayIconBuilder::on_menu_event(|app, event| { ... }) which receives app handle and event with an id field.
Listen to tray menu click events in JavaScript
In JavaScript, attach a menu click event listener by passing an 'action' function to a menu item definition. The action function receives the itemId as a parameter.
Shell plugin Rust command event example
In Tauri 2, when spawning shell commands with app.shell().command().spawn(), receive events including CommandEvent::Stdout. Use child.write() to send input to the process.
Dialog plugin initialization example
To use the dialog plugin in Tauri 2 JavaScript, initialize it with tauri::Builder::default().plugin(tauri_plugin_dialog::init()) in Rust and import from '@tauri-apps/plugin-dialog' in JavaScript.
V1 plugins now published as npm scoped packages
In Tauri 2, plugins from V1 are now published as @tauri-apps/plugin-<plugin-name>. Previously they were available from git as tauri-plugin-<plugin-name>-api.
JavaScript shell module moved to plugin
In Tauri 2, @tauri-apps/api/shell was removed. Use @tauri-apps/plugin-shell instead.
JavaScript process module moved to plugin
In Tauri 2, @tauri-apps/api/process was removed. Use @tauri-apps/plugin-process instead.
Clipboard plugin initialization example
To use the clipboard plugin in Tauri 2, initialize it with tauri::Builder::default().plugin(tauri_plugin_clipboard_manager::init()) in Rust and import from '@tauri-apps/plugin-clipboard-manager' in JavaScript. Use writeText() and readText() functions.
HTTP plugin initialization example
To use the HTTP plugin in Tauri 2, initialize with tauri::Builder::default().plugin(tauri_plugin_http::init()) and add @tauri-apps/plugin-http@^2.0.0 to package.json. The plugin reexports reqwest for use in Rust code.
JavaScript notification module moved to plugin
In Tauri 2, @tauri-apps/api/notification was removed. Use @tauri-apps/plugin-notification instead.
JavaScript os module moved to plugin
In Tauri 2, @tauri-apps/api/os was removed. Use @tauri-apps/plugin-os instead.
JavaScript http module moved to plugin
In Tauri 2, @tauri-apps/api/http was removed. Use @tauri-apps/plugin-http instead.
JavaScript global-shortcut module moved to plugin
In Tauri 2, @tauri-apps/api/global-shortcut was removed. Use @tauri-apps/plugin-global-shortcut instead.
JavaScript fs module moved to plugin
In Tauri 2, @tauri-apps/api/fs was removed. Use @tauri-apps/plugin-fs instead.
JavaScript clipboard module moved to plugin
In Tauri 2, @tauri-apps/api/clipboard was removed. Use @tauri-apps/plugin-clipboard-manager instead.
JavaScript CLI module moved to plugin
In Tauri 2, @tauri-apps/api/cli was removed. Use @tauri-apps/plugin-cli instead.
Plugin setup configuration method removed
In Tauri 2, Plugin::setup_with_config was removed. Use the updated tauri::Plugin::PluginApi instead.
Global shortcut API moved to plugin in Tauri 2
In Tauri 2, App::global_shortcut_manager and AppHandle::global_shortcut_manager were removed. Use tauri-plugin-global-shortcut instead.
Process and shell APIs moved to plugins in Tauri 2
In Tauri 2, tauri::api::process::Command, tauri::api::shell, and tauri::Manager::shell_scope were removed. Use tauri-plugin-shell instead.
File API in Tauri 2
In Tauri 2, tauri::api::file was removed. Use Rust standard library std::fs instead.
CLI API moved to plugin in Tauri 2
In Tauri 2, App::get_cli_matches was removed. Use tauri-plugin-cli instead.
Plugin API configuration in Tauri 2
In Tauri 2, Plugin::PluginApi now receives plugin configuration as a second argument.
Version API removed in Tauri 2
In Tauri 2, tauri::api::version was removed. Use the semver crate instead.
Global shortcut plugin requires conditional compilation
In Tauri 2, the global-shortcut plugin should be added to Cargo dependencies with a condition to exclude Android and iOS: [target."cfg(not(any(target_os = \"android\", target_os = \"ios\")))".dependencies] tauri-plugin-global-shortcut = "2".
Shell plugin for command execution
In Tauri 2, use tauri-plugin-shell for executing commands and opening URLs. Initialize with tauri::Builder::default().plugin(tauri_plugin_shell::init()) and use @tauri-apps/plugin-shell in JavaScript.
JavaScript dialog module moved to plugin
In Tauri 2, @tauri-apps/api/dialog was removed. Use @tauri-apps/plugin-dialog instead.
Notification plugin initialization example
To use the notification plugin in Tauri 2, initialize with tauri::Builder::default().plugin(tauri_plugin_notification::init()) and add @tauri-apps/plugin-notification@^2.0.0 to package.json. Use sendNotification() or request permission in Rust.
Process plugin for process management
In Tauri 2, use tauri-plugin-process for process functions. Initialize with tauri::Builder::default().plugin(tauri_plugin_process::init()) and add @tauri-apps/plugin-process@^2.0.0 to package.json. Use exit() and relaunch() functions.
OS plugin for system information
In Tauri 2, use tauri-plugin-os for OS information. Initialize with tauri::Builder::default().plugin(tauri_plugin_os::init()) and add @tauri-apps/plugin-os@^2.0.0 to package.json. Call arch() to get system architecture.
Filesystem plugin functions renamed
In Tauri 2, @tauri-apps/plugin-fs renamed several functions: createDir -> mkdir, readBinaryFile -> readFile, removeDir/removeFile -> remove, renameFile -> rename, writeBinaryFile -> writeFile. Type aliases FileEntry, FsBinaryFileOption, FsDirOptions, FsOptions, FsTextFileOption, BinaryFileContents were removed.
Filesystem plugin Dir enum renamed
In Tauri 2, the Dir alias in @tauri-apps/plugin-fs was removed. Use BaseDirectory enum instead.
Shell plugin Rust API for spawning commands
In Tauri 2, use app.shell().command("name").args(["arg1"]).spawn() to spawn a process and receive events, or .status() for status code, or .output() to capture output.
CLI plugin initialization example
To use the CLI plugin in Tauri 2, initialize with tauri::Builder::default().plugin(tauri_plugin_cli::init()) in Rust and add @tauri-apps/plugin-cli@^2.0.0 to package.json. Use getMatches() in JavaScript to get CLI argument matches.
JavaScript updater module moved to plugin
In Tauri 2, @tauri-apps/api/updater was removed. Use @tauri-apps/plugin-updater instead.
Dialog plugin migration in Tauri v2
The Rust `tauri::api::dialog` and JavaScript `@tauri-apps/api/dialog` APIs are removed. Use `@tauri-apps/plugin-dialog` instead. For Rust: add `tauri-plugin-dialog = "2"` to Cargo.toml. Initialize with `tauri::Builder::default().plugin(tauri_plugin_dialog::init())`. Use `app.dialog().file().pick_file(|file_path| { ... })` for file selection and `app.dialog().message("Tauri is Awesome!").show()` for messages. For JavaScript: add `@tauri-apps/plugin-dialog: ^2.0.0` to package.json. Import `{ save } from '@tauri-apps/plugin-dialog'` and call `const filePath = await save({ filters: [{ name: 'Image', extensions: ['png', 'jpeg'] }] });`
File system plugin migration in Tauri v2
The Rust `App::get_cli_matches` and JavaScript `@tauri-apps/api/fs` APIs are removed. For Rust, use `std::fs`. For JavaScript, use `@tauri-apps/plugin-fs` instead. For JavaScript: add `tauri-plugin-fs = "2"` to Cargo.toml and initialize with `tauri::Builder::default().plugin(tauri_plugin_fs::init())`. Add `@tauri-apps/plugin-fs: ^2.0.0` to package.json. Import `{ createDir, BaseDirectory } from '@tauri-apps/plugin-fs'` and call `await createDir('db', { dir: BaseDirectory.AppLocalData });`
Clipboard plugin migration in Tauri v2
The Rust `App::clipboard_manager` and `AppHandle::clipboard_manager` and JavaScript `@tauri-apps/api/clipboard` APIs are removed. Use `@tauri-apps/plugin-clipboard-manager` instead. For Rust: add `tauri-plugin-clipboard-manager = "2"` to Cargo.toml. Initialize with `tauri::Builder::default().plugin(tauri_plugin_clipboard_manager::init())`. Use `app.clipboard().write(ClipKind::PlainText { label: None, text: "Tauri is awesome!".into() })?;` For JavaScript: add `@tauri-apps/plugin-clipboard-manager: ^2.0.0` to package.json. Import `{ writeText, readText } from '@tauri-apps/plugin-clipboard-manager'` and use `await writeText('Tauri is awesome!')` and `assert(await readText(), 'Tauri is awesome!')`.
App plugin migration in Tauri v2
The JavaScript `@tauri-apps/api/app` module is removed. Use `@tauri-apps/plugin-app` instead. For Rust: add `tauri-plugin-app = "2"` to Cargo.toml, then initialize with `tauri::Builder::default().plugin(tauri_plugin_app::init())`. For JavaScript: add `@tauri-apps/plugin-app: ^2.0.0` to package.json, then import `{ show, hide } from '@tauri-apps/plugin-app'` and call `await hide()` and `await show()`. For Rust in setup, use `app.hide()?` and `app.show()?` on macOS.
CLI plugin migration in Tauri v2
The Rust `App::get_cli_matches` and JavaScript `@tauri-apps/api/cli` APIs are removed. Use `@tauri-apps/plugin-cli` instead. For Rust: add `tauri-plugin-cli = "2"` to Cargo.toml. Initialize with `tauri::Builder::default().plugin(tauri_plugin_cli::init())`. Use `app.cli().matches()?` in setup. For JavaScript: add `@tauri-apps/plugin-cli: ^2.0.0` to package.json. Import `{ getMatches } from '@tauri-apps/plugin-cli'` and call `const matches = await getMatches();`
Global shortcut plugin migration in Tauri v2
The Rust `App::global_shortcut_manager` and `AppHandle::global_shortcut_manager` and JavaScript `@tauri-apps/api/global-shortcut` APIs are removed. Use `@tauri-apps/plugin-global-shortcut` instead. For Rust: add `tauri-plugin-global-shortcut = "2"` to Cargo.toml. Initialize with `tauri::Builder::default().plugin(tauri_plugin_global_shortcut::init())`. Use `app.global_shortcut().register("CmdOrCtrl+Y")?;` For JavaScript: add `@tauri-apps/plugin-global-shortcut: ^2.0.0` to package.json. Import `{ register } from '@tauri-apps/plugin-global-shortcut'` and call `await register('CommandOrControl+Shift+C', () => { console.log('Shortcut triggered'); });`