2.4 MiB
This is the full developer documentation for Tauri
Tauri 2.0
The cross-platform app building toolkit
Create small, fast, secure, cross-platform applications
Get startedTauri 1.0 Documentation
Create a Project
-
Bash
sh <(curl https://create.tauri.app/sh) -
PowerShell
irm https://create.tauri.app/ps | iex -
Fish
sh (curl -sSL https://create.tauri.app/sh | psub) -
npm
npm create tauri-app@latest -
Yarn
yarn create tauri-app -
pnpm
pnpm create tauri-app -
deno
deno run -A npm:create-tauri-app -
bun
bun create tauri-app -
Cargo
cargo install create-tauri-app --locked cargo create-tauri-app
Front-of-mind for the Tauri Team that drives our highest priorities and biggest innovations.
By using the OS’s native web renderer, the size of a Tauri app can be little as 600KB.
What is Tauri?
Information for getting up and running with Tauri, including prerequisites and installation instructions
Tauri is a framework for building tiny, fast binaries for all major desktop and mobile platforms. Developers can integrate any frontend framework that compiles to HTML, JavaScript, and CSS for building their user experience while leveraging languages such as Rust, Swift, and Kotlin for backend logic when needed.
Get started building with create-tauri-app by using one of the below commands. Be sure to follow the prerequisites guide to install all of the dependencies required by Tauri. For a more detailed walk through, see Create a Project
-
Bash
sh <(curl https://create.tauri.app/sh) -
PowerShell
irm https://create.tauri.app/ps | iex -
Fish
sh (curl -sSL https://create.tauri.app/sh | psub) -
npm
npm create tauri-app@latest -
Yarn
yarn create tauri-app -
pnpm
pnpm create tauri-app -
deno
deno run -A npm:create-tauri-app -
bun
bun create tauri-app -
Cargo
cargo install create-tauri-app --locked cargo create-tauri-app
After you’ve created your first app, take a look at Project Structure to understand what each file does.
Or explore the project setups and features from the examples (tauri | plugins-workspace)
Why Tauri?
Tauri has 3 main advantages for developers to build upon:
- Secure foundation for building apps
- Smaller bundle size by using the system’s native webview
- Flexibility for developers to use any frontend and bindings for multiple languages
Learn more about the Tauri philosophy in the Tauri 1.0 blog post.
Secure Foundation
By being built on Rust, Tauri is able to take advantage of the memory, thread, and type-safety offered by Rust. Apps built on Tauri can automatically get those benefits even without needing to be developed by Rust experts.
Tauri also undergoes a security audit for major and minor releases. This not only covers code in the Tauri organization, but also for upstream dependencies that Tauri relies on. Of course this doesn’t mitigate all risks, but it provides a solid foundation for developers to build on top of.
Read the Tauri security policy and the Tauri 2.0 audit report.
Smaller App Size
Tauri apps take advantage of the web view already available on every user’s system. A Tauri app only contains the code and assets specific for that app and doesn’t need to bundle a browser engine with every app. This means that a minimal Tauri app can be less than 600KB in size.
Learn more about creating optimized apps in the App Size concept.
Flexible Architecture
Since Tauri uses web technologies that means that virtually any frontend framework is compatible with Tauri. The Frontend Configuration guide contains common configurations for popular frontend frameworks.
Bindings between JavaScript and Rust are available to developers using the invoke function in JavaScript and Swift and Kotlin bindings are available for Tauri Plugins.
TAO is responsible for Tauri window creation and WRY is responsible for web view rendering. These are libraries maintained by Tauri and can be consumed directly if deeper system integration is required outside of what Tauri exposes.
In addition, Tauri maintains a number of plugins to extend what core Tauri exposes. You can find those plugins alongside those provided by the community in the Plugins section.
Create a Project
One thing that makes Tauri so flexible is its ability to work with virtually any frontend framework. We’ve created the create-tauri-app utility to help you create a new Tauri project using one of the officially maintained framework templates.
create-tauri-app currently includes templates for vanilla (HTML, CSS and JavaScript without a framework), Vue.js, Svelte, React, SolidJS, Angular, Preact, Yew, Leptos, and Sycamore. You can also find or add your own community templates and frameworks in the Awesome Tauri repo.
Alternatively, you can add Tauri to an existing project to quickly turn your existing codebase into a Tauri app.
Using create-tauri-app
To get started using create-tauri-app run one of the below commands in the folder you’d like to setup your project. If you’re not sure which command to use we recommend the Bash command on Linux and macOS and the PowerShell command on Windows.
-
Bash
sh <(curl https://create.tauri.app/sh) -
PowerShell
irm https://create.tauri.app/ps | iex -
Fish
sh (curl -sSL https://create.tauri.app/sh | psub) -
npm
npm create tauri-app@latest -
Yarn
yarn create tauri-app -
pnpm
pnpm create tauri-app -
deno
deno run -A npm:create-tauri-app -
bun
bun create tauri-app -
Cargo
cargo install create-tauri-app --locked cargo create-tauri-app
Follow along with the prompts to choose your project name, frontend language, package manager, and frontend framework, and frontend framework options if applicable.
Not sure what to choose?
We recommend starting with the vanilla template (HTML, CSS, and JavaScript without a frontend framework) to get started. You can always integrate a frontend framework later.
- Choose which language to use for your frontend:
TypeScript / JavaScript - Choose your package manager:
pnpm - Choose your UI template:
Vanilla - Choose your UI flavor:
TypeScript
Scaffold a new project
-
Choose a name and a bundle identifier (unique-id for your app):
? Project name (tauri-app) › ? Identifier (com.tauri-app.app) › -
Select a flavor for your frontend. First the language:
? Choose which language to use for your frontend › Rust (cargo) TypeScript / JavaScript (pnpm, yarn, npm, bun) .NET (dotnet) -
Select a package manager (if there are multiple available):
Options for TypeScript / JavaScript:
? Choose your package manager › pnpm yarn npm bun -
Select a UI Template and flavor (if there are multiple available):
Options for Rust:
? Choose your UI template › Vanilla Yew Leptos SycamoreOptions for TypeScript / JavaScript:
? Choose your UI template › Vanilla Vue Svelte React Solid Angular Preact ? Choose your UI flavor › TypeScript JavaScriptOptions for .NET:
? Choose your UI template › Blazor (https://dotnet.microsoft.com/en-us/apps/aspnet/web-apps/blazor/)
Once completed, the utility reports that the template has been created and displays how to run it using the configured package manager. If it detects missing dependencies on your system, it prints a list of packages and prompts how to install them.
Start the development server
After create-tauri-app has completed, you can navigate into your project’s folder, install dependencies, and then use the Tauri CLI to start the development server:
-
npm
cd tauri-app npm install npm run tauri dev -
yarn
cd tauri-app yarn install yarn tauri dev -
pnpm
cd tauri-app pnpm install pnpm tauri dev -
deno
cd tauri-app deno install deno task tauri dev -
bun
cd tauri-app bun install bun tauri dev -
cargo
cd tauri-app cargo install tauri-cli --version "^2.0.0" --locked cargo tauri dev
You’ll now see a new window open with your app running.
Congratulations! You’ve made your Tauri app! 🚀
Manual Setup (Tauri CLI)
If you already have an existing frontend or prefer to set it up yourself, you can use the Tauri CLI to initialize the backend for your project separately.
Note
The following example assumes you are creating a new project. If you’ve already initialized the frontend of your application, you can skip the first step.
-
Create a new directory for your project and initialize the frontend. You can use plain HTML, CSS, and JavaScript, or any framework you prefer such as Next.js, Nuxt, Svelte, Yew, or Leptos. You just need a way of serving the app in your browser. Just as an example, this is how you would setup a simple Vite app:
-
npm
mkdir tauri-app cd tauri-app npm create vite@latest . -
yarn
mkdir tauri-app cd tauri-app yarn create vite . -
pnpm
mkdir tauri-app cd tauri-app pnpm create vite . -
deno
mkdir tauri-app cd tauri-app deno run -A npm:create-vite . -
bun
mkdir tauri-app cd tauri-app bun create vite
-
-
Then, install Tauri’s CLI tool using your package manager of choice. If you are using
cargoto install the Tauri CLI, you will have to install it globally.-
npm
npm install -D @tauri-apps/cli@latest -
yarn
yarn add -D @tauri-apps/cli@latest -
pnpm
pnpm add -D @tauri-apps/cli@latest -
deno
deno add -D npm:@tauri-apps/cli@latest -
bun
bun add -D @tauri-apps/cli@latest -
cargo
cargo install tauri-cli --version "^2.0.0" --locked
-
-
Determine the URL of your frontend development server. This is the URL that Tauri will use to load your content. For example, if you are using Vite, the default URL is
http://localhost:5173. -
In your project directory, initialize Tauri:
-
npm
npx tauri init -
yarn
yarn tauri init -
pnpm
pnpm tauri init -
deno
deno task tauri init -
bun
bun tauri init -
cargo
cargo tauri init
After running the command it will display a prompt asking you for different options:
✔ What is your app name? tauri-app ✔ What should the window title be? tauri-app ✔ Where are your web assets located? .. ✔ What is the url of your dev server? http://localhost:5173 ✔ What is your frontend dev command? pnpm run dev ✔ What is your frontend build command? pnpm run buildThis will create a
src-tauridirectory in your project with the necessary Tauri configuration files. -
-
Configure the
server.watch.ignoredoption invite.config.tsto prevent Vite from watching thesrc-tauridirectory:vite.config.ts
import { defineConfig } from "vite"; export default defineConfig({ server: { watch: { ignored: ["**/src-tauri/**"], }, }, }); -
Verify your Tauri app is working by running the development server:
-
npm
npx tauri dev -
yarn
yarn tauri dev -
pnpm
pnpm tauri dev -
deno
deno task tauri dev -
bun
bun tauri dev -
cargo
cargo tauri dev
This command will compile the Rust code and open a window with your web content.
-
Congratulations! You’ve created a new Tauri project using the Tauri CLI! 🚀
Next Steps
- Learn about the project layout and what each file does
- Add and Configure a Frontend Framework
- Tauri Command Line Interface (CLI) Reference
- Learn how to develop your Tauri app
- Discover additional features to extend Tauri
Frontend Configuration
Tauri is frontend agnostic and supports most frontend frameworks out of the box. However, sometimes a framework need a bit of extra configuration to integrate with Tauri. Below is a list of frameworks with recommended configurations.
If a framework is not listed then it may work with Tauri with no additional configuration needed or it could have not been documented yet. Any contributions to add a framework that may require additional configuration are welcome to help others in the Tauri community.
Configuration Checklist
Conceptually Tauri acts as a static web host. You need to provide Tauri with a folder containing some mix of HTML, CSS, Javascript and possibly WASM that can be served to the webview Tauri provides.
Below is a checklist of common scenarios needed to integrate a frontend with Tauri:
- Use static site generation (SSG), single-page applications (SPA), or classic multi-page apps (MPA). Tauri does not natively support server based alternatives (such as SSR).
- For mobile development, a development server of some kind is necessary that can host the frontend on your internal IP.
- Use a proper client-server relationship between your app and your API’s (no hybrid solutions with SSR).
JavaScript
For most projects we recommend Vite for SPA frameworks such as React, Vue, Svelte, and Solid, but also for plain JavaScript or TypeScript projects. Most other guides listed here show how to use Meta-Frameworks as they are typically designed for SSR and therefore require special configuration.
Rust
Framework Not Listed?
Don’t see a framework listed? It may work with Tauri without any additional configuration required. Read the configuration checklist for any common configurations to check for.
Leptos
Leptos is a Rust based web framework. You can read more about Leptos on their official website. This guide is accurate as of Leptos version 0.6.
Checklist
- Use SSG, Tauri doesn’t officially support server based solutions.
- Use
serve.ws_protocol = "ws"so that the hot-reload websocket can connect properly for mobile development. - Enable
withGlobalTaurito ensure that Tauri APIs are available in thewindow.__TAURI__variable and can be imported usingwasm-bindgen.
Example Configuration
-
Update Tauri configuration
src-tauri/tauri.conf.json
{ "build": { "beforeDevCommand": "trunk serve", "devUrl": "http://localhost:1420", "beforeBuildCommand": "trunk build", "frontendDist": "../dist" }, "app": { "withGlobalTauri": true } } -
Update Trunk configuration
Trunk.toml
[build] target = "./index.html" [watch] ignore = ["./src-tauri"] [serve] port = 1420 open = false ws_protocol = "ws"
Next.js
Next.js is a meta framework for React. Learn more about Next.js at https://nextjs.org. This guide is accurate as of Next.js 14.2.3.
Checklist
- Use static exports by setting
output: 'export'. Tauri doesn’t support server-based solutions. - Use the
outdirectory asfrontendDistintauri.conf.json.
Example Configuration
-
Update Tauri configuration
-
npm
src-tauri/tauri.conf.json
{ "build": { "beforeDevCommand": "npm run dev", "beforeBuildCommand": "npm run build", "devUrl": "http://localhost:3000", "frontendDist": "../out" } } -
yarn
src-tauri/tauri.conf.json
{ "build": { "beforeDevCommand": "yarn dev", "beforeBuildCommand": "yarn build", "devUrl": "http://localhost:3000", "frontendDist": "../out" } } -
pnpm
src-tauri/tauri.conf.json
{ "build": { "beforeDevCommand": "pnpm dev", "beforeBuildCommand": "pnpm build", "devUrl": "http://localhost:3000", "frontendDist": "../out" } } -
deno
src-tauri/tauri.conf.json
{ "build": { "beforeDevCommand": "deno task dev", "beforeBuildCommand": "deno task build", "devUrl": "http://localhost:3000", "frontendDist": "../out" } }
-
-
Update Next.js configuration
next.config.mjs
const isProd = process.env.NODE_ENV === 'production'; const internalHost = process.env.TAURI_DEV_HOST || 'localhost'; /** @type {import('next').NextConfig} */ const nextConfig = { // Ensure Next.js uses SSG instead of SSR // https://nextjs.org/docs/pages/building-your-application/deploying/static-exports output: 'export', // Note: This feature is required to use the Next.js Image component in SSG mode. // See https://nextjs.org/docs/messages/export-image-api for different workarounds. images: { unoptimized: true, }, // Configure assetPrefix or else the server won't properly resolve your assets. assetPrefix: isProd ? undefined : `http://${internalHost}:3000`, }; export default nextConfig; -
Update package.json configuration
"scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint", "tauri": "tauri" }
Nuxt
Nuxt is a meta framework for Vue. Learn more about Nuxt at https://nuxt.com. This guide is accurate as of Nuxt 4.2.
Checklist
- Use SSG by setting
ssr: false. Tauri doesn’t support server based solutions. - Use default
../distasfrontendDistintauri.conf.json. - Compile using
nuxi build. - (Optional): Disable telemetry by setting
telemetry: falseinnuxt.config.ts.
Example Configuration
-
Update Tauri configuration
-
npm
tauri.conf.json
{ "build": { "beforeDevCommand": "npm run dev", "beforeBuildCommand": "npm run generate", "devUrl": "http://localhost:3000", "frontendDist": "../dist" } } -
yarn
tauri.conf.json
{ "build": { "beforeDevCommand": "yarn dev", "beforeBuildCommand": "yarn generate", "devUrl": "http://localhost:3000", "frontendDist": "../dist" } } -
pnpm
tauri.conf.json
{ "build": { "beforeDevCommand": "pnpm dev", "beforeBuildCommand": "pnpm generate", "devUrl": "http://localhost:3000", "frontendDist": "../dist" } } -
deno
tauri.conf.json
{ "build": { "beforeDevCommand": "deno task dev", "beforeBuildCommand": "deno task generate", "devUrl": "http://localhost:3000", "frontendDist": "../dist" } }
-
-
Update Nuxt configuration
export default defineNuxtConfig({ compatibilityDate: '2025-05-15', // (optional) Enable the Nuxt devtools devtools: { enabled: true }, // Enable SSG ssr: false, // Enables the development server to be discoverable by other devices when running on iOS physical devices devServer: { host: '0', }, vite: { // Better support for Tauri CLI output clearScreen: false, // Enable environment variables // Additional environment variables can be found at // https://v2.tauri.app/reference/environment-variables/ envPrefix: ['VITE_', 'TAURI_'], server: { // Tauri requires a consistent port strictPort: true, }, }, // Avoids error [unhandledRejection] EMFILE: too many open files, watch ignore: ['**/src-tauri/**'], });
Qwik
This guide will walk you through creating your Tauri app using the Qwik web framework. Learn more about Qwik at https://qwik.dev.
Checklist
- Use SSG. Tauri doesn’t support server-based solutions.
- Use
dist/asfrontendDistintauri.conf.json.
Example Configuration
-
Create a new Qwik app
-
npm
npm create qwik@latest cd <PROJECT> -
yarn
yarn create qwik@latest cd <PROJECT> -
pnpm
pnpm create qwik@latest cd <PROJECT> -
deno
deno run -A npm:create-qwik@latest cd <PROJECT>
-
-
Install the
static adapter-
npm
npm run qwik add static -
yarn
yarn qwik add static -
pnpm
pnpm qwik add static -
deno
deno task qwik add static
-
-
Add the Tauri CLI to your project
-
npm
npm install -D @tauri-apps/cli@latest -
yarn
yarn add -D @tauri-apps/cli@latest -
pnpm
pnpm add -D @tauri-apps/cli@latest -
deno
deno add -D npm:@tauri-apps/cli@latest
-
-
Initiate a new Tauri project
-
npm
npm run tauri init -
yarn
yarn tauri init -
pnpm
pnpm tauri init -
deno
deno task tauri init
-
-
Tauri configuration
-
npm
tauri.conf.json
{ "build": { "devUrl": "http://localhost:5173" "frontendDist": "../dist", "beforeDevCommand": "npm run dev", "beforeBuildCommand": "npm run build" } } -
yarn
tauri.conf.json
{ "build": { "devUrl": "http://localhost:5173" "frontendDist": "../dist", "beforeDevCommand": "yarn dev", "beforeBuildCommand": "yarn build" } } -
pnpm
tauri.conf.json
{ "build": { "devUrl": "http://localhost:5173" "frontendDist": "../dist", "beforeDevCommand": "pnpm dev", "beforeBuildCommand": "pnpm build" } } -
deno
tauri.conf.json
{ "build": { "devUrl": "http://localhost:5173" "frontendDist": "../dist", "beforeDevCommand": "deno task dev", "beforeBuildCommand": "deno task build" } }
-
-
Start your
tauriapp-
npm
npm run tauri dev -
yarn
yarn tauri dev -
pnpm
pnpm tauri dev -
deno
deno task tauri dev
-
SvelteKit
SvelteKit is a meta framework for Svelte. Learn more about SvelteKit at https://svelte.dev/. This guide is accurate as of SvelteKit 2.20.4 / Svelte 5.25.8.
Checklist
- Use SSG and SPA via
static-adapter. Tauri doesn’t support server-based solutions. - If using SSG with prerendering, be aware that
loadfunctions will not have access to tauri APIs during the build process of your app. Using SPA mode (without prerendering) is recommended since the load functions will only run in the webview with access to tauri APIs. - Use
build/asfrontendDistintauri.conf.json.
Example Configuration
-
Install
@sveltejs/adapter-static-
npm
npm install --save-dev @sveltejs/adapter-static -
yarn
yarn add -D @sveltejs/adapter-static -
pnpm
pnpm add -D @sveltejs/adapter-static -
deno
deno add -D npm:@sveltejs/adapter-static
-
-
Update Tauri configuration
-
npm
tauri.conf.json
{ "build": { "beforeDevCommand": "npm run dev", "beforeBuildCommand": "npm run build", "devUrl": "http://localhost:5173", "frontendDist": "../build" } } -
yarn
tauri.conf.json
{ "build": { "beforeDevCommand": "yarn dev", "beforeBuildCommand": "yarn build", "devUrl": "http://localhost:5173", "frontendDist": "../build" } } -
pnpm
tauri.conf.json
{ "build": { "beforeDevCommand": "pnpm dev", "beforeBuildCommand": "pnpm build", "devUrl": "http://localhost:5173", "frontendDist": "../build" } } -
deno
tauri.conf.json
{ "build": { "beforeDevCommand": "deno task dev", "beforeBuildCommand": "deno task build", "devUrl": "http://localhost:5173", "frontendDist": "../build" } }
-
-
Update SvelteKit configuration:
svelte.config.js
import adapter from '@sveltejs/adapter-static'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; /** @type {import('@sveltejs/kit').Config} */ const config = { // Consult https://svelte.dev/docs/kit/integrations#preprocessors // for more information about preprocessors preprocess: vitePreprocess(), kit: { adapter: adapter({ fallback: 'index.html', }), }, }; export default config; -
Disable SSR
Lastly, we need to disable SSR by adding a root
+layout.tsfile (or+layout.jsif you are not using TypeScript) with these contents:src/routes/+layout.ts
export const ssr = false;Note that
static-adapterdoesn’t require you to disable SSR for the whole app but it makes it possible to use APIs that depend on the global window object (like Tauri’s API) without Client-side checks.Furthermore, if you prefer Static Site Generation (SSG) over Single-Page Application (SPA) mode, you can change the adapter configurations and
+layout.tsaccording to the adapter docs.
Trunk
Trunk is a WASM web application bundler for Rust. Learn more about Trunk at https://trunk-rs.github.io/trunk/. This guide is accurate as of Trunk 0.17.5.
Checklist
- Use SSG, Tauri doesn’t officially support server based solutions.
- Use
serve.ws_protocol = "ws"so that the hot-reload websocket can connect properly for mobile development. - Enable
withGlobalTaurito ensure that Tauri APIs are available in thewindow.__TAURI__variable and can be imported usingwasm-bindgen.
Example Configuration
-
Update Tauri configuration
tauri.conf.json
{ "build": { "beforeDevCommand": "trunk serve", "beforeBuildCommand": "trunk build", "devUrl": "http://localhost:8080", "frontendDist": "../dist" }, "app": { "withGlobalTauri": true } } -
Update Trunk configuration
Trunk.toml
[watch] ignore = ["./src-tauri"] [serve] ws_protocol = "ws"
Vite
Vite is a build tool that aims to provide a faster and leaner development experience for modern web projects. This guide is accurate as of Vite 5.4.8.
Checklist
- Use
../distasfrontendDistinsrc-tauri/tauri.conf.json. - Use
process.env.TAURI_DEV_HOSTas the development server host IP when set to run on iOS physical devices.
Example configuration
-
Update Tauri configuration
Assuming you have the following
devandbuildscripts in yourpackage.json:{ "scripts": { "dev": "vite", "build": "tsc && vite build", "preview": "vite preview", "tauri": "tauri" } }You can configure the Tauri CLI to use your Vite development server and dist folder along with the hooks to automatically run the Vite scripts:
-
npm
tauri.conf.json
{ "build": { "beforeDevCommand": "npm run dev", "beforeBuildCommand": "npm run build", "devUrl": "http://localhost:5173", "frontendDist": "../dist" } } -
yarn
tauri.conf.json
{ "build": { "beforeDevCommand": "yarn dev", "beforeBuildCommand": "yarn build", "devUrl": "http://localhost:5173", "frontendDist": "../dist" } } -
pnpm
tauri.conf.json
{ "build": { "beforeDevCommand": "pnpm dev", "beforeBuildCommand": "pnpm build", "devUrl": "http://localhost:5173", "frontendDist": "../dist" } } -
deno
tauri.conf.json
{ "build": { "beforeDevCommand": "deno task dev", "beforeBuildCommand": "deno task build", "devUrl": "http://localhost:5173", "frontendDist": "../dist" } }
-
-
Update Vite configuration:
vite.config.js
import { defineConfig } from 'vite'; const host = process.env.TAURI_DEV_HOST; export default defineConfig({ // prevent vite from obscuring rust errors clearScreen: false, server: { // make sure this port matches the devUrl port in tauri.conf.json file port: 5173, // Tauri expects a fixed port, fail if that port is not available strictPort: true, // if the host Tauri is expecting is set, use it host: host || false, hmr: host ? { protocol: 'ws', host, port: 1421, } : undefined, watch: { // tell vite to ignore watching `src-tauri` ignored: ['**/src-tauri/**'], }, }, // Env variables starting with the item of `envPrefix` will be exposed in tauri's source code through `import.meta.env`. envPrefix: ['VITE_', 'TAURI_ENV_*'], build: { // Tauri uses Chromium on Windows and WebKit on macOS and Linux target: process.env.TAURI_ENV_PLATFORM == 'windows' ? 'chrome105' : 'safari13', // don't minify for debug builds minify: !process.env.TAURI_ENV_DEBUG ? 'esbuild' : false, // produce sourcemaps for debug builds sourcemap: !!process.env.TAURI_ENV_DEBUG, }, });
Upgrade & Migrate
Learn about common scenarios and steps to upgrade from Tauri 1.0 or migrate from another framework.
Upgrade from Tauri 1.0Read more about the updates you need to make to a version 1 project in order to upgrade to version 2.
Migrate from Tauri 2.0 betaRead more about the updates required for the 2.0 beta project to upgrade to 2.0.
Upgrade from Tauri 1.0
This guide walks you through upgrading your Tauri 1.0 application to Tauri 2.0.
Preparing for Mobile
The mobile interface of Tauri requires your project to output a shared library. If you are targeting mobile for your existing application, you must change your crate to produce that kind of artifact along with the desktop executable.
- Change the Cargo manifest to produce the library. Append the following block:
src-tauri/Cargo.toml
[lib]
name = "app_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
-
Rename
src-tauri/src/main.rstosrc-tauri/src/lib.rs. This file will be shared by both desktop and mobile targets. -
Rename the
mainfunction header inlib.rsto the following:
src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
// your code here
}
The tauri::mobile_entry_point macro prepares your function to be executed on mobile.
- Recreate the
main.rsfile calling the shared run function:
src-tauri/src/main.rs
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
app_lib::run();
}
Automated Migration
Danger
This command is not a substitute for this guide! Please read the whole page regardless of whether you chose to use the command.
The Tauri v2 CLI includes a migrate command that automates most of the process and helps you finish the migration:
-
npm
npm install @tauri-apps/cli@latest npm run tauri migrate -
yarn
yarn upgrade @tauri-apps/cli@latest yarn tauri migrate -
pnpm
pnpm update @tauri-apps/cli@latest pnpm tauri migrate -
cargo
cargo install tauri-cli --version "^2.0.0" --locked cargo tauri migrate
Learn more about the migrate command in the Command Line Interface reference
Summary of Changes
Below is a summary of the changes from Tauri 1.0 to Tauri 2.0:
Tauri Configuration
package > productNameandpackage > versionmoved to top-level object.- the binary name is no longer renamed to match
productNameautomatically, so you must add amainBinaryNamestring to the top-level object matchingproductName. packageremoved.taurikey renamed toapp.tauri > allowlistremoved. Refer to Migrate Permissions.tauri > allowlist > protocol > assetScopemoved toapp > security > assetProtocol > scope. See Asset protocol scope forenable, glob patterns,requireLiteralLeadingDot, and dynamic paths.tauri > climoved toplugins > cli.tauri > windows > fileDropEnabledrenamed toapp > windows > dragDropEnabled.tauri > updater > activeremoved.tauri > updater > dialogremoved.tauri > updatermoved toplugins > updater.bundle > createUpdaterArtifactsadded, must be set when using the app updater.- set it to
v1Compatiblewhen upgrading from v1 apps that were already distributed. See the updater guide for more information.
- set it to
tauri > systemTrayrenamed toapp > trayIcon.tauri > patternmoved toapp > security > pattern.tauri > bundlemoved top-level.tauri > bundle > identifiermoved to top-level object.tauri > bundle > dmgmoved tobundle > macOS > dmgtauri > bundle > debmoved tobundle > linux > debtauri > bundle > appimagemoved tobundle > linux > appimagetauri > bundle > macOS > licenseremoved, usebundle > licenseFileinstead.tauri > bundle > windows > wix > licenseremoved, usebundle > licenseFileinstead.tauri > bundle > windows > nsis > licenseremoved, usebundle > licenseFileinstead.tauri > bundle > windows > webviewFixedRuntimePathremoved, usebundle > windows > webviewInstallModeinstead.build > withGlobalTaurimoved toapp > withGlobalTauri.build > distDirrenamed tofrontendDist.build > devPathrenamed todevUrl.
Tauri 2.0 Configuration API reference
New Cargo Features
- linux-protocol-body: Enables custom protocol request body parsing, allowing the IPC to use it. Requires webkit2gtk 2.40.
Removed Cargo Features
- reqwest-client: reqwest is now the only supported client.
- reqwest-native-tls-vendored: use
native-tls-vendoredinstead. - process-command-api: use the
shellplugin instead (see instructions in the following section). - shell-open-api: use the
shellplugin instead (see instructions in the following section). - windows7-compat: moved to the
notificationplugin. - updater: Updater is now a plugin.
- linux-protocol-headers: Now enabled by default since we upgraded our minimum webkit2gtk version.
- system-tray: renamed to
tray-icon.
Rust Crate Changes
apimodule removed. Each API module can be found in a Tauri plugin.api::dialogmodule removed. Usetauri-plugin-dialoginstead. Migrationapi::filemodule removed. Use Rust’sstd::fsinstead.api::httpmodule removed. Usetauri-plugin-httpinstead. Migrationapi::ipmodule rewritten and moved totauri::ipc. Check out the new APIs, speciallytauri::ipc::Channel.api::pathmodule functions andtauri::PathResolvedmoved totauri::Manager::path. Migrationapi::process::Command,tauri::api::shellandtauri::Manager::shell_scopeAPIs removed. Usetauri-plugin-shellinstead. Migrationapi::process::current_binaryandtauri::api::process::restartmoved totauri::process.api::versionmodule has been removed. Use the semver crate instead.App::clipboard_managerandAppHandle::clipboard_managerremoved. Usetauri-plugin-clipboardinstead. MigrationApp::get_cli_matchesremoved. Usetauri-plugin-cliinstead. MigrationApp::global_shortcut_managerandAppHandle::global_shortcut_managerremoved. Usetauri-plugin-global-shortcutinstead. MigrationManager::fs_scoperemoved. The file system scope can be accessed viatauri_plugin_fs::FsExt.Plugin::PluginApinow receives a plugin configuration as a second argument.Plugin::setup_with_configremoved. Use the updatedtauri::Plugin::PluginApiinstead.scope::ipc::RemoteDomainAccessScope::enable_tauri_apiandscope::ipc::RemoteDomainAccessScope::enables_tauri_apiremoved. Enable each core plugin individually viascope::ipc::RemoteDomainAccessScope::add_plugininstead.scope::IpcScoperemoved, usescope::ipc::Scopeinstead.scope::FsScope,scope::GlobPatternandscope::FsScopeEventremoved, usescope::fs::Scope,scope::fs::Patternandscope::fs::Eventrespectively.updatermodule removed. Usetauri-plugin-updaterinstead. MigrationEnv.argsfield has been removed, useEnv.args_osfield instead.Menu,MenuEvent,CustomMenuItem,Submenu,WindowMenuEvent,MenuItemandBuilder::on_menu_eventAPIs removed. MigrationSystemTray,SystemTrayHandle,SystemTrayMenu,SystemTrayMenuItemHandle,SystemTraySubmenu,MenuEntryandSystemTrayMenuItemAPIs removed. Migration
JavaScript API Changes
The @tauri-apps/api package no longer provides non-core modules. Only the previous tauri (now core), path, event and window modules are exported. All others have been moved to plugins.
@tauri-apps/api/taurimodule renamed to@tauri-apps/api/core. Migration@tauri-apps/api/climodule removed. Use@tauri-apps/plugin-cliinstead. Migration@tauri-apps/api/clipboardmodule removed. Use@tauri-apps/plugin-clipboardinstead. Migration@tauri-apps/api/dialogmodule removed. Use@tauri-apps/plugin-dialoginstead. Migration@tauri-apps/api/fsmodule removed. Use@tauri-apps/plugin-fsinstead. Migration@tauri-apps/api/global-shortcutmodule removed. Use@tauri-apps/plugin-global-shortcutinstead. Migration@tauri-apps/api/httpmodule removed. Use@tauri-apps/plugin-httpinstead. Migration@tauri-apps/api/osmodule removed. Use@tauri-apps/plugin-osinstead. Migration@tauri-apps/api/notificationmodule removed. Use@tauri-apps/plugin-notificationinstead. Migration@tauri-apps/api/processmodule removed. Use@tauri-apps/plugin-processinstead. Migration@tauri-apps/api/shellmodule removed. Use@tauri-apps/plugin-shellinstead. Migration@tauri-apps/api/updatermodule removed. Use@tauri-apps/plugin-updaterinstead Migration@tauri-apps/api/windowmodule renamed to@tauri-apps/api/webviewWindow. Migration
The v1 plugins are now published as @tauri-apps/plugin-<plugin-name>. Previously they were available from git as tauri-plugin-<plugin-name>-api.
Environment Variables Changes
Most of the environment variables read and written by the Tauri CLI were renamed for consistency and prevention of mistakes:
TAURI_PRIVATE_KEY->TAURI_SIGNING_PRIVATE_KEYTAURI_KEY_PASSWORD->TAURI_SIGNING_PRIVATE_KEY_PASSWORDTAURI_SKIP_DEVSERVER_CHECK->TAURI_CLI_NO_DEV_SERVER_WAITTAURI_DEV_SERVER_PORT->TAURI_CLI_PORTTAURI_PATH_DEPTH->TAURI_CLI_CONFIG_DEPTHTAURI_FIPS_COMPLIANT->TAURI_BUNDLER_WIX_FIPS_COMPLIANTTAURI_DEV_WATCHER_IGNORE_FILE->TAURI_CLI_WATCHER_IGNORE_FILENAMETAURI_TRAY->TAURI_LINUX_AYATANA_APPINDICATORTAURI_APPLE_DEVELOPMENT_TEAM->APPLE_DEVELOPMENT_TEAMTAURI_PLATFORM->TAURI_ENV_PLATFORMTAURI_ARCH->TAURI_ENV_ARCHTAURI_FAMILY->TAURI_ENV_FAMILYTAURI_PLATFORM_VERSION->TAURI_ENV_PLATFORM_VERSIONTAURI_PLATFORM_TYPE->TAURI_ENV_PLATFORM_TYPETAURI_DEBUG->TAURI_ENV_DEBUG
Event System
The event system was redesigned to be easier to use. Instead of relying on the source of the event, it now has a simpler implementation that relies on event targets.
- The
emitfunction now emits the event to all event listeners. - Added a new
emit_to/emitTofunction to trigger an event to a specific target. emit_filternow filters based onEventTargetinstead of a window.- Renamed
listen_globaltolisten_any. It now listens to all events regardless of their filters and targets. - JavaScript:
event.listen()behaves similar tolisten_any. It now listens to all events regardless of their filters and targets, unless a target is set in theOptions. - JavaScript:
WebviewWindow.listenetc. only listen to events emitted to the respectiveEventTarget.
Multiwebview support
Tauri v2 introduces multiwebview support currently behind an unstable feature flag. In order to support it, we renamed the Rust Window type to WebviewWindow and the Manager get_window function to get_webview_window.
The WebviewWindow JS API type is now re-exported from @tauri-apps/api/webviewWindow instead of @tauri-apps/api/window.
New origin URL on Windows
On Windows the frontend files in production apps are now hosted on http://tauri.localhost instead of https://tauri.localhost. Because of this IndexedDB, LocalStorage and Cookies will be reset unless dangerousUseHttpScheme was used in v1. To prevent this you can set app > windows > useHttpsScheme to true or use WebviewWindowBuilder::use_https_scheme to keep using the https scheme.
Detailed Migration Steps
Common scenarios you may encounter when migrating your Tauri 1.0 app to Tauri 2.0.
Migrate to Core Module
The @tauri-apps/api/tauri module was renamed to @tauri-apps/api/core. Simply rename the module import:
import { invoke } from "@tauri-apps/api/tauri"
import { invoke } from "@tauri-apps/api/core"
Migrate to CLI Plugin
The Rust App::get_cli_matches JavaScript @tauri-apps/api/cli APIs have been removed. Use the @tauri-apps/plugin-cli plugin instead:
- Add to cargo dependencies:
Cargo.toml
[dependencies]
tauri-plugin-cli = "2"
- Use in JavaScript or Rust project:
-
JavaScript
fn main() { tauri::Builder::default() .plugin(tauri_plugin_cli::init()) }package.json
{ "dependencies": { "@tauri-apps/plugin-cli": "^2.0.0" } }import { getMatches } from '@tauri-apps/plugin-cli'; const matches = await getMatches(); -
Rust
fn main() { use tauri_plugin_cli::CliExt; tauri::Builder::default() .plugin(tauri_plugin_cli::init()) .setup(|app| { let cli_matches = app.cli().matches()?; Ok(()) }) }
Migrate to Clipboard Plugin
The Rust App::clipboard_manager and AppHandle::clipboard_manager and JavaScript @tauri-apps/api/clipboard APIs have been removed. Use the @tauri-apps/plugin-clipboard-manager plugin instead:
[dependencies]
tauri-plugin-clipboard-manager = "2"
-
JavaScript
fn main() { tauri::Builder::default() .plugin(tauri_plugin_clipboard_manager::init()) }package.json
{ "dependencies": { "@tauri-apps/plugin-clipboard-manager": "^2.0.0" } }import { writeText, readText } from '@tauri-apps/plugin-clipboard-manager'; await writeText('Tauri is awesome!'); assert(await readText(), 'Tauri is awesome!'); -
Rust
use tauri_plugin_clipboard::{ClipboardExt, ClipKind}; tauri::Builder::default() .plugin(tauri_plugin_clipboard::init()) .setup(|app| { app.clipboard().write(ClipKind::PlainText { label: None, text: "Tauri is awesome!".into(), })?; Ok(()) })
Migrate to Dialog Plugin
The Rust tauri::api::dialog JavaScript @tauri-apps/api/dialog APIs have been removed. Use the @tauri-apps/plugin-dialog plugin instead:
- Add to cargo dependencies:
Cargo.toml
[dependencies]
tauri-plugin-dialog = "2"
- Use in JavaScript or Rust project:
-
JavaScript
fn main() { tauri::Builder::default() .plugin(tauri_plugin_dialog::init()) }package.json
{ "dependencies": { "@tauri-apps/plugin-dialog": "^2.0.0" } }import { save } from '@tauri-apps/plugin-dialog'; const filePath = await save({ filters: [ { name: 'Image', extensions: ['png', 'jpeg'], }, ], }); -
Rust
use tauri_plugin_dialog::DialogExt; tauri::Builder::default() .plugin(tauri_plugin_dialog::init()) .setup(|app| { app.dialog().file().pick_file(|file_path| { // do something with the optional file path here // the file path is `None` if the user closed the dialog }); app.dialog().message("Tauri is Awesome!").show(); Ok(()) })
Migrate to File System Plugin
The Rust tauri::api::file and JavaScript @tauri-apps/api/fs APIs have been removed. Use std::fs for Rust and the @tauri-apps/plugin-fs plugin for JavaScript instead:
- Add to cargo dependencies:
Cargo.toml
[dependencies]
tauri-plugin-fs = "2"
- Use in JavaScript or Rust project:
-
JavaScript
fn main() { tauri::Builder::default() .plugin(tauri_plugin_fs::init()) }package.json
{ "dependencies": { "@tauri-apps/plugin-fs": "^2.0.0" } }import { mkdir, BaseDirectory } from '@tauri-apps/plugin-fs'; await mkdir('db', { baseDir: BaseDirectory.AppLocalData });Some functions and types have been renamed or removed:
Direnum alias removed, useBaseDirectory.FileEntry,FsBinaryFileOption,FsDirOptions,FsOptions,FsTextFileOptionandBinaryFileContentsinterfaces and type aliases have been removed and replaced with new interfaces suited for each function.createDirrenamed tomkdir.readBinaryFilerenamed toreadFile.removeDirremoved and replaced withremove.removeFileremoved and replaced withremove.renameFileremoved and replaced withrename.writeBinaryFilerenamed towriteFile.
-
Rust
Use the Rust
std::fsfunctions.
Migrate to Global Shortcut Plugin
The Rust App::global_shortcut_manager and AppHandle::global_shortcut_manager and JavaScript @tauri-apps/api/global-shortcut APIs have been removed. Use the @tauri-apps/plugin-global-shortcut plugin instead:
- Add to cargo dependencies:
Cargo.toml
[dependencies]
[target."cfg(not(any(target_os = \"android\", target_os = \"ios\")))".dependencies]
tauri-plugin-global-shortcut = "2"
- Use in JavaScript or Rust project:
-
JavaScript
fn main() { tauri::Builder::default() .plugin(tauri_plugin_global_shortcut::Builder::default().build()) }package.json
{ "dependencies": { "@tauri-apps/plugin-global-shortcut": "^2.0.0" } }import { register } from '@tauri-apps/plugin-global-shortcut'; await register('CommandOrControl+Shift+C', () => { console.log('Shortcut triggered'); }); -
Rust
use tauri_plugin_global_shortcut::GlobalShortcutExt; tauri::Builder::default() .plugin( tauri_plugin_global_shortcut::Builder::new().with_handler(|app, shortcut| { println!("Shortcut triggered: {:?}", shortcut); }) .build(), ) .setup(|app| { // register a global shortcut // on macOS, the Cmd key is used // on Windows and Linux, the Ctrl key is used app.global_shortcut().register("CmdOrCtrl+Y")?; Ok(()) })
Migrate to HTTP Plugin
The Rust tauri::api::http JavaScript @tauri-apps/api/http APIs have been removed. Use the @tauri-apps/plugin-http plugin instead:
- Add to cargo dependencies:
Cargo.toml
[dependencies]
tauri-plugin-http = "2"
- Use in JavaScript or Rust project:
-
JavaScript
fn main() { tauri::Builder::default() .plugin(tauri_plugin_http::init()) }package.json
{ "dependencies": { "@tauri-apps/plugin-http": "^2.0.0" } }import { fetch } from '@tauri-apps/plugin-http'; const response = await fetch( 'https://raw.githubusercontent.com/tauri-apps/tauri/dev/package.json' ); -
Rust
use tauri_plugin_http::reqwest; tauri::Builder::default() .plugin(tauri_plugin_http::init()) .setup(|app| { let response_data = tauri::async_runtime::block_on(async { let response = reqwest::get( "https://raw.githubusercontent.com/tauri-apps/tauri/dev/package.json", ) .await .unwrap(); response.text().await })?; Ok(()) })The HTTP plugin re-exports reqwest so you can check out their documentation for more information.
Migrate to Notification Plugin
The Rust tauri::api::notification JavaScript @tauri-apps/api/notification APIs have been removed. Use the @tauri-apps/plugin-notification plugin instead:
- Add to cargo dependencies:
Cargo.toml
[dependencies]
tauri-plugin-notification = "2"
- Use in JavaScript or Rust project:
-
JavaScript
fn main() { tauri::Builder::default() .plugin(tauri_plugin_notification::init()) }package.json
{ "dependencies": { "@tauri-apps/plugin-notification": "^2.0.0" } }import { sendNotification } from '@tauri-apps/plugin-notification'; sendNotification('Tauri is awesome!'); -
Rust
use tauri_plugin_notification::NotificationExt; use tauri::plugin::PermissionState; fn main() { tauri::Builder::default() .plugin(tauri_plugin_notification::init()) .setup(|app| { if app.notification().permission_state()? == PermissionState::Unknown { app.notification().request_permission()?; } if app.notification().permission_state()? == PermissionState::Granted { app.notification() .builder() .body("Tauri is awesome!") .show()?; } Ok(()) }) }
Migrate to Menu Module
The Rust Menu APIs were moved to the tauri::menu module and refactored to use the muda crate.
Use tauri::menu::MenuBuilder
Use tauri::menu::MenuBuilder instead of tauri::Menu. Note that its constructor takes a Manager instance (one of App, AppHandle or WebviewWindow) as an argument:
use tauri::menu::MenuBuilder;
tauri::Builder::default()
.setup(|app| {
let menu = MenuBuilder::new(app)
.copy()
.paste()
.separator()
.undo()
.redo()
.text("open-url", "Open URL")
.check("toggle", "Toggle")
.icon("show-app", "Show App", app.default_window_icon().cloned().unwrap())
.build()?;
app.set_menu(menu);
Ok(())
})
Use tauri::menu::PredefinedMenuItem
Use tauri::menu::PredefinedMenuItem instead of tauri::MenuItem:
use tauri::menu::{MenuBuilder, PredefinedMenuItem};
tauri::Builder::default()
.setup(|app| {
let menu = MenuBuilder::new(app).item(&PredefinedMenuItem::copy(app)?).build()?;
Ok(())
})
Tip
The menu builder has dedicated methods to add each predefined menu item so you can call .copy() instead of .item(&PredefinedMenuItem::copy(app, None)?).
Use tauri::menu::MenuItemBuilder
Use tauri::menu::MenuItemBuilder instead of tauri::CustomMenuItem:
use tauri::menu::MenuItemBuilder;
tauri::Builder::default()
.setup(|app| {
let toggle = MenuItemBuilder::new("Toggle").accelerator("Ctrl+Shift+T").build(app)?;
Ok(())
})
Use tauri::menu::SubmenuBuilder
Use tauri::menu::SubmenuBuilder instead of tauri::Submenu:
use tauri::menu::{MenuBuilder, SubmenuBuilder};
tauri::Builder::default()
.setup(|app| {
let submenu = SubmenuBuilder::new(app, "Sub")
.text("Tauri")
.separator()
.check("Is Awesome")
.build()?;
let menu = MenuBuilder::new(app).item(&submenu).build()?;
Ok(())
})
tauri::Builder::menu now takes a closure because the menu needs a Manager instance to be built. See the documentation for more information.
Menu Events
The Rust tauri::Builder::on_menu_event API was removed. Use tauri::App::on_menu_event or tauri::AppHandle::on_menu_event instead:
use tauri::menu::{CheckMenuItemBuilder, MenuBuilder, MenuItemBuilder};
tauri::Builder::default()
.setup(|app| {
let toggle = MenuItemBuilder::with_id("toggle", "Toggle").build(app)?;
let check = CheckMenuItemBuilder::new("Mark").build(app)?;
let menu = MenuBuilder::new(app).items(&[&toggle, &check]).build()?;
app.set_menu(menu)?;
app.on_menu_event(move |app, event| {
if event.id() == check.id() {
println!("`check` triggered, do something! is checked? {}", check.is_checked().unwrap());
} else if event.id() == "toggle" {
println!("toggle triggered!");
}
});
Ok(())
})
Note that there are two ways to check which menu item was selected: move the item to the event handler closure and compare IDs, or define a custom ID for the item through the with_id constructor and use that ID string to compare.
Tip
Menu items can be shared across menus, and the menu event is bound to a menu item instead of a menu or window. If you don’t want all listeners to be triggered when a menu item is selected, do not share menu items and use dedicated instances instead, that you could move into tauri::WebviewWindow/WebviewWindowBuilder::on_menu_event closure.
Migrate to OS Plugin
The Rust tauri::api::os JavaScript @tauri-apps/api/os APIs have been removed. Use the @tauri-apps/plugin-os plugin instead:
- Add to cargo dependencies:
Cargo.toml
[dependencies]
tauri-plugin-os = "2"
- Use in JavaScript or Rust project:
-
JavaScript
fn main() { tauri::Builder::default() .plugin(tauri_plugin_os::init()) }package.json
{ "dependencies": { "@tauri-apps/plugin-os": "^2.0.0" } }import { arch } from '@tauri-apps/plugin-os'; const architecture = await arch(); -
Rust
fn main() { tauri::Builder::default() .plugin(tauri_plugin_os::init()) .setup(|app| { let os_arch = tauri_plugin_os::arch(); Ok(()) }) }
Migrate to Process Plugin
The Rust tauri::api::process JavaScript @tauri-apps/api/process APIs have been removed. Use the @tauri-apps/plugin-process plugin instead:
- Add to cargo dependencies:
Cargo.toml
[dependencies]
tauri-plugin-process = "2"
- Use in JavaScript or Rust project:
-
JavaScript
fn main() { tauri::Builder::default() .plugin(tauri_plugin_process::init()) }package.json
{ "dependencies": { "@tauri-apps/plugin-process": "^2.0.0" } }import { exit, relaunch } from '@tauri-apps/plugin-process'; await exit(0); await relaunch(); -
Rust
fn main() { tauri::Builder::default() .plugin(tauri_plugin_process::init()) .setup(|app| { // exit the app with a status code app.handle().exit(1); // restart the app app.handle().restart(); Ok(()) }) }
Migrate to Shell Plugin
The Rust tauri::api::shell JavaScript @tauri-apps/api/shell APIs have been removed. Use the @tauri-apps/plugin-shell plugin instead:
- Add to cargo dependencies:
Cargo.toml
[dependencies]
tauri-plugin-shell = "2"
- Use in JavaScript or Rust project:
-
JavaScript
fn main() { tauri::Builder::default() .plugin(tauri_plugin_shell::init()) }package.json
{ "dependencies": { "@tauri-apps/plugin-shell": "^2.0.0" } }import { Command, open } from '@tauri-apps/plugin-shell'; const output = await Command.create('echo', 'message').execute(); await open('https://github.com/tauri-apps/tauri'); -
Rust
- Open an URL
use tauri_plugin_shell::ShellExt; fn main() { tauri::Builder::default() .plugin(tauri_plugin_shell::init()) .setup(|app| { app.shell().open("https://github.com/tauri-apps/tauri", None)?; Ok(()) }) }- Spawn a child process and retrieve the status code
use tauri_plugin_shell::ShellExt; fn main() { tauri::Builder::default() .plugin(tauri_plugin_shell::init()) .setup(|app| { let status = tauri::async_runtime::block_on(async move { app.shell().command("which").args(["ls"]).status().await.unwrap() }); println!("`which` finished with status: {:?}", status.code()); Ok(()) }) }- Spawn a child process and capture its output
use tauri_plugin_shell::ShellExt; fn main() { tauri::Builder::default() .plugin(tauri_plugin_shell::init()) .setup(|app| { let output = tauri::async_runtime::block_on(async move { app.shell().command("echo").args(["TAURI"]).output().await.unwrap() }); assert!(output.status.success()); assert_eq!(String::from_utf8(output.stdout).unwrap(), "TAURI"); Ok(()) }) }- Spawn a child process and read its events asynchronously:
use tauri_plugin_shell::{ShellExt, process::CommandEvent}; fn main() { tauri::Builder::default() .plugin(tauri_plugin_shell::init()) .setup(|app| { let handle = app.handle().clone(); tauri::async_runtime::spawn(async move { let (mut rx, mut child) = handle.shell().command("cargo") .args(["tauri", "dev"]) .spawn() .expect("Failed to spawn cargo"); let mut i = 0; while let Some(event) = rx.recv().await { if let CommandEvent::Stdout(line) = event { println!("got: {}", String::from_utf8(line).unwrap()); i += 1; if i == 4 { child.write("message from Rust\n".as_bytes()).unwrap(); i = 0; } } } }); Ok(()) }) }
Migrate to Tray Icon Module
The Rust SystemTray APIs were renamed to TrayIcon for consistency. The new APIs can be found in the Rust tray module.
Use tauri::tray::TrayIconBuilder
Use tauri::tray::TrayIconBuilder instead of tauri::SystemTray:
let tray = tauri::tray::TrayIconBuilder::with_id("my-tray").build(app)?;
See TrayIconBuilder for more information.
Migrate to Menu
Use tauri::menu::Menu instead of tauri::SystemTrayMenu, tauri::menu::Submenu instead of tauri::SystemTraySubmenu and tauri::menu::PredefinedMenuItem instead of tauri::SystemTrayMenuItem.
Tray Events
tauri::SystemTray::on_event have been split into tauri::tray::TrayIconBuilder::on_menu_event and tauri::tray::TrayIconBuilder::on_tray_icon_event:
use tauri::{
menu::{MenuBuilder, MenuItemBuilder},
tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent},
};
tauri::Builder::default()
.setup(|app| {
let toggle = MenuItemBuilder::with_id("toggle", "Toggle").build(app)?;
let menu = MenuBuilder::new(app).items(&[&toggle]).build()?;
let tray = TrayIconBuilder::new()
.menu(&menu)
.on_menu_event(move |app, event| match event.id().as_ref() {
"toggle" => {
println!("toggle clicked");
}
_ => (),
})
.on_tray_icon_event(|tray, event| {
if let TrayIconEvent::Click {
button: MouseButton::Left,
button_state: MouseButtonState::Up,
..
} = event
{
let app = tray.app_handle();
if let Some(webview_window) = app.get_webview_window("main") {
let _ = webview_window.unminimize();
let _ = webview_window.show();
let _ = webview_window.set_focus();
}
}
})
.build(app)?;
Ok(())
})
Migrate to Updater Plugin
Change of default behavior
The built-in dialog with an automatic update check was removed, use the Rust and JS APIs to check for and install updates instead. Failing to do so will prevent your users from getting further updates!
The Rust tauri::updater and JavaScript @tauri-apps/api-updater APIs have been removed. To set a custom updater target with the @tauri-apps/plugin-updater:
- Add to cargo dependencies:
[dependencies]
tauri-plugin-updater = "2"
- Use in JavaScript or Rust project:
-
JavaScript
fn main() { tauri::Builder::default() .plugin(tauri_plugin_updater::Builder::new().build()) }package.json
{ "dependencies": { "@tauri-apps/plugin-updater": "^2.0.0" } }import { check } from '@tauri-apps/plugin-updater'; import { relaunch } from '@tauri-apps/plugin-process'; const update = await check(); if (update?.available) { console.log(`Update to ${update.version} available! Date: ${update.date}`); console.log(`Release notes: ${update.body}`); await update.downloadAndInstall(); // requires the `process` plugin await relaunch(); } -
Rust
To check for updates:
use tauri_plugin_updater::UpdaterExt; fn main() { tauri::Builder::default() .plugin(tauri_plugin_updater::Builder::new().build()) .setup(|app| { let handle = app.handle(); tauri::async_runtime::spawn(async move { let response = handle.updater().check().await; }); Ok(()) }) }To set a custom updater target:
fn main() { let mut updater = tauri_plugin_updater::Builder::new(); #[cfg(target_os = "macos")] { updater = updater.target("darwin-universal"); } tauri::Builder::default() .plugin(updater.build()) }
Migrate Path to Tauri Manager
The Rust tauri::api::path module functions and tauri::PathResolver have been moved to tauri::Manager::path:
use tauri::{path::BaseDirectory, Manager};
tauri::Builder::default()
.setup(|app| {
let home_dir_path = app.path().home_dir().expect("failed to get home dir");
let path = app.path().resolve("path/to/something", BaseDirectory::Config)?;
Ok(())
})
Migrate to new Window API
On the Rust side, Window was renamed to WebviewWindow, its builder WindowBuilder is now named WebviewWindowBuilder and WindowUrl is now named WebviewUrl.
Additionally, the Manager::get_window function was renamed to get_webview_window and the window’s parent_window API was renamed to parent_raw to support a high level window parent API.
On the JavaScript side, the WebviewWindow class is now exported in the @tauri-apps/api/webviewWindow path.
The onMenuClicked function was removed, you can intercept menu events when creating a menu in JavaScript instead.
Migrate Embedded Additional Files (Resources)
On the JavaScript side, make sure you Migrate to File System Plugin. Additionally, note the changes made to the v1 allowlist in Migrate Permissions.
On the Rust side, make sure you Migrate Path to Tauri Manager.
Migrate Embedded External Binaries (Sidecar)
In Tauri v1, the external binaries and their arguments were defined in the allowlist. In v2, use the new permissions system. Read Migrate Permissions for more information.
On the JavaScript side, make sure you Migrate to Shell Plugin.
On the Rust side, tauri::api::process API has been removed. Use tauri_plugin_shell::ShellExt and tauri_plugin_shell::process::CommandEvent APIs instead. Read the Embedding External Binaries guide to see how.
The “process-command-api” features flag has been removed in v2. So running the external binaries does not require this feature to be defined in the Tauri config anymore.
Migrate Permissions
The v1 allowlist have been rewritten to a completely new system for permissions that works for individual plugins and is much more configurable for multiwindow and remote URL support. This new system works like an access control list (ACL) where you can allow or deny commands, allocate permissions to a specific set of windows and domains, and define access scopes.
To enable permissions for your app, you must create capability files inside the src-tauri/capabilities folder, and Tauri will automatically configure everything else for you.
The migrate CLI command automatically parses your v1 allowlist and generates the associated capability file.
To learn more about permissions and capabilities, see the security documentation.
Upgrade from Tauri 2.0 Beta
This guide walks you through upgrading your Tauri 2.0 beta application to Tauri 2.0 release candidate.
Automated Migration
The Tauri v2 CLI includes a migrate command that automates most of the process and helps you finish the migration:
-
npm
npm install @tauri-apps/cli@latest npm run tauri migrate -
yarn
yarn upgrade @tauri-apps/cli@latest yarn tauri migrate -
pnpm
pnpm update @tauri-apps/cli@latest pnpm tauri migrate -
cargo
cargo install tauri-cli --version "^2.0.0" --locked cargo tauri migrate
Learn more about the migrate command in the Command Line Interface reference
Breaking Changes
We have had several breaking changes going from beta to release candidate. These can be either auto-migrated (see above) or manually performed.
Tauri Core Plugins
We changed how Tauri built-in plugins are addressed in the capabilities PR #10390.
To migrate from the latest beta version you need to prepend all core permission identifiers in your capabilities with core: or switch to the core:default permission and remove old core plugin identifiers.
...
"permissions": [
"path:default",
"event:default",
"window:default",
"app:default",
"image:default",
"resources:default",
"menu:default",
"tray:default",
]
...
...
"permissions": [
"core:path:default",
"core:event:default",
"core:window:default",
"core:app:default",
"core:image:default",
"core:resources:default",
"core:menu:default",
"core:tray:default",
]
...
We also added a new special core:default permission set which will contain all default permissions of all core plugins, so you can simplify the permissions boilerplate in your capabilities config.
...
"permissions": [
"core:default"
]
...
Built-In Development Server
We introduced changes to the network exposure of the built-in development server PR #10437 and PR #10456.
The built-in mobile development server no longer exposes network wide and tunnels traffic from the local machine directly to the device.
Currently this improvement does not automatically apply when running on iOS devices (either directly or from Xcode). In this case we default to using the public network address for the development server, but there’s a way around it which involves opening Xcode to automatically start a connection between your macOS machine and your connected iOS device, then running tauri ios dev --force-ip-prompt to select the iOS device’s TUN address (ends with ::2).
Your development server configuration needs to adapt to this change if running on a physical iOS device is intended. Previously we recommended checking if the TAURI_ENV_PLATFORM environment variable matches either android or ios, but since we can now connect to localhost unless using an iOS device, you should instead check the TAURI_DEV_HOST environment variable. Here’s an example of a Vite configuration migration:
- 2.0.0-beta:
import { defineConfig } from 'vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';
import { internalIpV4Sync } from 'internal-ip';
const mobile = !!/android|ios/.exec(process.env.TAURI_ENV_PLATFORM);
export default defineConfig({
plugins: [svelte()],
clearScreen: false,
server: {
host: mobile ? '0.0.0.0' : false,
port: 1420,
strictPort: true,
hmr: mobile
? {
protocol: 'ws',
host: internalIpV4Sync(),
port: 1421,
}
: undefined,
},
});
- 2.0.0:
import { defineConfig } from 'vite';
import Unocss from 'unocss/vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';
const host = process.env.TAURI_DEV_HOST;
export default defineConfig({
plugins: [svelte()],
clearScreen: false,
server: {
host: host || false,
port: 1420,
strictPort: true,
hmr: host
? {
protocol: 'ws',
host: host,
port: 1430,
}
: undefined,
},
});
Note
The internal-ip NPM package is no longer required, you can directly use the TAURI_DEV_HOST value instead.
Prerequisites
In order to get started building your project with Tauri you’ll first need to install a few dependencies:
- System Dependencies
- Rust
- Configure for Mobile Targets (only required if developing for mobile)
System Dependencies
Follow the link to get started for your respective operating system:
- Linux (see below for specific distributions)
- macOS Catalina (10.15) and later
- Windows 7 and later
Linux
Tauri requires various system dependencies for development on Linux. These may be different depending on your distribution but we’ve included some popular distributions below to help you get setup.
-
Debian
sudo apt update sudo apt install libwebkit2gtk-4.1-dev \ build-essential \ curl \ wget \ file \ libxdo-dev \ libssl-dev \ libayatana-appindicator3-dev \ librsvg2-dev -
Arch
sudo pacman -Syu sudo pacman -S --needed \ webkit2gtk-4.1 \ base-devel \ curl \ wget \ file \ openssl \ appmenu-gtk-module \ libappindicator-gtk3 \ librsvg \ xdotool -
Fedora
sudo dnf check-update sudo dnf install webkit2gtk4.1-devel \ openssl-devel \ curl \ wget \ file \ libappindicator-gtk3-devel \ librsvg2-devel \ libxdo-devel sudo dnf group install "c-development" -
Gentoo
sudo emerge --ask \ net-libs/webkit-gtk:4.1 \ dev-libs/libayatana-appindicator \ net-misc/curl \ net-misc/wget \ sys-apps/file -
OSTree
sudo rpm-ostree install webkit2gtk4.1-devel \ openssl-devel \ curl \ wget \ file \ libappindicator-gtk3-devel \ librsvg2-devel \ libxdo-devel \ gcc \ gcc-c++ \ make sudo systemctl reboot -
openSUSE
sudo zypper up sudo zypper in webkit2gtk3-devel \ libopenssl-devel \ curl \ wget \ file \ libappindicator3-1 \ librsvg-devel sudo zypper in -t pattern devel_basis -
Alpine
sudo apk add \ build-base \ webkit2gtk-4.1-dev \ curl \ wget \ file \ openssl \ libayatana-appindicator-dev \ librsvgNote: Alpine Linux containers don’t include any fonts by default. To ensure text renders correctly in your Tauri app, install at least one font package (for example,
font-dejavu). -
NixOS
Note
Instructions for Nix/NixOS can be found in the NixOS Wiki.
If your distribution isn’t included above then you may want to check Awesome Tauri on GitHub to see if a guide has been created.
Next: Install Rust
macOS
Tauri uses Xcode and various macOS and iOS development dependencies.
Download and install Xcode from one of the following places:
Be sure to launch Xcode after installing so that it can finish setting up.
Only developing for desktop targets?
If you’re only planning to develop desktop apps and not targeting iOS then you can install Xcode Command Line Tools instead:
xcode-select --install
Next: Install Rust
Windows
Tauri uses the Microsoft C++ Build Tools for development as well as Microsoft Edge WebView2. These are both required for development on Windows.
Follow the steps below to install the required dependencies.
Microsoft C++ Build Tools
- Download the Microsoft C++ Build Tools installer and open it to begin installation.
- During installation check the “Desktop development with C++” option.
Next: Install WebView2.
WebView2
Tip
WebView 2 is already installed on Windows 10 (from version 1803 onward) and later versions of Windows. If you are developing on one of these versions then you can skip this step and go directly to installing Rust.
Tauri uses Microsoft Edge WebView2 to render content on Windows.
Install WebView2 by visiting the WebView2 Runtime download section. Download the “Evergreen Bootstrapper” and install it.
Next: Check VBSCRIPT
VBSCRIPT (for MSI installers)
MSI package building only
This is only required if you plan to build MSI installer packages ("targets": "msi" or "targets": "all" in tauri.conf.json).
Building MSI packages on Windows requires the VBSCRIPT optional feature to be enabled. This feature is enabled by default on most Windows installations, but may have been disabled on some systems.
If you encounter errors like failed to run light.exe when building MSI packages, you may need to enable the VBSCRIPT feature:
- Open Settings → Apps → Optional features → More Windows features
- Locate VBSCRIPT in the list and ensure it’s checked
- Click Next and restart your computer if prompted
Note: VBSCRIPT is currently enabled by default on most Windows installations, but is being deprecated and may be disabled in future Windows versions.
Next: Install Rust
Rust
Tauri is built with Rust and requires it for development. Install Rust using one of following methods. You can view more installation methods at https://www.rust-lang.org/tools/install.
-
Linux and macOS
Install via
rustupusing the following command:curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | shSecurity Tip
We have audited this bash script, and it does what it says it is supposed to do. Nevertheless, before blindly curl-bashing a script, it is always wise to look at it first.
Here is the file as a plain script: rustup.sh
-
Windows
Visit https://www.rust-lang.org/tools/install to install
rustup.Alternatively, you can use
wingetto install rustup using the following command in PowerShell:winget install --id Rustlang.RustupMSVC toolchain as default
For full support for Tauri and tools like
trunkmake sure the MSVC Rust toolchain is the selecteddefault host triplein the installer dialog. Depending on your system it should be eitherx86_64-pc-windows-msvc,i686-pc-windows-msvc, oraarch64-pc-windows-msvc.If you already have Rust installed, you can make sure the correct toolchain is installed by running this command:
rustup default stable-msvc
Be sure to restart your Terminal (and in some cases your system) for the changes to take effect.
Next: Configure for Mobile Targets if you’d like to build for Android and iOS, or, if you’d like to use a JavaScript framework, install Node. Otherwise Create a Project.
Node.js
JavaScript ecosystem
Only if you intend to use a JavaScript frontend framework
- Go to the Node.js website, download the Long Term Support (LTS) version and install it.
- Check if Node was successfully installed by running:
node -v
# v20.10.0
npm -v
# 10.2.3
It’s important to restart your Terminal to ensure it recognizes the new installation. In some cases, you might need to restart your computer.
While npm is the default package manager for Node.js, you can also use others like pnpm or yarn. To enable these, run corepack enable in your Terminal. This step is optional and only needed if you prefer using a package manager other than npm.
Next: Configure for Mobile Targets or Create a project.
Configure for Mobile Targets
If you’d like to target your app for Android or iOS then there are a few additional dependencies that you need to install:
Android
- Download and install Android Studio from the Android Developers website
- Set the
JAVA_HOMEenvironment variable:
-
Linux
export JAVA_HOME=/opt/android-studio/jbr -
macOS
export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home" -
Windows
[System.Environment]::SetEnvironmentVariable("JAVA_HOME", "C:\Program Files\Android\Android Studio\jbr", "User")
- Use the SDK Manager in Android Studio to install the following:
- Android SDK Platform
- Android SDK Platform-Tools
- NDK (Side by side)
- Android SDK Build-Tools
- Android SDK Command-line Tools
Selecting “Show Package Details” in the SDK Manager enables the installation of older package versions. Only install older versions if necessary, as they may introduce compatibility issues or security risks.
- Set
ANDROID_HOMEandNDK_HOMEenvironment variables.
-
Linux
export ANDROID_HOME="$HOME/Android/Sdk" export NDK_HOME="$ANDROID_HOME/ndk/$(ls -1 $ANDROID_HOME/ndk)" -
macOS
export ANDROID_HOME="$HOME/Library/Android/sdk" export NDK_HOME="$ANDROID_HOME/ndk/$(ls -1 $ANDROID_HOME/ndk)" -
Windows
[System.Environment]::SetEnvironmentVariable("ANDROID_HOME", "$env:LocalAppData\Android\Sdk", "User") $VERSION = Get-ChildItem -Name "$env:LocalAppData\Android\Sdk\ndk" | Select-Object -Last 1 [System.Environment]::SetEnvironmentVariable("NDK_HOME", "$env:LocalAppData\Android\Sdk\ndk\$VERSION", "User")Tip
Most apps don’t refresh their environment variables automatically, so to let them pickup the changes, you can either restart your terminal and IDE or for your current PowerShell session, you can refresh it with
[System.Environment]::GetEnvironmentVariables("User").GetEnumerator() | % { Set-Item -Path "Env:\$($_.key)" -Value $_.value }
- Add the Android targets with
rustup:
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android
Next: Setup for iOS or Create a project.
iOS
macOS Only
iOS development requires Xcode and is only available on macOS. Be sure that you’ve installed Xcode and not Xcode Command Line Tools in the macOS system dependencies section.
- Add the iOS targets with
rustupin Terminal:
rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim
- Install Homebrew:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
- Install Cocoapods using Homebrew:
brew install cocoapods
Next: Create a project.
Troubleshooting
If you run into any issues during installation be sure to check the Troubleshooting Guide or reach out on the Tauri Discord.
Next Steps
Now that you’ve installed all of the prerequisites you’re ready to create your first Tauri project!
Project Structure
A Tauri project is usually made of 2 parts, a Rust project and a JavaScript project (optional), and typically the setup looks something like this:
.
├── package.json
├── index.html
├── src/
│ ├── main.js
├── src-tauri/
│ ├── Cargo.toml
│ ├── Cargo.lock
│ ├── build.rs
│ ├── tauri.conf.json
│ ├── src/
│ │ ├── main.rs
│ │ └── lib.rs
│ ├── icons/
│ │ ├── icon.png
│ │ ├── icon.icns
│ │ └── icon.ico
│ └── capabilities/
│ └── default.json
In this case, the JavaScript project is at the top level, and the Rust project is inside src-tauri/, the Rust project is a normal Cargo project with some extra files:
tauri.conf.jsonis the main configuration file for Tauri, it contains everything from the application identifier to dev server url, this file is also a marker for the Tauri CLI to find the Rust project, to learn more about it, see Tauri Configcapabilities/directory is the default folder Tauri reads capability files from (in short, you need to allow commands here to use them in your JavaScript code), to learn more about it, see Securityicons/directory is the default output directory of thetauri iconcommand, it’s usually referenced intauri.conf.json > bundle > iconand used for the app’s iconsbuild.rscontainstauri_build::build()which is used for tauri’s build systemsrc/lib.rscontains the Rust code and the mobile entry point (the function marked with#[cfg_attr(mobile, tauri::mobile_entry_point)]), the reason we don’t write directly inmain.rsis because we compile your app to a library in mobile builds and load them through the platform frameworkssrc/main.rsis the main entry point for the desktop, and we runapp_lib::run()inmainto use the same entry point as mobile, so to keep it simple, don’t modify this file, modifylib.rsinstead. Note thatapp_libcorresponds to[lib.name]in Cargo.toml.
Tauri works similar to a static web host, and the way it builds is that you would compile your JavaScript project to static files first, and then compile the Rust project that will bundle those static files in, so the JavaScript project setup is basically the same as if you were to build a static website, to learn more, see Frontend Configuration
If you want to work with Rust code only, simply remove everything else and use the src-tauri/ folder as your top level project or as a member of your Rust workspace
Next Steps
- Add and Configure a Frontend Framework
- Tauri Command Line Interface (CLI) Reference
- Learn how to develop your Tauri app
- Discover additional features to extend Tauri
404
Page not found. Check the URL or try using the search bar.
If you're having trouble navigating, please create an issue on GitHub or report on Discord.
About Tauri
Various information about Tauri from governance, philosophy, and trademark guidelines
Tip
If you’re looking for a quick technical overview and to start building an app then visit the What is Tauri page. If you’d like to learn more about the project’s philosophy then keep reading.
Tauri PhilosophyLearn more about the approach behind Tauri
GovernanceUnderstand how the Tauri governance structure is setup
TrademarkGuidelines for using the Tauri trademark
The Tauri Book
Progress Update
We’re actively working on authoring and writing The Tauri Book. We’ve encountered delays due to the immense growth of Tauri but have recently re-prioritized this project. While we don’t yet have details on the timelines of a release, you can keep an eye on this page for updates.
We’d like to apologize for this being delayed beyond the originally communicated publish date. If you’ve donated through GitHub Sponsors or Open Collective and would like to request a refund you may do so via Open Collective: Contact Tauri on Open Collective.
Overview
The Tauri Book will guide you through the history of Tauri and the design decisions we’ve made. It will also talk in depth about why privacy, security and sustainability are important and fundamental discussions you can apply to any modern software project.
Topics included are:
- The method and reasoning behind the design of Tauri
- The options you have when building with Tauri
- That you don’t have to choose between shipping fast and being sustainable and responsible
- Why we chose the Rust language as a binding and application layer for Tauri
- Why a binary review is important
History
In 2020, the manufacture of native-apps has become easier and more accessible than ever before. All the same, beginners and seasoned developers alike are confronted with tough choices in a rapidly changing landscape of security and privacy. This is especially true in the semi-trusted environment of user devices.
Tauri takes the guesswork out of the equation, as it was designed from the ground up to embrace new paradigms of secure development and creative flexibility that leverage the language features of Rust and lets you build an app using any frontend framework you like. Find out how you can design, build, audit and deploy tiny, fast, robust, and secure native applications for the major desktop and mobile platforms, all from the exact same codebase and in record time - without even needing to know the Rust programming language.
Authors and Tauri co-founders Daniel and Lucas take you on a journey from theory to execution, during which you will learn why Tauri was built and how it works under the hood. Together with guest insights that specialize in Open Source, DevOps, Security and Enterprise Architecture, this book also presents discourse-formatted philosophical discussions and open-source sustainability viewpoints from which your next-gen apps will profit - and your users will benefit.
Tauri Governance
One of the main goals of the organizational structure of Tauri is to guarantee we stay true to our open source values and do so sustainably while respecting the health and well-being of contributors. The Tauri Programme within the Commons Conservancy was established to commit to those values, and facilitate an open, transparent and efficient governance process throughout the future development of the Tauri and its auxiliary materials.
Tauri Working Group
The Tauri Working Group is the collective framework created to enable this governance process. It’s composed of the following components:
- Working Group Members
- Tauri Board & Board Directors
- Domains & Domain Leads
- Teams
Working Group Members
All of the individuals that make up the Tauri Working Group.
Tauri Board & Board Directors
The Tauri Board is the central decision making body for the Tauri Programme and is responsible for the overall health and stability of the Tauri Programme. The Board votes on major decisions within the Programme and issues raised by the Working Group.
An individual Board Director may be a technical contributor, be a stakeholder in Tauri’s future, share experience from the industry, or have a passion for regulatory and legal aspects within Open Source.
Domains & Domain Leads
Domains are organizational units that represent an area of interest within Tauri.
Domain Leads are trusted contributors within the Tauri community with expertise in the Domain they are leading. They are responsible for setting direction, overseeing and supporting the activities within that Domain.
The current Domains and Domain leads are outlined in the Governance and Guidance repo on GitHub.
Teams
Teams are small groups of contributors that support or maintain specific areas of the Tauri Programme. They are a means for Tauri to execute its longer-term tasks and goals, especially when ad-hoc contributions cannot achieve the same results.
Get Involved
If you’re interested in becoming a Tauri Board Director or a Domain Lead, elections for those positions are run throughout the year. For Domain Leads those take place in both the spring and fall and for Board Directors in the summer. Instructions for how to apply are posted to the Tauri Blog leading up to the respective election.
Additional Resources
- Governance and Guidance Repository: More detailed information about Tauri’s Governance and the current Domains and Domain Leads
- Social Contract: The social contract informs our decision making and organization
- Code of Conduct
- Tauri Programme Statutes
Tauri Philosophy
Tauri is a toolkit that helps developers make applications for the major desktop platforms - using virtually any frontend framework in existence. The core is built with Rust, and the CLI leverages Node.js making Tauri a genuinely polyglot approach to creating and maintaining great apps.
Security First
In today’s world, every honest threat model assumes that the user’s device has already been compromised. This puts app developers in a complicated situation because if the device is already at risk, how can the software be trusted?
Defense in depth is the approach we’ve taken. We want you to be able to take every precaution possible to minimize the surface area you present to attackers. Tauri lets you choose which API endpoints to ship, whether or not you want a localhost server built into your app, and it even randomizes functional handles at runtime. These and other techniques form a secure baseline that empowers you and your users.
Slowing down attackers by making static attacks crushingly difficult and isolating systems from one another is the name of the game. And if you are coming from the Electron ecosystem - rest assured - by default Tauri only ships binaries, not ASAR files.
By choosing to build Tauri with security as a guiding force, we give you every opportunity to take a proactive security posture.
Polyglots, not Silos
Most contemporary frameworks use a single language paradigm and are therefore trapped in a bubble of knowledge and idiom. This can work well for certain niche applications, but it also fosters a kind of tribalism.
This can be seen in the way that the React, Angular, and Vue development communities huddle on their stacks, ultimately breeding very little cross-pollination.
This same situation can be seen in the Rust vs. Node vs. C++ battlefields, where hardliners take their stances and refuse to collaborate across communities.
Today, Tauri uses Rust for the backend - but in the not too distant future, other backends like Go, Nim, Python, Csharp, etc. will be possible. This is because we are maintaining the official Rust bindings to the webview organization and plan to let you switch out the backend for your needs. Since our API can be implemented in any language with C interop, full compliance is only a PR away.
Honest Open Source
None of this would make any sense without a community. Today software communities are amazing places where people help each other and make awesome things - open source is a very big part of that.
Open source means different things to different people, but most will agree that it serves to support freedom. When software doesn’t respect your rights, then it can seem unfair and potentially compromise your freedoms by operating in unethical ways.
This is why we are proud that FLOSS advocates can build applications with Tauri that are “certifiably” open source and can be included in FSF endorsed GNU/Linux distributions.
The Future
Tauri’s future depends on your involvement and contributions. Try it out, file issues, join a working group or make a donation - every contribution is important. Please, at any rate, do get in touch!!!
Trademark Guidelines
This trademark policy was prepared to help you understand how to use the TAURI trademarks, service marks and logos owned by the Tauri Programme within the Commons Conservancy.
While our software is available under a free and open source software license, that copyright license does not include a license to use our trademark, and this Policy is intended to explain how to use our marks consistent with background law and community expectation.
This Policy covers:
- Our word trademarks and service marks: TAURI, TAO, WRY
- Our logos: The TAURI, TAO, WRY logos (and all visual derivatives)
This policy encompasses all trademarks and service marks, whether they are registered or not.
General Guidelines
Whenever you use one of our marks, you must always do so in a way that does not mislead anyone about what they are getting and from whom. For example, you cannot say you are distributing TAURI software when you’re distributing a modified version of it (aka a Fork), because recipients may not understand the differences between your modified versions and our own.
You also cannot use our logo on your website in a way that suggests that your website is an official website or that we endorse your website.
You can, though, say you like TAURI software, that you participate in the TAURI community, that you are providing an unmodified version of the TAURI software.
You may not use or register our marks, or variations of them as part of your own trademark, service mark, domain name, company name, trade name, product name or service name.
Trademark law does not allow your use of names or trademarks that are too similar to ours. You therefore may not use an obvious variation of any of our marks or any phonetic equivalent, foreign language equivalent, takeoff, or abbreviation for a similar or compatible product or service. We would consider the following too similar to one of our Marks:
- TAURIMAGE
- Tauri Wallet App
Acceptable Uses
Applications
TAURI is a framework for making applications for computing devices. You may claim that your application uses TAURI, but care should be taken to avoid giving the impression that your application is approved by The Tauri Programme within the Commons Conservancy, or is an official application. Care must be taken, not to ship your application with the default ICON.
Plugins & Templates
You may publish the code for plugins and templates using the appropriate naming conventions, but please mention that these works are not officially approved. Only such codebases that are managed by the organization within the GitHub organization tauri-apps are considered official.
Core Modifications (Forks)
If you distribute a modified version of our software (TAURI CORE), you must remove all of our logos and naming from it. You must retain our original license in SPDX format. You may use our word marks, but not our logos, to truthfully describe the origin of the software that you are providing. For example, if the code you are distributing is a modification of our software, you may say, “This software is derived from the source code for TAURI software.”
Statements About Compatibility
You may use the word marks, but not the logos, to truthfully describe the relationship between your software and ours. Any other use may imply that we have certified or approved your software. If you wish to use our logos, please contact us to discuss license terms.
Naming Compatible Products
If you wish to describe your product with reference to the TAURI software, here are the conditions under which you may do so. You may call your software XYZ (where XYZ is your product name) for TAURI only if:
- All versions of the TAURI software you deliver with your product are the exact binaries provided by us, or manufactured by the core software and tooling we provide.
- Your product is fully compatible with the APIs for the TAURI software.
- You use the following legend in marketing materials or product descriptions: “TAURI is a trademark of The Tauri Programme within the Commons Conservancy. https://tauri.app/ ”
User Groups
You can use the Word Marks as part of your user group name provided that:
- The main focus of the group is our software
- The group does not make a profit
- Any charge to attend meetings are to cover the cost of the venue, food and drink only
You are not authorized to conduct a conference using our marks.
No Domain Names
You must not register any domain that includes our word marks or any variant or combination of them.
Other For Profit Usage of the TAURI Marks
If you are making a video, tutorial series, book, or other educational material, for which you are receiving payment through subscriptions, sales, advertising or the like, then you must acquire explicit licensing permission from The Tauri Programme within the Commons Conservancy.
How to Display Our Marks
When you have the right to use our mark, here is how to display it.
Trademark Marking and Legends
The first or most prominent mention of a mark on a webpage, document, or documentation should be accompanied by a symbol indicating whether the mark is a registered trademark (“®”) or an unregistered trademark (“™”). If you don’t know which applies, contact us. (TAURI itself is a registered trademark.)
Place the following notice at the foot of the page where you have used the mark: TAURI is trademark of [The Tauri Programme within the Commons Conservancy].”
Use of Trademarks in Text
Always use trademarks in their exact form with the correct spelling, neither abbreviated, hyphenated, or combined with any other word or words.
- Unacceptable: TAUREE
- Acceptable: TAURI
Don’t pluralize a trademark.
- Unacceptable: I have seventeen TAURIs running on my computer.
- Acceptable: I am running seventeen TAURI applications on my computer and have ram to spare.
Always use a trademark as an adjective modifying a noun.
- Unacceptable: This is a TAURI.
- Acceptable: This is a TAURI software application.
Use of Logos
You may not change any logo except to scale it. This means you may not add decorative elements, change the colors, change the proportions, distort it, add elements, or combine it with other logos.
We have a high-contrast version of the logo, which you can download below in the assets section.
Assets
- Here you may download the entire Brand Guidelines - (PDF, 74.3 MB)
- Here you may download SVG and PNG formats of the LOGO and Wordmark in the Logopack - (ZIP, 203 KB)
The Tauri Programme within the Commons Conservancy retains all rights to the modification of these trademark guidelines at any time. If you have a question or enquiry, please send an email to trademark@tauri.app.
These guidelines are based on the Model Trademark Guidelines, available at http://www.modeltrademarkguidelines.org, used under a Creative Commons Attribution 3.0 Unported license: https://creativecommons.org/licenses/by/3.0/deed.en_EU. Version 1.0 dated 20th, August 2022
Core Concepts
Topics that you should get more intimately familiar with if you want to get the most out of the framework
Tauri has a variety of topics that are considered to be core concepts, things any developer should be aware of when developing their applications. Here’s a variety of topics that you should get more intimately familiar with if you want to get the most out of the framework.
Tauri ArchitectureArchitecture and ecosystem.
Inter-Process Communication (IPC)The inner workings on the IPC.
SecurityHow Tauri enforces security practices.
Process ModelWhich processes Tauri manages and why.
App SizeHow to make your app as small as possible.
Tauri Architecture
Introduction
Tauri is a polyglot and generic toolkit that is very composable and allows engineers to make a wide variety of applications. It is used for building applications for desktop computers using a combination of Rust tools and HTML rendered in a Webview. Apps built with Tauri can ship with any number of pieces of an optional JS API and Rust API so that webviews can control the system via message passing. Developers can extend the default API with their own functionality and bridge the Webview and Rust-based backend easily.
Tauri apps can have tray-type interfaces. They can be updated and are managed by the user’s operating system as expected. They are very small because they use the OS’s webview. They do not ship a runtime since the final binary is compiled from Rust. This makes the reversing of Tauri apps not a trivial task.
What Tauri is Not
Tauri is not a lightweight kernel wrapper. Instead, it directly uses WRY and TAO to do the heavy lifting in making system calls to the OS.
Tauri is not a VM or virtualized environment. Instead, it is an application toolkit that allows making Webview OS applications.
Core Ecosystem
Simplified representation of the Tauri architecture.
tauri
This is the major crate that holds everything together. It brings the runtimes, macros, utilities and API into one final product. It reads the tauri.conf.json file at compile time to bring in features and undertake the actual configuration of the app (and even the Cargo.toml file in the project’s folder). It handles script injection (for polyfills / prototype revision) at runtime, hosts the API for systems interaction, and even manages the updating process.
tauri-runtime
The glue layer between Tauri itself and lower-level webview libraries.
tauri-macros
Creates macros for the context, handler, and commands by leveraging the tauri-codegen crate.
tauri-utils
Common code that is reused in many places and offers useful utilities like parsing configuration files, detecting platform triples, injecting the CSP, and managing assets.
tauri-build
Applies the macros at build-time to rig some special features needed by cargo.
tauri-codegen
Embeds, hashes, and compresses assets, including icons for the app as well as the system tray. Parses tauri.conf.json at compile time and generates the Config struct.
tauri-runtime-wry
This crate opens up direct systems-level interactions specifically for WRY, such as printing, monitor detection, and other windowing-related tasks.
Tauri Tooling
API (JavaScript / TypeScript)
A typescript library that creates cjs and esm JavaScript endpoints for you to import into your frontend framework so that the Webview can call and listen to backend activity. Also ships in pure typescript, because for some frameworks this is more optimal. It uses the message passing of webviews to their hosts.
Bundler (Rust / Shell)
A library that builds a Tauri app for the platform it detects or is told. Currently supports macOS, Windows and Linux - but in the near future will support mobile platforms as well. May be used outside of Tauri projects.
cli.rs (Rust)
This Rust executable provides the full interface to all of the required activities for which the CLI is required. It runs on macOS, Windows, and Linux.
cli.js (JavaScript)
Wrapper around cli.rs using napi-rs to produce npm packages for each platform.
create-tauri-app (JavaScript)
A toolkit that will enable engineering teams to rapidly scaffold out a new tauri-apps project using the frontend framework of their choice (as long as it has been configured).
Upstream Crates
The Tauri-Apps organization maintains two “upstream” crates from Tauri, namely TAO for creating and managing application windows, and WRY for interfacing with the Webview that lives within the window.
TAO
Cross-platform application window creation library in Rust that supports all major platforms like Windows, macOS, Linux, iOS and Android. Written in Rust, it is a fork of winit that we have extended for our own needs - like menu bar and system tray.
WRY
WRY is a cross-platform WebView rendering library in Rust that supports all major desktop platforms like Windows, macOS, and Linux. Tauri uses WRY as the abstract layer responsible to determine which webview is used (and how interactions are made).
Additional Tooling
tauri-action
GitHub workflow that builds Tauri binaries for all platforms. Even allows creating a (very basic) Tauri app even if Tauri is not set up.
tauri-vscode
This project enhances the Visual Studio Code interface with several nice-to-have features.
Plugins
Generally speaking, plugins are authored by third parties (even though there may be official, supported plugins). A plugin generally does 3 things:
- Enables Rust code to do “something”.
- Provides interface glue to make it easy to integrate into an app.
- Provides a JavaScript API for interfacing with the Rust code.
Here are some examples of Tauri Plugins:
License
Tauri itself is licensed under MIT or Apache-2.0. If you repackage it and modify any source code, it is your responsibility to verify that you are complying with all upstream licenses. Tauri is provided AS-IS with no explicit claim for suitability for any purpose.
Here you may peruse our Software Bill of Materials.
Inter-Process Communication
Inter-Process Communication (IPC) allows isolated processes to communicate securely and is key to building more complex applications.
Learn more about the specific IPC patterns in the following guides:
Tauri uses a particular style of Inter-Process Communication called Asynchronous Message Passing, where processes exchange requests and responses serialized using some simple data representation. Message Passing should sound familiar to anyone with web development experience, as this paradigm is used for client-server communication on the internet.
Message passing is a safer technique than shared memory or direct function access because the recipient is free to reject or discard requests as it sees fit. For example, if the Tauri Core process determines a request to be malicious, it simply discards the requests and never executes the corresponding function.
In the following, we explain Tauri’s two IPC primitives - Events and Commands - in more detail.
Events
Events are fire-and-forget, one-way IPC messages that are best suited to communicate lifecycle events and state changes. Unlike Commands, Events can be emitted by both the Frontend and the Tauri Core.
Events sent between the Core and the Webview.
Commands
Tauri also provides a foreign function interface-like abstraction on top of IPC messages1. The primary API, invoke, is similar to the browser’s fetch API and allows the Frontend to invoke Rust functions, pass arguments, and receive data.
Because this mechanism uses a JSON-RPC like protocol under the hood to serialize requests and responses, all arguments and return data must be serializable to JSON.
IPC messages involved in a command invocation.
Footnotes
- Because Commands still use message passing under the hood, they do not share the same security pitfalls as real FFI interfaces do. ↩
Brownfield Pattern
This is the default pattern.
This is the simplest and most straightforward pattern to use Tauri with, because it tries to be as compatible as possible with existing frontend projects. In short, it tries to require nothing additional to what an existing web frontend might use inside a browser. Not everything that works in existing browser applications will work out-of-the-box.
If you are unfamiliar with Brownfield software development in general, the Brownfield Wikipedia article provides a nice summary. For Tauri, the existing software is current browser support and behavior, instead of legacy systems.
Configuration
Because the Brownfield pattern is the default pattern, it doesn’t require a configuration option to be set. To explicitly set it, you can use the app > security > pattern object in the tauri.conf.json configuration file.
{
"app": {
"security": {
"pattern": {
"use": "brownfield"
}
}
}
}
There are no additional configuration options for the brownfield pattern.
Isolation Pattern
The Isolation pattern is a way to intercept and modify Tauri API messages sent by the frontend before they get to Tauri Core, all with JavaScript. The secure JavaScript code that is injected by the Isolation pattern is referred to as the Isolation application.
Why
The Isolation pattern’s purpose is to provide a mechanism for developers to help protect their application from unwanted or malicious frontend calls to Tauri Core. The need for the Isolation pattern rose out of threats coming from untrusted content running on the frontend, a common case for applications with many dependencies. See Security: Threat Models for a list of many sources of threats that an application may see.
The largest threat model described above that the Isolation pattern was designed in mind was Development Threats. Not only do many frontend build-time tools consist of many dozen (or hundreds) of often deeply-nested dependencies, but a complex application may also have a large amount of (also often deeply-nested) dependencies that are bundled into the final output.
When
Tauri highly recommends using the isolation pattern whenever it can be used. Because the Isolation application intercepts all messages from the frontend, it can always be used.
Tauri also strongly suggests locking down your application whenever you use external Tauri APIs. As the developer, you can utilize the secure Isolation application to try and verify IPC inputs, to make sure they are within some expected parameters. For example, you may want to check that a call to read or write a file is not trying to access a path outside your application’s expected locations. Another example is making sure that a Tauri API HTTP fetch call is only setting the Origin header to what your application expects it to be.
That said, it intercepts all messages from the frontend, so it will even work with always-on APIs such as Events. Since some events may cause your own rust code to perform actions, the same sort of validation techniques can be used with them.
How
The Isolation pattern is all about injecting a secure application in between your frontend and Tauri Core to intercept and modify incoming IPC messages. It does this by using the sandboxing feature of <iframe>s to run the JavaScript securely alongside the main frontend application. Tauri enforces the Isolation pattern while loading the page, forcing all IPC calls to Tauri Core to instead be routed through the sandboxed Isolation application first. Once the message is ready to be passed to Tauri Core, it is encrypted using the browser’s SubtleCrypto implementation and passed back to the main frontend application. Once there, it is directly passed to Tauri Core, where it is then decrypted and read like normal.
To ensure that someone cannot manually read the keys for a specific version of your application and use that to modify the messages after being encrypted, new keys are generated each time your application is run.
Approximate Steps of an IPC Message
To make it easier to follow, here’s an ordered list with the approximate steps an IPC message will go through when being sent to Tauri Core with the Isolation pattern:
- Tauri’s IPC handler receives a message
- IPC handler -> Isolation application
[sandbox]Isolation application hook runs and potentially modifies the message[sandbox]Message is encrypted with AES-GCM using a runtime-generated key[encrypted]Isolation application -> IPC handler[encrypted]IPC handler -> Tauri Core
Note: Arrows (->) indicate message passing.
Performance Implications
Because encryption of the message does occur, there are additional overhead costs compared to the Brownfield pattern, even if the secure Isolation application doesn’t do anything. Aside from performance-sensitive applications (who likely have a carefully-maintained and small set of dependencies, to keep the performance adequate), most applications should not notice the runtime costs of encrypting/decrypting the IPC messages, as they are relatively small and AES-GCM is relatively fast. If you are unfamiliar with AES-GCM, all that is relevant in this context is that it’s the only authenticated mode algorithm included in SubtleCrypto and that you probably already use it every day under the hood with TLS.
There is also a cryptographically secure key generated once each time the Tauri application is started. It is not generally noticeable if the system already has enough entropy to immediately return enough random numbers, which is extremely common for desktop environments. If running in a headless environment to perform some integration testing with WebDriver then you may want to install some sort of entropy-generating service such as haveged if your operating system does not have one included. Linux 5.6 (March 2020) now includes entropy generation using speculative execution.
Limitations
There are a few limitations in the Isolation pattern that arose out of platform inconsistencies. The most significant limitation is due to external files not loading correctly inside sandboxed <iframes> on Windows. Because of this, we have implemented a simple script inlining step during build time that takes the content of scripts relative to the Isolation application and injects them inline. This means that typical bundling or simple including of files like <script src="index.js"></script> still works properly, but newer mechanisms such as ES Modules will not successfully load.
Recommendations
Because the point of the Isolation application is to protect against Development Threats, we highly recommend keeping your Isolation application as simple as possible. Not only should you strive to keep dependencies of your isolation application minimal, but you should also consider keeping its required build steps minimal. This would allow you to not need to worry about supply chain attacks against your Isolation application on top of your frontend application.
Creating the Isolation Application
In this example, we will make a small hello-world style Isolation application and hook it up to an imaginary existing Tauri application. It will do no verification of the messages passing through it, only print the contents to the WebView console.
For the purposes of this example, let’s imagine we are in the same directory as tauri.conf.json. The existing Tauri application has its frontendDist set to ../dist.
../dist-isolation/index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Isolation Secure Script</title>
</head>
<body>
<script src="index.js"></script>
</body>
</html>
../dist-isolation/index.js:
window.__TAURI_ISOLATION_HOOK__ = (payload) => {
// let's not verify or modify anything, just print the content from the hook
console.log('hook', payload);
return payload;
};
Now, all we need to do is set up our tauri.conf.json configuration to use the Isolation pattern, and have just bootstrapped to the Isolation pattern from the Brownfield pattern.
Configuration
Let’s assume that our main frontend frontendDist is set to ../dist. We also output our Isolation application to ../dist-isolation.
{
"build": {
"frontendDist": "../dist"
},
"app": {
"security": {
"pattern": {
"use": "isolation",
"options": {
"dir": "../dist-isolation"
}
}
}
}
}
Process Model
Tauri employs a multi-process architecture similar to Electron or many modern web browsers. This guide explores the reasons behind the design choice and why it is key to writing secure applications.
Why Multiple Processes?
In the early days of GUI applications, it was common to use a single process to perform computation, draw the interface and react to user input. As you can probably guess, this meant that a long-running, expensive computation would leave the user interface unresponsive, or worse, a failure in one app component would bring the whole app crashing down.
It became clear that a more resilient architecture was needed, and applications began running different components in different processes. This makes much better use of modern multi-core CPUs and creates far safer applications. A crash in one component doesn’t affect the whole system anymore, as components are isolated on different processes. If a process gets into an invalid state, we can easily restart it.
We can also limit the blast radius of potential exploits by handing out only the minimum amount of permissions to each process, just enough so they can get their job done. This pattern is known as the Principle of Least Privilege, and you see it in the real world all the time. If you have a gardener coming over to trim your hedge, you give them the key to your garden. You would not give them the keys to your house; why would they need access to that? The same concept applies to computer programs. The less access we give them, the less harm they can do if they get compromised.
The Core Process
Each Tauri application has a core process, which acts as the application’s entry point and which is the only component with full access to the operating system.
The Core’s primary responsibility is to use that access to create and orchestrate application windows, system-tray menus, or notifications. Tauri implements the necessary cross-platform abstractions to make this easy. It also routes all Inter-Process Communication through the Core process, allowing you to intercept, filter, and manipulate IPC messages in one central place.
The Core process should also be responsible for managing global state, such as settings or database connections. This allows you to easily synchronize state between windows and protect your business-sensitive data from prying eyes in the Frontend.
We chose Rust to implement Tauri because of its concept of Ownership guarantees memory safety while retaining excellent performance.
Simplified representation of the Tauri process model. A single Core process manages one or more WebView processes.
The WebView Process
The Core process doesn’t render the actual user interface (UI) itself; it spins up WebView processes that leverage WebView libraries provided by the operating system. A WebView is a browser-like environment that executes your HTML, CSS, and JavaScript.
This means that most of your techniques and tools used in traditional web development can be used to create Tauri applications. For example, many Tauri examples are written using the Svelte frontend framework and the Vite bundler.
Security best practices apply as well; for example, you must always sanitize user input, never handle secrets in the Frontend, and ideally defer as much business logic as possible to the Core process to keep your attack surface small.
Unlike other similar solutions, the WebView libraries are not included in your final executable but dynamically linked at runtime1. This makes your application significantly smaller, but it also means that you need to keep platform differences in mind, just like traditional web development.
Footnotes
- Currently, Tauri uses Microsoft Edge WebView2 on Windows, WKWebView on macOS and webkitgtk on Linux. ↩
App Size
While Tauri by default provides very small binaries it doesn’t hurt to push the limits a bit, so here are some tips and tricks for reaching optimal results.
Cargo Configuration
One of the simplest frontend agnostic size improvements you can do to your project is adding a Cargo profile to it.
Dependent on whether you use the stable or nightly Rust toolchain the options available to you differ a bit. It’s recommended you stick to the stable toolchain unless you’re an advanced user.
-
Stable
src-tauri/Cargo.toml
[profile.dev] incremental = true # Compile your binary in smaller steps. [profile.release] codegen-units = 1 # Allows LLVM to perform better optimization. lto = true # Enables link-time-optimizations. opt-level = "s" # Prioritizes small binary size. Use `3` if you prefer speed. panic = "abort" # Higher performance by disabling panic handlers. strip = true # Ensures debug symbols are removed. -
Nightly
src-tauri/Cargo.toml
[profile.dev] incremental = true # Compile your binary in smaller steps. rustflags = ["-Zthreads=8"] # Better compile performance. [profile.release] codegen-units = 1 # Allows LLVM to perform better optimization. lto = true # Enables link-time-optimizations. opt-level = "s" # Prioritizes small binary size. Use `3` if you prefer speed. panic = "abort" # Higher performance by disabling panic handlers. strip = true # Ensures debug symbols are removed. trim-paths = "all" # Removes potentially privileged information from your binaries. rustflags = ["-Cdebuginfo=0", "-Zthreads=8"] # Better compile performance.
References
Note
This is not a complete reference over all available options, merely the ones that we’d like to draw extra attention to.
-
incremental: Compile your binary in smaller steps.
-
codegen-units: Speeds up compile times at the cost of compile time optimizations.
-
lto: Enables link time optimizations.
-
opt-level: Determines the focus of the compiler. Use
3to optimize performance,zto optimize for size, andsfor something in-between. -
panic: Reduce size by removing panic unwinding.
-
strip: Strip either symbols or debuginfo from a binary.
-
rpath: Assists in finding the dynamic libraries the binary requires by hard coding information into the binary.
-
trim-paths: Removes potentially privileged information from binaries.
-
rustflags: Sets Rust compiler flags on a profile by profile basis.
-Cdebuginfo=0: Whether debuginfo symbols should be included in the build.-Zthreads=8: Increases the number of threads used during compilation.
Remove Unused Commands
In Pull Request feat: add a new option to remove unused commands, we added in a new option in the tauri config file
tauri.conf.json
{
"build": {
"removeUnusedCommands": true
}
}
to remove commands that’re never allowed in your capability files (ACL), so you don’t have to pay for what you don’t use
Tip
To maximize the benefit of this, only include commands that you use in the ACL instead of using defaultss
Note
This feature requires tauri@2.4, tauri-build@2.1, tauri-plugin@2.1 and tauri-cli@2.4
Note
This won’t be accounting for dynamically added ACLs at runtime so make sure to check it when using this
How does it work under the hood?
tauri-cli will communicate with tauri-build and the build script of tauri, tauri-plugin through an environment variable and let them generate a list of allowed commands from the ACL, this will then be used by the generate_handler macro to remove unused commands based on that
An internal detail is this environment variable is currently REMOVE_UNUSED_COMMANDS, and it’s set to project’s directory, usually the src-tauri directory, this is used for the build scripts to find the capability files, and although it’s not encouraged, you can still set this environment variable yourself if you can’t or don’t want to use tauri-cli to get this to work (do note that as this is an implementation detail, we don’t guarantee the stability of it)
Contribute
Guide for Tauri contributors
We, the maintainers, are really excited that you are interested in contributing to Tauri. We welcome contributors of any skill level and are happy to provide guidance on PRs. In case of any doubts you can reach out to us on our Discord server.
Project repositories
Main Tauri repositories you can contribute to are:
- The core Tauri repository containing the Tauri runtime, build tools, macros and utils.
- Plugins workspace repository with all the official Tauri plugins
- Tauri Docs repository containing this website
Each of those Tauri repositories contains a .github/CONTRIBUTING.md file. In it you will find instructions on how to set up local development environment and submit a Pull Request.
Translating
The Tauri documentation is available in multiple languages: English, French, Spanish, Chinese (Simplified), Japanese, and Korean. Contributions to translations are welcome.
When translating or reviewing documentation, consider using the following tools:
- zhlint — A linting tool for Chinese text that checks punctuation, spacing, and other common issues. Recommended for contributors working on the
zh-cnlocale. Available at zhlint.jinjiang.dev. - Chinese Copywriting Guidelines — A style guide for writing consistent and correct Chinese text. Available at github.com/sparanoid/chinese-copywriting-guidelines.
- Starlight i18n VS Code extension — A useful extension for managing i18n content in Starlight-based documentation sites. Available on the VS Code Marketplace.
Develop
Topics pertaining to the development of Tauri applications, including how to use the Tauri API, communicating between the frontend and backend, configuration, state management, debugging and more
Now that you have everything set up, you are ready to run your application using Tauri.
If you are using a UI framework or JavaScript bundler, you likely have access to a development server that will speed up your development process, so if you haven’t configured your app’s dev URL and script that starts it, you can do so via the devUrl and beforeDevCommand config values:
tauri.conf.json
{
"build": {
"devUrl": "http://localhost:3000",
"beforeDevCommand": "npm run dev"
}
}
Note
Every framework has its own development tooling. It is outside of the scope of this document to cover them all or stay up to date.
Please refer to your framework’s documentation to learn more and determine the correct values to be configured.
Otherwise, if you are not using a UI framework or module bundler, you can point Tauri to your frontend source code and the Tauri CLI will start a development server for you:
tauri.conf.json
{
"build": {
"frontendDist": "./src"
}
}
Note that in this example, the src folder must include an index.html file along with any other assets loaded by your frontend.
Plain/Vanilla Dev Server Security
The built-in Tauri development server does not support mutual authentication or encryption. You should never use it for development on untrusted networks. See the development server security considerations for a more detailed explanation.
Developing Your Desktop Application
To develop your application for desktop, run the tauri dev command.
-
npm
npm run tauri dev -
yarn
yarn tauri dev -
pnpm
pnpm tauri dev -
deno
deno task tauri dev -
bun
bun tauri dev -
cargo
cargo tauri dev
The first time you run this command, the Rust package manager may need several minutes to download and build all the required packages. Since they are cached, subsequent builds are much faster, as only your code needs rebuilding.
Once Rust has finished building, the webview opens, displaying your web app. You can make changes to your web app, and if your tooling supports it, the webview should update automatically, just like a browser.
Opening the Web Inspector
You can open the Web Inspector to debug your application by performing a right-click on the webview and clicking “Inspect” or using the Ctrl + Shift + I shortcut on Windows and Linux or Cmd + Option + I shortcut on macOS.
Developing Your Mobile Application
Developing for mobile is similar to how desktop development works, but you must run tauri android dev or tauri ios dev instead:
-
npm
npm run tauri [android|ios] dev -
yarn
yarn tauri [android|ios] dev -
pnpm
pnpm tauri [android|ios] dev -
deno
deno task tauri [android|ios] dev -
bun
bun tauri [android|ios] dev -
cargo
cargo tauri [android|ios] dev
The first time you run this command, the Rust package manager may need several minutes to download and build all the required packages. Since they are cached, subsequent builds are much faster, as only your code needs rebuilding.
Development Server
The development server on mobile works similarly to the desktop one, but if you are trying to run on a physical iOS device, you must configure it to listen to a particular address provided by the Tauri CLI, defined in the TAURI_DEV_HOST environment variable. This address is either a public network address (which is the default behavior) or the actual iOS device TUN address — which is more secure, but currently needs Xcode to connect to the device.
To use the iOS device’s address you must open Xcode before running the dev command and ensure your device is connected via network in the Window > Devices and Simulators menu. Then you must run tauri ios dev --force-ip-prompt to select the iOS device address (an IPv6 address ending with ::2).
To make your development server listen on the correct host to be accessible by the iOS device, you must tweak its configuration to use the TAURI_DEV_HOST value if it has been provided. Here is an example configuration for Vite:
import { defineConfig } from 'vite';
const host = process.env.TAURI_DEV_HOST;
// https://vitejs.dev/config/
export default defineConfig({
clearScreen: false,
server: {
host: host || false,
port: 1420,
strictPort: true,
hmr: host
? {
protocol: 'ws',
host,
port: 1421,
}
: undefined,
},
});
Check your framework’s setup guide for more information.
Note
Projects created with create-tauri-app configure your development server for mobile dev out of the box.
Device Selection
By default, the mobile dev command tries to run your application on a connected device, and falls back to prompting you to select a simulator to use. To define the run target upfront, you can provide the device or simulator name as an argument:
-
npm
npm run tauri ios dev 'iPhone 15' -
yarn
yarn tauri ios dev 'iPhone 15' -
pnpm
pnpm tauri ios dev 'iPhone 15' -
deno
deno task tauri ios dev 'iPhone 15' -
bun
bun tauri ios dev 'iPhone 15' -
cargo
cargo tauri ios dev 'iPhone 15'
Using Xcode or Android Studio
Alternatively you can choose to use Xcode or Android Studio to develop your application. This can help you troubleshoot some development issues by using the IDE instead of the command line tools. To open the mobile IDE instead of running on a connected device or simulator, use the --open flag:
-
npm
npm run tauri [android|ios] dev --open -
yarn
yarn tauri [android|ios] dev --open -
pnpm
pnpm tauri [android|ios] dev --open -
deno
deno task tauri [android|ios] dev --open -
bun
bun tauri [android|ios] dev --open -
cargo
cargo tauri [android|ios] dev --open
Note
If you intend to run the application on a physical iOS device, you must also provide the --host argument and your development server must use the process.env.TAURI_DEV_HOST value as host. See your framework’s setup guide for more information.
-
npm
npm run tauri [android|ios] dev --open --host -
yarn
yarn tauri [android|ios] dev --open --host -
pnpm
pnpm tauri [android|ios] dev --open --host -
deno
deno task tauri [android|ios] dev --open --host -
bun
bun tauri [android|ios] dev --open --host -
cargo
cargo tauri [android|ios] dev --open --host
Caution
To use Xcode or Android Studio, the Tauri CLI process must be running and cannot be killed. It is recommended to use the tauri [android|ios] dev --open command and keep the process alive until you close the IDE.
Opening the Web Inspector
-
iOS
Safari must be used to access the Web Inspector for your iOS application.
Open Safari on your Mac, choose Safari > Settings in the menu bar, click Advanced, then select Show features for web developers.
If you are running on a physical device, you must enable Web Inspector in Settings > Safari > Advanced.
After following all steps you should see a Develop menu in Safari, where you will find the connected devices and applications to inspect. Select your device or simulator and click on localhost to open the Safari Developer Tools window.
-
Android
The inspector is enabled by default for Android emulators, but you must enable it for physical devices. Connect your Android device to the computer, open the Settings app on the Android device, select About, scroll to Build Number, and tap it 7 times. This will enable Developer Mode for your Android device and the Developer Options settings.
To enable application debugging on your device, you must enter the Developer Options settings, toggle on the developer options switch and enable USB Debugging.
Note
Each Android distribution has its own way to enable the Developer Mode. Please check your manufacturer’s documentation for more information.
The Web Inspector for Android is powered by Google Chrome’s DevTools and can be accessed by navigating to
chrome://inspectin the Chrome browser on your computer. Your device or emulator should appear in the remote devices list if your Android application is running, and you can open the developer tools by clicking inspect on the entry matching your device.
Troubleshooting
- Error running build script on Xcode
Tauri hooks into the iOS Xcode project by creating a build phase that executes the Tauri CLI to compile the Rust source as a library that is loaded at runtime. The build phase is executed on the Xcode process context, so it might not be able to use shell modifications such as PATH additions, so be careful when using tools such as Node.js version managers which may not be compatible.
- Network permission prompt on first iOS app execution
When you first execute tauri ios dev, you might see iOS prompting you for permission to find and connect to devices on your local network. This permission is required because, to access your development server from an iOS device, it must be exposed on the local network. To run your app on your device, you must click Allow and restart your application.
Reacting to Source Code Changes
Similarly to how your webview reflects changes in real time, tauri dev watches your src-tauri folder and its dependent crates in the workspace for changes, so your application is automatically rebuilt and restarted whenever you modify them.
You can disable this behavior by using the --no-watch flag on the tauri dev command.
To ignore watching certain files, you can create .taurignore files which work like regular .gitignore files:
.taurignore
build/
src/generated/*.rs
deny.toml
.taurignore files are usually put in the src-tauri directory or cargo workspace root folder. Currently, tauri dev looks for .taurignore files anywhere inside the common ancestor of the watched folders and the Cargo workspace root folder.
Using the Browser DevTools
Tauri’s APIs only work in your app window, so once you start using them you won’t be able to open your frontend in your system’s browser anymore.
If you prefer using your browser’s developer tooling, you must configure tauri-invoke-http to bridge Tauri API calls through a HTTP server.
Source Control
In your project repository, you SHOULD commit the src-tauri/Cargo.lock along with the src-tauri/Cargo.toml to git because Cargo uses the lockfile to provide deterministic builds. As a result, it is recommended that all applications check in their Cargo.lock. You SHOULD NOT commit the src-tauri/target folder or any of its contents.
Calling the Frontend from Rust
The @tauri-apps/api NPM package offers APIs to listen to both global and webview-specific events.
-
Listening to global events
import { listen } from '@tauri-apps/api/event'; type DownloadStarted = { url: string; downloadId: number; contentLength: number; }; listen<DownloadStarted>('download-started', (event) => { console.log( `downloading ${event.payload.contentLength} bytes from ${event.payload.url}` ); }); -
Listening to webview-specific events
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; const appWebview = getCurrentWebviewWindow(); appWebview.listen<string>('logged-in', (event) => { localStorage.setItem('session-token', event.payload); });
The listen function keeps the event listener registered for the entire lifetime of the application. To stop listening on an event you can use the unlisten function which is returned by the listen function:
import { listen } from '@tauri-apps/api/event';
const unlisten = await listen('download-started', (event) => {});
unlisten();
Note
Always use the unlisten function when your execution context goes out of scope such as when a component is unmounted.
When the page is reloaded or you navigate to another URL the listeners are unregistered automatically. This does not apply to a Single Page Application (SPA) router though.
Common Pitfalls
Don’t call unlisten() before the listener resolves
The listen function returns a Promise that resolves to the unlisten handle. If you call unlisten synchronously before the Promise resolves, the handler will be removed immediately and you won’t receive any events:
// Wrong: unlisten is called before the listener is registered
const unlisten = listen('sync-complete', (event) => {
console.log('sync finished');
});
unlisten(); // unlisten is a Promise here, not a function -- the listener is not cleaned up
// Correct: await the Promise to get the unlisten handle
const unlisten = await listen('sync-complete', (event) => {
console.log('sync finished');
});
// Now you can store and call it later, e.g. in a cleanup function
unlisten();
Timing in setup hooks
In frameworks like React, Vue, and Svelte, the setup or mount hook runs before the component is fully rendered. If you listen for events during setup, make sure the event handler does not depend on DOM elements that haven’t been rendered yet, or defer the listener registration to an effect/hook that runs after mount.
// Wrong: DOM ref may not be available yet
function MyComponent() {
const ref = useRef(null);
listen('scroll-to', (event) => {
ref.current.scrollIntoView(); // ref.current may be null during setup
});
return <div ref={ref} />;
}
// Correct: use useEffect which runs after the component mounts
function MyComponent() {
const ref = useRef(null);
useEffect(() => {
const unlisten = listen('scroll-to', (event) => {
ref.current?.scrollIntoView();
});
return () => {
unlisten.then((fn) => fn());
};
}, []);
return <div ref={ref} />;
}
Event ordering and async listeners
Event listeners are called in the order they are registered, but if a listener is async and the event emitter sends multiple events in rapid succession, the listeners may process events out of order. For ordered, high-throughput data delivery, consider using Channels instead of the event system.
Framework-specific Cleanup Examples
When using a frontend framework, you should clean up event listeners when a component is unmounted to avoid memory leaks and duplicate handlers.
-
React
import { useEffect, useState } from 'react'; import { listen } from '@tauri-apps/api/event'; function DownloadTracker() { const [progress, setProgress] = useState(0); useEffect(() => { const unlisten = listen<number>('download-progress', (event) => { setProgress(event.payload); }); return () => { unlisten.then((fn) => fn()); }; }, []); return <div>Download progress: {progress}%</div>; } -
Vue
<script setup lang="ts"> import { ref, onMounted, onUnmounted } from 'vue'; import { listen } from '@tauri-apps/api/event'; const progress = ref(0); let unlistenPromise; onMounted(() => { unlistenPromise = listen<number>('download-progress', (event) => { progress.value = event.payload; }); }); onUnmounted(() => { unlistenPromise?.then((fn) => fn()); }); </script> <template> <div>Download progress: {{ progress }}%</div> </template> -
Svelte
<script lang="ts"> import { listen } from '@tauri-apps/api/event'; let progress = $state(0); $effect(() => { const unlistenPromise = listen<number>( 'download-progress', (event) => { progress = event.payload; } ); return () => { unlistenPromise.then((unlisten) => unlisten()); }; }); </script> <div>Download progress: {progress}%</div>
Additionally Tauri provides a utility function for listening to an event exactly once:
import { once } from '@tauri-apps/api/event';
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';
once('ready', (event) => {});
const appWebview = getCurrentWebviewWindow();
appWebview.once('ready', () => {});
Note
Events emitted in the frontend also trigger listeners registered by these APIs. For more information, see the Calling Rust from the Frontend documentation.
Listening to Events on Rust
Global and webview-specific events are also delivered to listeners registered in Rust.
-
Listening to global events
src-tauri/src/lib.rs
use tauri::Listener; #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .setup(|app| { app.listen("download-started", |event| { if let Ok(payload) = serde_json::from_str::<DownloadStarted>(&event.payload()) { println!("downloading {}", payload.url); } }); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Listening to webview-specific events
src-tauri/src/lib.rs
use tauri::{Listener, Manager}; #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .setup(|app| { let webview = app.get_webview_window("main").unwrap(); webview.listen("logged-in", |event| { let session_token = event.data; // save token.. }); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
The listen function keeps the event listener registered for the entire lifetime of the application. To stop listening on an event you can use the unlisten function:
// unlisten outside of the event handler scope:
let event_id = app.listen("download-started", |event| {});
app.unlisten(event_id);
// unlisten when some event criteria is matched
let handle = app.handle().clone();
app.listen("status-changed", |event| {
if event.data == "ready" {
handle.unlisten(event.id);
}
});
Additionally Tauri provides a utility function for listening to an event exactly once:
app.once("ready", |event| {
println!("app is ready");
});
In this case the event listener is immediately unregistered after its first trigger.
Calling the Frontend from Rust
This document includes guides on how to communicate with your application frontend from your Rust code. To see how to communicate with your Rust code from your frontend, see Calling Rust from the Frontend.
The Rust side of your Tauri application can call the frontend by leveraging the Tauri event system, using channels or directly evaluating JavaScript code.
Event System
Tauri ships a simple event system you can use to have bi-directional communication between Rust and your frontend.
The event system was designed for situations where small amounts of data need to be streamed or you need to implement a multi consumer multi producer pattern (e.g. push notification system).
The event system is not designed for low latency or high throughput situations. See the channels section for the implementation optimized for streaming data.
The major differences between a Tauri command and a Tauri event are that events have no strong type support, event payloads are always JSON strings making them not suitable for bigger messages and there is no support of the capabilities system to fine grain control event data and channels.
The AppHandle and WebviewWindow types implement the event system traits Listener and Emitter.
Events are either global (delivered to all listeners) or webview-specific (only delivered to the webview matching a given label).
Global Events
To trigger a global event you can use the Emitter#emit function:
src-tauri/src/lib.rs
use tauri::{AppHandle, Emitter};
#[tauri::command]
fn download(app: AppHandle, url: String) {
app.emit("download-started", &url).unwrap();
for progress in [1, 15, 50, 80, 100] {
app.emit("download-progress", progress).unwrap();
}
app.emit("download-finished", &url).unwrap();
}
Note
Global events are delivered to all listeners
Webview Event
To trigger an event to a listener registered by a specific webview you can use the Emitter#emit_to function:
src-tauri/src/lib.rs
use tauri::{AppHandle, Emitter};
#[tauri::command]
fn login(app: AppHandle, user: String, password: String) {
let authenticated = user == "tauri-apps" && password == "tauri";
let result = if authenticated { "loggedIn" } else { "invalidCredentials" };
app.emit_to("login", "login-result", result).unwrap();
}
It is also possible to trigger an event to a list of webviews by calling Emitter#emit_filter. In the following example we emit a open-file event to the main and file-viewer webviews:
src-tauri/src/lib.rs
use tauri::{AppHandle, Emitter, EventTarget};
#[tauri::command]
fn open_file(app: AppHandle, path: std::path::PathBuf) {
app.emit_filter("open-file", path, |target| match target {
EventTarget::WebviewWindow { label } => label == "main" || label == "file-viewer",
_ => false,
}).unwrap();
}
Note
Webview-specific events are not triggered to regular global event listeners. To listen to any event you must use the listen_any function instead of listen, which defines the listener to act as a catch-all for emitted events.
Event Payload
The event payload can be any serializable type that also implements Clone. Let’s enhance the download event example by using an object to emit more information in each event:
src-tauri/src/lib.rs
use tauri::{AppHandle, Emitter};
use serde::Serialize;
#[derive(Clone, Serialize)]
#[serde(rename_all = "camelCase")]
struct DownloadStarted<'a> {
url: &'a str,
download_id: usize,
content_length: usize,
}
#[derive(Clone, Serialize)]
#[serde(rename_all = "camelCase")]
struct DownloadProgress {
download_id: usize,
chunk_length: usize,
}
#[derive(Clone, Serialize)]
#[serde(rename_all = "camelCase")]
struct DownloadFinished {
download_id: usize,
}
#[tauri::command]
fn download(app: AppHandle, url: String) {
let content_length = 1000;
let download_id = 1;
app.emit("download-started", DownloadStarted {
url: &url,
download_id,
content_length
}).unwrap();
for chunk_length in [15, 150, 35, 500, 300] {
app.emit("download-progress", DownloadProgress {
download_id,
chunk_length,
}).unwrap();
}
app.emit("download-finished", DownloadFinished { download_id }).unwrap();
}
Listening to Events
Tauri provides APIs to listen to events on both the webview and the Rust interfaces.
Listening to Events on the Frontend
The @tauri-apps/api NPM package offers APIs to listen to both global and webview-specific events.
-
Listening to global events
import { listen } from '@tauri-apps/api/event'; type DownloadStarted = { url: string; downloadId: number; contentLength: number; }; listen<DownloadStarted>('download-started', (event) => { console.log( `downloading ${event.payload.contentLength} bytes from ${event.payload.url}` ); }); -
Listening to webview-specific events
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; const appWebview = getCurrentWebviewWindow(); appWebview.listen<string>('logged-in', (event) => { localStorage.setItem('session-token', event.payload); });
The listen function keeps the event listener registered for the entire lifetime of the application. To stop listening on an event you can use the unlisten function which is returned by the listen function:
import { listen } from '@tauri-apps/api/event';
const unlisten = await listen('download-started', (event) => {});
unlisten();
Note
Always use the unlisten function when your execution context goes out of scope such as when a component is unmounted.
When the page is reloaded or you navigate to another URL the listeners are unregistered automatically. This does not apply to a Single Page Application (SPA) router though.
Common Pitfalls
Don’t call unlisten() before the listener resolves
The listen function returns a Promise that resolves to the unlisten handle. If you call unlisten synchronously before the Promise resolves, the handler will be removed immediately and you won’t receive any events:
// Wrong: unlisten is called before the listener is registered
const unlisten = listen('sync-complete', (event) => {
console.log('sync finished');
});
unlisten(); // unlisten is a Promise here, not a function -- the listener is not cleaned up
// Correct: await the Promise to get the unlisten handle
const unlisten = await listen('sync-complete', (event) => {
console.log('sync finished');
});
// Now you can store and call it later, e.g. in a cleanup function
unlisten();
Timing in setup hooks
In frameworks like React, Vue, and Svelte, the setup or mount hook runs before the component is fully rendered. If you listen for events during setup, make sure the event handler does not depend on DOM elements that haven’t been rendered yet, or defer the listener registration to an effect/hook that runs after mount.
// Wrong: DOM ref may not be available yet
function MyComponent() {
const ref = useRef(null);
listen('scroll-to', (event) => {
ref.current.scrollIntoView(); // ref.current may be null during setup
});
return <div ref={ref} />;
}
// Correct: use useEffect which runs after the component mounts
function MyComponent() {
const ref = useRef(null);
useEffect(() => {
const unlisten = listen('scroll-to', (event) => {
ref.current?.scrollIntoView();
});
return () => {
unlisten.then((fn) => fn());
};
}, []);
return <div ref={ref} />;
}
Event ordering and async listeners
Event listeners are called in the order they are registered, but if a listener is async and the event emitter sends multiple events in rapid succession, the listeners may process events out of order. For ordered, high-throughput data delivery, consider using Channels instead of the event system.
Framework-specific Cleanup Examples
When using a frontend framework, you should clean up event listeners when a component is unmounted to avoid memory leaks and duplicate handlers.
-
React
import { useEffect, useState } from 'react'; import { listen } from '@tauri-apps/api/event'; function DownloadTracker() { const [progress, setProgress] = useState(0); useEffect(() => { const unlisten = listen<number>('download-progress', (event) => { setProgress(event.payload); }); return () => { unlisten.then((fn) => fn()); }; }, []); return <div>Download progress: {progress}%</div>; } -
Vue
<script setup lang="ts"> import { ref, onMounted, onUnmounted } from 'vue'; import { listen } from '@tauri-apps/api/event'; const progress = ref(0); let unlistenPromise; onMounted(() => { unlistenPromise = listen<number>('download-progress', (event) => { progress.value = event.payload; }); }); onUnmounted(() => { unlistenPromise?.then((fn) => fn()); }); </script> <template> <div>Download progress: {{ progress }}%</div> </template> -
Svelte
<script lang="ts"> import { listen } from '@tauri-apps/api/event'; let progress = $state(0); $effect(() => { const unlistenPromise = listen<number>( 'download-progress', (event) => { progress = event.payload; } ); return () => { unlistenPromise.then((unlisten) => unlisten()); }; }); </script> <div>Download progress: {progress}%</div>
Additionally Tauri provides a utility function for listening to an event exactly once:
import { once } from '@tauri-apps/api/event';
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';
once('ready', (event) => {});
const appWebview = getCurrentWebviewWindow();
appWebview.once('ready', () => {});
Note
Events emitted in the frontend also trigger listeners registered by these APIs. For more information, see the Calling Rust from the Frontend documentation.
Listening to Events on Rust
Global and webview-specific events are also delivered to listeners registered in Rust.
-
Listening to global events
src-tauri/src/lib.rs
use tauri::Listener; #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .setup(|app| { app.listen("download-started", |event| { if let Ok(payload) = serde_json::from_str::<DownloadStarted>(&event.payload()) { println!("downloading {}", payload.url); } }); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Listening to webview-specific events
src-tauri/src/lib.rs
use tauri::{Listener, Manager}; #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .setup(|app| { let webview = app.get_webview_window("main").unwrap(); webview.listen("logged-in", |event| { let session_token = event.data; // save token.. }); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
The listen function keeps the event listener registered for the entire lifetime of the application. To stop listening on an event you can use the unlisten function:
// unlisten outside of the event handler scope:
let event_id = app.listen("download-started", |event| {});
app.unlisten(event_id);
// unlisten when some event criteria is matched
let handle = app.handle().clone();
app.listen("status-changed", |event| {
if event.data == "ready" {
handle.unlisten(event.id);
}
});
Additionally Tauri provides a utility function for listening to an event exactly once:
app.once("ready", |event| {
println!("app is ready");
});
In this case the event listener is immediately unregistered after its first trigger.
Channels
The event system is designed to be a simple two way communication that is globally available in your application. Under the hood it directly evaluates JavaScript code so it might not be suitable to sending a large amount of data.
Channels are designed to be fast and deliver ordered data. They are used internally for streaming operations such as download progress, child process output and WebSocket messages.
Let’s rewrite our download command example to use channels instead of the event system:
src-tauri/src/lib.rs
use tauri::{AppHandle, ipc::Channel};
use serde::Serialize;
#[derive(Clone, Serialize)]
#[serde(rename_all = "camelCase", rename_all_fields = "camelCase", tag = "event", content = "data")]
enum DownloadEvent<'a> {
Started {
url: &'a str,
download_id: usize,
content_length: usize,
},
Progress {
download_id: usize,
chunk_length: usize,
},
Finished {
download_id: usize,
},
}
#[tauri::command]
fn download(app: AppHandle, url: String, on_event: Channel<DownloadEvent>) {
let content_length = 1000;
let download_id = 1;
on_event.send(DownloadEvent::Started {
url: &url,
download_id,
content_length,
}).unwrap();
for chunk_length in [15, 150, 35, 500, 300] {
on_event.send(DownloadEvent::Progress {
download_id,
chunk_length,
}).unwrap();
}
on_event.send(DownloadEvent::Finished { download_id }).unwrap();
}
When calling the download command you must create the channel and provide it as an argument:
import { invoke, Channel } from '@tauri-apps/api/core';
type DownloadEvent =
| {
event: 'started';
data: {
url: string;
downloadId: number;
contentLength: number;
};
}
| {
event: 'progress';
data: {
downloadId: number;
chunkLength: number;
};
}
| {
event: 'finished';
data: {
downloadId: number;
};
};
const onEvent = new Channel<DownloadEvent>();
onEvent.onmessage = (message) => {
console.log(`got download event ${message.event}`);
};
await invoke('download', {
url: 'https://raw.githubusercontent.com/tauri-apps/tauri/dev/crates/tauri-schema-generator/schemas/config.schema.json',
onEvent,
});
Evaluating JavaScript
To directly execute any JavaScript code on the webview context you can use the WebviewWindow#eval function:
src-tauri/src/lib.rs
use tauri::Manager;
tauri::Builder::default()
.setup(|app| {
let webview = app.get_webview_window("main").unwrap();
webview.eval("console.log('hello from Rust')")?;
Ok(())
})
If the script to be evaluated is not so simple and must use input from Rust objects we recommend using the serialize-to-javascript crate.
Calling Rust from the Frontend
This document includes guides on how to communicate with your Rust code from your application frontend. To see how to communicate with your frontend from your Rust code, see Calling the Frontend from Rust.
Tauri provides a command primitive for reaching Rust functions with type safety, along with an event system that is more dynamic.
Commands
Tauri provides a simple yet powerful command system for calling Rust functions from your web app. Commands can accept arguments and return values. They can also return errors and be async.
Basic Example
Commands can be defined in your src-tauri/src/lib.rs file. To create a command, just add a function and annotate it with #[tauri::command]:
src-tauri/src/lib.rs
#[tauri::command]
fn my_custom_command() {
println!("I was invoked from JavaScript!");
}
Note
Command names must be unique.
Note
Commands defined in the lib.rs file cannot be marked as pub due to a limitation in the glue code generation. You will see an error like this if you mark it as a public function:
error[E0255]: the name `__cmd__command_name` is defined multiple times
--> src/lib.rs:28:8
|
27 | #[tauri::command]
| ----------------- previous definition of the macro `__cmd__command_name` here
28 | pub fn x() {}
| ^ `__cmd__command_name` reimported here
|
= note: `__cmd__command_name` must be defined only once in the macro namespace of this module
You will have to provide a list of your commands to the builder function like so:
src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
+.invoke_handler(tauri::generate_handler![my_custom_command])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Now, you can invoke the command from your JavaScript code:
// When using the Tauri API npm package:
import { invoke } from '@tauri-apps/api/core';
// When using the Tauri global script (if not using the npm package)
// Be sure to set `app.withGlobalTauri` in `tauri.conf.json` to true
const invoke = window.__TAURI__.core.invoke;
// Invoke the command
invoke('my_custom_command');
Defining Commands in a Separate Module
If your application defines a lot of components or if they can be grouped, you can define commands in a separate module instead of bloating the lib.rs file.
As an example let’s define a command in the src-tauri/src/commands.rs file:
src-tauri/src/commands.rs
#[tauri::command]
pub fn my_custom_command() {
println!("I was invoked from JavaScript!");
}
Note
When defining commands in a separate module they should be marked as pub.
Note
The command name is not scoped to the module so they must be unique even between modules.
In the lib.rs file, define the module and provide the list of your commands accordingly;
src-tauri/src/lib.rs
mod commands;
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
+.invoke_handler(tauri::generate_handler![commands::my_custom_command])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Note the commands:: prefix in the command list, which denotes the full path to the command function.
The command name in this example is my_custom_command so you can still call it by executing invoke("my_custom_command") in your frontend, the commands:: prefix is ignored.
WASM
When using a Rust frontend to call invoke() without arguments, you will need to adapt your frontend code as below. The reason is that Rust doesn’t support optional arguments.
#[wasm_bindgen]
extern "C" {
// invoke without arguments
+ #[wasm_bindgen(js_namespace = ["window", "__TAURI__", "core"], js_name = invoke)]
+async fn invoke_without_args(cmd: &str) -> JsValue;
// invoke with arguments (default)
#[wasm_bindgen(js_namespace = ["window", "__TAURI__", "core"])]
async fn invoke(cmd: &str, args: JsValue) -> JsValue;
// They need to have different names!
}
Passing Arguments
Your command handlers can take arguments:
#[tauri::command]
fn my_custom_command(invoke_message: String) {
println!("I was invoked from JavaScript, with this message: {}", invoke_message);
}
Arguments should be passed as a JSON object with camelCase keys:
invoke('my_custom_command', { invokeMessage: 'Hello!' });
Note
You can use snake_case for the arguments with the rename_all attribute:
#[tauri::command(rename_all = "snake_case")]
fn my_custom_command(invoke_message: String) {}
The corresponding JavaScript:
invoke('my_custom_command', { invoke_message: 'Hello!' });
Arguments can be of any type, as long as they implement serde::Deserialize.
Returning Data
Command handlers can return data as well:
#[tauri::command]
fn my_custom_command() -> String {
"Hello from Rust!".into()
}
The invoke function returns a promise that resolves with the returned value:
invoke('my_custom_command').then((message) => console.log(message));
Returned data can be of any type, as long as it implements serde::Serialize.
Returning Array Buffers
Return values that implements serde::Serialize are serialized to JSON when the response is sent to the frontend. This can slow down your application if you try to return a large data such as a file or a download HTTP response. To return array buffers in an optimized way, use tauri::ipc::Response:
use tauri::ipc::Response;
#[tauri::command]
fn read_file() -> Response {
let data = std::fs::read("/path/to/file").unwrap();
tauri::ipc::Response::new(data)
}
Error Handling
If your handler could fail and needs to be able to return an error, have the function return a Result:
#[tauri::command]
fn login(user: String, password: String) -> Result<String, String> {
if user == "tauri" && password == "tauri" {
// resolve
Ok("logged_in".to_string())
} else {
// reject
Err("invalid credentials".to_string())
}
}
If the command returns an error, the promise will reject, otherwise, it resolves:
invoke('login', { user: 'tauri', password: '0j4rijw8=' })
.then((message) => console.log(message))
.catch((error) => console.error(error));
As mentioned above, everything returned from commands must implement serde::Serialize, including errors. This can be problematic if you’re working with error types from Rust’s std library or external crates as most error types do not implement it. In simple scenarios you can use map_err to convert these errors to String:
#[tauri::command]
fn my_custom_command() -> Result<(), String> {
std::fs::File::open("path/to/file").map_err(|err| err.to_string())?;
// Return `null` on success
Ok(())
}
Since this is not very idiomatic you may want to create your own error type which implements serde::Serialize. In the following example, we use the thiserror crate to help create the error type. It allows you to turn enums into error types by deriving the thiserror::Error trait. You can consult its documentation for more details.
// create the error type that represents all errors possible in our program
#[derive(Debug, thiserror::Error)]
enum Error {
#[error(transparent)]
Io(#[from] std::io::Error)
}
// we must manually implement serde::Serialize
impl serde::Serialize for Error {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
serializer.serialize_str(self.to_string().as_ref())
}
}
#[tauri::command]
fn my_custom_command() -> Result<(), Error> {
// This will return an error
std::fs::File::open("path/that/does/not/exist")?;
// Return `null` on success
Ok(())
}
A custom error type has the advantage of making all possible errors explicit so readers can quickly identify what errors can happen. This saves other people (and yourself) enormous amounts of time when reviewing and refactoring code later.
It also gives you full control over the way your error type gets serialized. In the above example, we simply returned the error message as a string, but you could assign each error a code so you could more easily map it to a similar looking TypeScript error enum for example:
#[derive(Debug, thiserror::Error)]
enum Error {
#[error(transparent)]
Io(#[from] std::io::Error),
#[error("failed to parse as string: {0}")]
Utf8(#[from] std::str::Utf8Error),
}
#[derive(serde::Serialize)]
#[serde(tag = "kind", content = "message")]
#[serde(rename_all = "camelCase")]
enum ErrorKind {
Io(String),
Utf8(String),
}
impl serde::Serialize for Error {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
let error_message = self.to_string();
let error_kind = match self {
Self::Io(_) => ErrorKind::Io(error_message),
Self::Utf8(_) => ErrorKind::Utf8(error_message),
};
error_kind.serialize(serializer)
}
}
#[tauri::command]
fn read() -> Result<Vec<u8>, Error> {
let data = std::fs::read("/path/to/file")?;
Ok(data)
}
In your frontend you now get a { kind: 'io' | 'utf8', message: string } error object:
type ErrorKind = {
kind: 'io' | 'utf8';
message: string;
};
invoke('read').catch((e: ErrorKind) => {});
Async Commands
Asynchronous commands are preferred in Tauri to perform heavy work in a manner that doesn’t result in UI freezes or slowdowns.
Note
Async commands are executed on a separate async task using async_runtime::spawn. Commands without the async keyword are executed on the main thread unless defined with #[tauri::command(async)].
If your command needs to run asynchronously, simply declare it as async.
Caution
You need to be careful when creating asynchronous functions using Tauri. Currently, you cannot simply include borrowed arguments in the signature of an asynchronous function. Some common examples of types like this are &str and State<'_, Data>. This limitation is tracked here: https://github.com/tauri-apps/tauri/issues/2533 and workarounds are shown below.
When working with borrowed types, you have to make additional changes. These are your two main options:
Option 1: Convert the type, such as &str to a similar type that is not borrowed, such as String. This may not work for all types, for example State<'_, Data>.
Example:
// Declare the async function using String instead of &str, as &str is borrowed and thus unsupported
#[tauri::command]
async fn my_custom_command(value: String) -> String {
// Call another async function and wait for it to finish
some_async_function().await;
value
}
Option 2: Wrap the return type in a Result. This one is a bit harder to implement, but works for all types.
Use the return type Result<a, b>, replacing a with the type you wish to return, or () if you wish to return null, and replacing b with an error type to return if something goes wrong, or () if you wish to have no optional error returned. For example:
Result<String, ()>to return a String, and no error.Result<(), ()>to returnnull.Result<bool, Error>to return a boolean or an error as shown in the Error Handling section above.
Example:
// Return a Result<String, ()> to bypass the borrowing issue
#[tauri::command]
async fn my_custom_command(value: &str) -> Result<String, ()> {
// Call another async function and wait for it to finish
some_async_function().await;
// Note that the return value must be wrapped in `Ok()` now.
Ok(format!(value))
}
Invoking from JavaScript
Since invoking the command from JavaScript already returns a promise, it works just like any other command:
invoke('my_custom_command', { value: 'Hello, Async!' }).then(() =>
console.log('Completed!')
);
Channels
The Tauri channel is the recommended mechanism for streaming data such as streamed HTTP responses to the frontend. The following example reads a file and notifies the frontend of the progress in chunks of 4096 bytes:
use tokio::io::AsyncReadExt;
#[tauri::command]
async fn load_image(path: std::path::PathBuf, reader: tauri::ipc::Channel<&[u8]>) {
// for simplicity this example does not include error handling
let mut file = tokio::fs::File::open(path).await.unwrap();
let mut chunk = vec![0; 4096];
loop {
let len = file.read(&mut chunk).await.unwrap();
if len == 0 {
// Length of zero means end of file.
break;
}
reader.send(&chunk).unwrap();
}
}
See the channels documentation for more information.
Accessing the WebviewWindow in Commands
Commands can access the WebviewWindow instance that invoked the message:
src-tauri/src/lib.rs
#[tauri::command]
async fn my_custom_command(webview_window: tauri::WebviewWindow) {
println!("WebviewWindow: {}", webview_window.label());
}
Accessing an AppHandle in Commands
Commands can access an AppHandle instance:
src-tauri/src/lib.rs
#[tauri::command]
async fn my_custom_command(app_handle: tauri::AppHandle) {
let app_dir = app_handle.path().app_dir();
use tauri::GlobalShortcutManager;
app_handle.global_shortcut_manager().register("CTRL + U", move || {});
}
Tip
AppHandle and WebviewWindow both take a generic parameter R: Runtime, when the wry feature is enabled in tauri (which is enabled by default), we default the generic to the Wry runtime so you can use it directly, but if you want to use a different runtime, for example the mock runtime, you need to write your functions like this
src-tauri/src/lib.rs
use tauri::{AppHandle, GlobalShortcutManager, Runtime, WebviewWindow};
#[tauri::command]
async fn my_custom_command<R: Runtime>(app_handle: AppHandle<R>, webview_window: WebviewWindow<R>) {
let app_dir = app_handle.path().app_dir();
app_handle
.global_shortcut_manager()
.register("CTRL + U", move || {});
println!("WebviewWindow: {}", webview_window.label());
}
Accessing Managed State
Tauri can manage state using the manage function on tauri::Builder. The state can be accessed on a command using tauri::State:
src-tauri/src/lib.rs
struct MyState(String);
#[tauri::command]
fn my_custom_command(state: tauri::State<MyState>) {
assert_eq!(state.0 == "some state value", true);
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.manage(MyState("some state value".into()))
.invoke_handler(tauri::generate_handler![my_custom_command])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Accessing Raw Request
Tauri commands can also access the full tauri::ipc::Request object which includes the raw body payload and the request headers.
#[derive(Debug, thiserror::Error)]
enum Error {
#[error("unexpected request body")]
RequestBodyMustBeRaw,
#[error("missing `{0}` header")]
MissingHeader(&'static str),
}
impl serde::Serialize for Error {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
serializer.serialize_str(self.to_string().as_ref())
}
}
#[tauri::command]
fn upload(request: tauri::ipc::Request) -> Result<(), Error> {
let tauri::ipc::InvokeBody::Raw(upload_data) = request.body() else {
return Err(Error::RequestBodyMustBeRaw);
};
let Some(authorization_header) = request.headers().get("Authorization") else {
return Err(Error::MissingHeader("Authorization"));
};
// upload...
Ok(())
}
In the frontend you can call invoke() sending a raw request body by providing an ArrayBuffer or Uint8Array on the payload argument, and include request headers in the third argument:
const data = new Uint8Array([1, 2, 3]);
await __TAURI__.core.invoke('upload', data, {
headers: {
Authorization: 'apikey',
},
});
Creating Multiple Commands
The tauri::generate_handler! macro takes an array of commands. To register multiple commands, you cannot call invoke_handler multiple times. Only the last call will be used. You must pass each command to a single call of tauri::generate_handler!.
src-tauri/src/lib.rs
#[tauri::command]
fn cmd_a() -> String {
"Command a"
}
#[tauri::command]
fn cmd_b() -> String {
"Command b"
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![cmd_a, cmd_b])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Complete Example
Any or all of the above features can be combined:
src-tauri/src/lib.rs
struct Database;
#[derive(serde::Serialize)]
struct CustomResponse {
message: String,
other_val: usize,
}
async fn some_other_function() -> Option<String> {
Some("response".into())
}
#[tauri::command]
async fn my_custom_command(
window: tauri::WebviewWindow,
number: usize,
database: tauri::State<'_, Database>,
) -> Result<CustomResponse, String> {
println!("Called from {}", window.label());
let result: Option<String> = some_other_function().await;
if let Some(message) = result {
Ok(CustomResponse {
message,
other_val: 42 + number,
})
} else {
Err("No result".into())
}
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.manage(Database {})
.invoke_handler(tauri::generate_handler![my_custom_command])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
import { invoke } from '@tauri-apps/api/core';
// Invocation from JavaScript
invoke('my_custom_command', {
number: 42,
})
.then((res) =>
console.log(`Message: ${res.message}, Other Val: ${res.other_val}`)
)
.catch((e) => console.error(e));
Event System
The event system is a simpler communication mechanism between your frontend and the Rust. Unlike commands, events are not type safe, are always async, cannot return values and only supports JSON payloads.
Global Events
To trigger a global event you can use the event.emit or the WebviewWindow#emit functions:
import { emit } from '@tauri-apps/api/event';
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';
// emit(eventName, payload)
emit('file-selected', '/path/to/file');
const appWebview = getCurrentWebviewWindow();
appWebview.emit('route-changed', { url: window.location.href });
Note
Global events are delivered to all listeners
Webview Event
To trigger an event to a listener registered by a specific webview you can use the event.emitTo or the WebviewWindow#emitTo functions:
import { emitTo } from '@tauri-apps/api/event';
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';
// emitTo(webviewLabel, eventName, payload)
emitTo('settings', 'settings-update-requested', {
key: 'notification',
value: 'all',
});
const appWebview = getCurrentWebviewWindow();
appWebview.emitTo('editor', 'file-changed', {
path: '/path/to/file',
contents: 'file contents',
});
Note
Webview-specific events are not triggered to regular global event listeners. To listen to any event you must provide the { target: { kind: 'Any' } } option to the event.listen function, which defines the listener to act as a catch-all for emitted events:
import { listen } from '@tauri-apps/api/event';
listen(
'state-changed',
(event) => {
console.log('got state changed event', event);
},
{
target: { kind: 'Any' },
}
);
Listening to Events
The @tauri-apps/api NPM package offers APIs to listen to both global and webview-specific events.
-
Listening to global events
import { listen } from '@tauri-apps/api/event'; type DownloadStarted = { url: string; downloadId: number; contentLength: number; }; listen<DownloadStarted>('download-started', (event) => { console.log( `downloading ${event.payload.contentLength} bytes from ${event.payload.url}` ); }); -
Listening to webview-specific events
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; const appWebview = getCurrentWebviewWindow(); appWebview.listen<string>('logged-in', (event) => { localStorage.setItem('session-token', event.payload); });
The listen function keeps the event listener registered for the entire lifetime of the application. To stop listening on an event you can use the unlisten function which is returned by the listen function:
import { listen } from '@tauri-apps/api/event';
const unlisten = await listen('download-started', (event) => {});
unlisten();
Note
Always use the unlisten function when your execution context goes out of scope such as when a component is unmounted.
When the page is reloaded or you navigate to another URL the listeners are unregistered automatically. This does not apply to a Single Page Application (SPA) router though.
Common Pitfalls
Don’t call unlisten() before the listener resolves
The listen function returns a Promise that resolves to the unlisten handle. If you call unlisten synchronously before the Promise resolves, the handler will be removed immediately and you won’t receive any events:
// Wrong: unlisten is called before the listener is registered
const unlisten = listen('sync-complete', (event) => {
console.log('sync finished');
});
unlisten(); // unlisten is a Promise here, not a function -- the listener is not cleaned up
// Correct: await the Promise to get the unlisten handle
const unlisten = await listen('sync-complete', (event) => {
console.log('sync finished');
});
// Now you can store and call it later, e.g. in a cleanup function
unlisten();
Timing in setup hooks
In frameworks like React, Vue, and Svelte, the setup or mount hook runs before the component is fully rendered. If you listen for events during setup, make sure the event handler does not depend on DOM elements that haven’t been rendered yet, or defer the listener registration to an effect/hook that runs after mount.
// Wrong: DOM ref may not be available yet
function MyComponent() {
const ref = useRef(null);
listen('scroll-to', (event) => {
ref.current.scrollIntoView(); // ref.current may be null during setup
});
return <div ref={ref} />;
}
// Correct: use useEffect which runs after the component mounts
function MyComponent() {
const ref = useRef(null);
useEffect(() => {
const unlisten = listen('scroll-to', (event) => {
ref.current?.scrollIntoView();
});
return () => {
unlisten.then((fn) => fn());
};
}, []);
return <div ref={ref} />;
}
Event ordering and async listeners
Event listeners are called in the order they are registered, but if a listener is async and the event emitter sends multiple events in rapid succession, the listeners may process events out of order. For ordered, high-throughput data delivery, consider using Channels instead of the event system.
Framework-specific Cleanup Examples
When using a frontend framework, you should clean up event listeners when a component is unmounted to avoid memory leaks and duplicate handlers.
-
React
import { useEffect, useState } from 'react'; import { listen } from '@tauri-apps/api/event'; function DownloadTracker() { const [progress, setProgress] = useState(0); useEffect(() => { const unlisten = listen<number>('download-progress', (event) => { setProgress(event.payload); }); return () => { unlisten.then((fn) => fn()); }; }, []); return <div>Download progress: {progress}%</div>; } -
Vue
<script setup lang="ts"> import { ref, onMounted, onUnmounted } from 'vue'; import { listen } from '@tauri-apps/api/event'; const progress = ref(0); let unlistenPromise; onMounted(() => { unlistenPromise = listen<number>('download-progress', (event) => { progress.value = event.payload; }); }); onUnmounted(() => { unlistenPromise?.then((fn) => fn()); }); </script> <template> <div>Download progress: {{ progress }}%</div> </template> -
Svelte
<script lang="ts"> import { listen } from '@tauri-apps/api/event'; let progress = $state(0); $effect(() => { const unlistenPromise = listen<number>( 'download-progress', (event) => { progress = event.payload; } ); return () => { unlistenPromise.then((unlisten) => unlisten()); }; }); </script> <div>Download progress: {progress}%</div>
Additionally Tauri provides a utility function for listening to an event exactly once:
import { once } from '@tauri-apps/api/event';
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';
once('ready', (event) => {});
const appWebview = getCurrentWebviewWindow();
appWebview.once('ready', () => {});
Note
Events emitted in the frontend also trigger listeners registered by these APIs. For more information, see the Calling Rust from the Frontend documentation.
Listening to Events on Rust
Global and webview-specific events are also delivered to listeners registered in Rust.
-
Listening to global events
src-tauri/src/lib.rs
use tauri::Listener; #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .setup(|app| { app.listen("download-started", |event| { if let Ok(payload) = serde_json::from_str::<DownloadStarted>(&event.payload()) { println!("downloading {}", payload.url); } }); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Listening to webview-specific events
src-tauri/src/lib.rs
use tauri::{Listener, Manager}; #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .setup(|app| { let webview = app.get_webview_window("main").unwrap(); webview.listen("logged-in", |event| { let session_token = event.data; // save token.. }); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
The listen function keeps the event listener registered for the entire lifetime of the application. To stop listening on an event you can use the unlisten function:
// unlisten outside of the event handler scope:
let event_id = app.listen("download-started", |event| {});
app.unlisten(event_id);
// unlisten when some event criteria is matched
let handle = app.handle().clone();
app.listen("status-changed", |event| {
if event.data == "ready" {
handle.unlisten(event.id);
}
});
Additionally Tauri provides a utility function for listening to an event exactly once:
app.once("ready", |event| {
println!("app is ready");
});
In this case the event listener is immediately unregistered after its first trigger.
To learn how to listen to events and emit events from your Rust code, see the Rust Event System documentation.
Configuration Files
Since Tauri is a toolkit for building applications there can be many files to configure project settings. Some common files that you may run across are tauri.conf.json, package.json and Cargo.toml. We briefly explain each on this page to help point you in the right direction for which files to modify.
Tauri Config
The Tauri configuration is used to define the source of your Web app, describe your application’s metadata, configure bundles, set plugin configurations, modify runtime behavior by configuring windows, tray icons, menus and more.
This file is used by the Tauri runtime and the Tauri CLI. You can define build settings (such as the command run before tauri build or tauri dev kicks in), set the name and version of your app, control the Tauri runtime, and configure plugins.
Tip
You can find all of the options in the configuration reference.
Supported Formats
The default Tauri config format is JSON. The JSON5 or TOML format can be enabled by adding the config-json5 or config-toml feature flag (respectively) to the tauri and tauri-build dependencies in Cargo.toml.
Cargo.toml
[build-dependencies]
tauri-build = { version = "2.0.0", features = [ "config-json5" ] }
[dependencies]
tauri = { version = "2.0.0", features = [ "config-json5" ] }
The structure and values are the same across all formats, however, the formatting should be consistent with the respective file’s format:
tauri.conf.json
{
build: {
devUrl: 'http://localhost:3000',
// start the dev server
beforeDevCommand: 'npm run dev',
},
bundle: {
active: true,
icon: ['icons/app.png'],
},
app: {
windows: [
{
title: 'MyApp',
},
],
},
plugins: {
updater: {
pubkey: 'updater pub key',
endpoints: ['https://my.app.updater/{{target}}/{{current_version}}'],
},
},
}
Tauri.toml
[build]
dev-url = "http://localhost:3000"
# start the dev server
before-dev-command = "npm run dev"
[bundle]
active = true
icon = ["icons/app.png"]
[[app.windows]]
title = "MyApp"
[plugins.updater]
pubkey = "updater pub key"
endpoints = ["https://my.app.updater/{{target}}/{{current_version}}"]
Note that JSON5 and TOML supports comments, and TOML can use kebab-case for config names which are more idiomatic. Field names are case-sensitive in all 3 formats.
Platform-specific Configuration
In addition to the default configuration file, Tauri can read a platform-specific configuration from:
tauri.linux.conf.jsonorTauri.linux.tomlfor Linuxtauri.windows.conf.jsonorTauri.windows.tomlfor Windowstauri.macos.conf.jsonorTauri.macos.tomlfor macOStauri.android.conf.jsonorTauri.android.tomlfor Androidtauri.ios.conf.jsonorTauri.ios.tomlfor iOS
The platform-specific configuration file gets merged with the main configuration object following the JSON Merge Patch (RFC 7396) specification.
For example, given the following base tauri.conf.json:
tauri.conf.json
{
"productName": "MyApp",
"bundle": {
"resources": ["./resources"]
},
"plugins": {
"deep-link": {}
}
}
And the given tauri.linux.conf.json:
tauri.linux.conf.json
{
"productName": "my-app",
"bundle": {
"resources": ["./linux-assets"]
},
"plugins": {
"cli": {
"description": "My app",
"subcommands": {
"update": {}
}
},
"deep-link": {}
}
}
The resolved configuration for Linux would be the following object:
{
"productName": "my-app",
"bundle": {
"resources": ["./linux-assets"]
},
"plugins": {
"cli": {
"description": "My app",
"subcommands": {
"update": {}
}
},
"deep-link": {}
}
}
Additionally you can provide a configuration to be merged via the CLI, see the following section for more information.
Extending the Configuration
The Tauri CLI allows you to extend the Tauri configuration when running one of the dev, android dev, ios dev, build, android build, ios build or bundle commands. The configuration extension can be provided by the --config argument either as a raw JSON string or as a path to a JSON file. Tauri uses the JSON Merge Patch (RFC 7396) specification to merge the provided configuration value with the originally resolved configuration object.
This mechanism can be used to define multiple flavours of your application or have more flexibility when configuring your application bundles.
For instance to distribute a completely isolated beta application you can use this feature to configure a separate application name and identifier:
src-tauri/tauri.beta.conf.json
{
"productName": "My App Beta",
"identifier": "com.myorg.myappbeta"
}
And to distribute this separate beta app you provide this configuration file when building it:
-
npm
npm run tauri build -- --config src-tauri/tauri.beta.conf.json -
yarn
yarn tauri build --config src-tauri/tauri.beta.conf.json -
pnpm
pnpm tauri build --config src-tauri/tauri.beta.conf.json -
deno
deno task tauri build --config src-tauri/tauri.beta.conf.json -
bun
bun tauri build --config src-tauri/tauri.beta.conf.json -
cargo
cargo tauri build --config src-tauri/tauri.beta.conf.json
Cargo.toml
Cargo’s manifest file is used to declare Rust crates your app depends on, metadata about your app, and other Rust-related features. If you do not intend to do backend development using Rust for your app then you may not be modifying it much, but it’s important to know that it exists and what it does.
Below is an example of a barebones Cargo.toml file for a Tauri project:
Cargo.toml
[package]
name = "app"
version = "0.1.0"
description = "A Tauri App"
authors = ["you"]
license = ""
repository = ""
default-run = "app"
edition = "2021"
rust-version = "1.57"
[build-dependencies]
tauri-build = { version = "2.0.0" }
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
tauri = { version = "2.0.0", features = [ ] }
The most important parts to take note of are the tauri-build and tauri dependencies. Generally, they must both be on the same latest minor versions as the Tauri CLI, but this is not strictly required. If you encounter issues while trying to run your app you should check that any Tauri versions (tauri and tauri-cli) are on the latest versions for their respective minor releases.
Cargo version numbers use Semantic Versioning. Running cargo update in the src-tauri folder will pull the latest available Semver-compatible versions of all dependencies. For example, if you specify 2.0.0 as the version for tauri-build, Cargo will detect and download version 2.0.1 because it is the latest Semver-compatible version available. Tauri will update the major version number whenever a breaking change is introduced, meaning you should always be capable of safely upgrading to the latest minor and patch versions without fear of your code breaking.
If you want to use a specific crate version you can use exact versions instead by prepending = to the version number of the dependency:
tauri-build = { version = "=2.0.0" }
An additional thing to take note of is the features=[] portion of the tauri dependency. Running tauri dev and tauri build will automatically manage which features need to be enabled in your project based on the your Tauri configuration. For more information about tauri feature flags see the documentation.
When you build your application a Cargo.lock file is produced. This file is used primarily for ensuring that the same dependencies are used across machines during development (similar to yarn.lock, pnpm-lock.yaml or package-lock.json in Node.js). It is recommended to commit this file to your source repository so you get consistent builds.
To learn more about the Cargo manifest file please refer to the official documentation.
package.json
This is the package file used by Node.js. If the frontend of your Tauri app is developed using Node.js-based technologies (such as npm, yarn, or pnpm) this file is used to configure the frontend dependencies and scripts.
An example of a barebones package.json file for a Tauri project might look a little something like this:
package.json
{
"scripts": {
"dev": "command to start your app development mode",
"build": "command to build your app frontend",
"tauri": "tauri"
},
"dependencies": {
"@tauri-apps/api": "^2.0.0",
"@tauri-apps/cli": "^2.0.0"
}
}
It’s common to use the "scripts" section to store the commands used to launch and build the frontend used by your Tauri application. The above package.json file specifies the dev command that you can run using yarn dev or npm run dev to start the frontend framework and the build command that you can run using yarn build or npm run build to build your frontend’s Web assets to be added by Tauri in production. The most convenient way to use these scripts is to hook them with the Tauri CLI via the Tauri configuration’s beforeDevCommand and beforeBuildCommand hooks:
tauri.conf.json
{
"build": {
"beforeDevCommand": "yarn dev",
"beforeBuildCommand": "yarn build"
}
}
Note
The "tauri" script is only needed when using npm
The dependencies object specifies which dependencies Node.js should download when you run either yarn, pnpm install or npm install (in this case the Tauri CLI and API).
In addition to the package.json file you may see either a yarn.lock, pnpm-lock.yaml or package-lock.json file. These files assist in ensuring that when you download the dependencies later you’ll get the exact same versions that you have used during development (similar to Cargo.lock in Rust).
To learn more about the package.json file format please refer to the official documentation.
Debug
With all the moving pieces in Tauri, you may run into a problem that requires debugging. There are many locations where error details are printed, and Tauri includes some tools to make the debugging process more straightforward.
Development Only Code
One of the most useful tools in your toolkit for debugging is the ability to add debugging statements in your code. However, you generally don’t want these to end up in production, which is where the ability to check whether you’re running in development mode or not comes in handy.
In Rust
fn main() {
// Whether the current instance was started with `tauri dev` or not.
#[cfg(dev)]
{
// `tauri dev` only code
}
if cfg!(dev) {
// `tauri dev` only code
} else {
// `tauri build` only code
}
let is_dev: bool = tauri::is_dev();
// Whether debug assertions are enabled or not. This is true for `tauri dev` and `tauri build --debug`.
#[cfg(debug_assertions)]
{
// Debug only code
}
if cfg!(debug_assertions) {
// Debug only code
} else {
// Production only code
}
}
Rust Console
The first place to look for errors is in the Rust Console. This is in the terminal where you ran, e.g., tauri dev. You can use the following code to print something to that console from within a Rust file:
println!("Message from Rust: {}", msg);
Sometimes you may have an error in your Rust code, and the Rust compiler can give you lots of information. If, for example, tauri dev crashes, you can rerun it like this on Linux and macOS:
RUST_BACKTRACE=1 tauri dev
or like this on Windows (PowerShell):
$env:RUST_BACKTRACE=1
tauri dev
This command gives you a granular stack trace. Generally speaking, the Rust compiler helps you by giving you detailed information about the issue, such as:
error[E0425]: cannot find value `sun` in this scope
--> src/main.rs:11:5
|
11 | sun += i.to_string().parse::<u64>().unwrap();
| ^^^ help: a local variable with a similar name exists: `sum`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0425`.
WebView Console
Right-click in the WebView, and choose Inspect Element. This opens up a web-inspector similar to the Chrome or Firefox dev tools you are used to. You can also use the Ctrl + Shift + i shortcut on Linux and Windows, and Command + Option + i on macOS to open the inspector.
The inspector is platform-specific, rendering the webkit2gtk WebInspector on Linux, Safari’s inspector on macOS and the Microsoft Edge DevTools on Windows.
Opening Devtools Programmatically
You can control the inspector window visibility by using the WebviewWindow::open_devtools and WebviewWindow::close_devtools functions:
tauri::Builder::default()
.setup(|app| {
#[cfg(debug_assertions)] // only include this code on debug builds
{
let window = app.get_webview_window("main").unwrap();
window.open_devtools();
window.close_devtools();
}
Ok(())
});
Using the Inspector in Production
By default, the inspector is only enabled in development and debug builds unless you enable it with a Cargo feature.
Create a Debug Build
To create a debug build, run the tauri build --debug command.
-
npm
npm run tauri build -- --debug -
yarn
yarn tauri build --debug -
pnpm
pnpm tauri build --debug -
deno
deno task tauri build --debug -
bun
bun tauri build --debug -
cargo
cargo tauri build --debug
Like the normal build and dev processes, building takes some time the first time you run this command but is significantly faster on subsequent runs. The final bundled app has the development console enabled and is placed in src-tauri/target/debug/bundle.
You can also run a built app from the terminal, giving you the Rust compiler notes (in case of errors) or your println messages. Browse to the file src-tauri/target/(release|debug)/[app name] and run it in directly in your console or double-click the executable itself in the filesystem (note: the console closes on errors with this method).
Enable Devtools Feature
Danger
The devtools API is private on macOS. Using private APIs on macOS prevents your application from being accepted to the App Store.
To enable the devtools in production builds, you must enable the devtools Cargo feature in the src-tauri/Cargo.toml file:
[dependencies]
tauri = { version = "...", features = ["...", "devtools"] }
Debugging the Core Process
The Core process is powered by Rust so you can use GDB or LLDB to debug it. You can follow the Debugging in VS Code guide to learn how to use the LLDB VS Code Extension to debug the Core Process of Tauri applications.
CrabNebula DevTools
CrabNebula provides a free DevTools application for Tauri as part of its partnership with the Tauri project. This application allows you to instrument your Tauri app by capturing its embedded assets, Tauri configuration file, logs and spans and providing a web frontend to seamlessly visualize data in real time.
With the CrabNebula DevTools you can inspect your app’s log events (including logs from dependencies), track down the performance of your command calls and overall Tauri API usage, with a special interface for Tauri events and commands, including payload, responses and inner logs and execution spans.
To enable the CrabNebula DevTools, install the devtools crate:
cargo add tauri-plugin-devtools@2.0.0
And initialize the plugin as soon as possible in your main function:
fn main() {
// This should be called as early in the execution of the app as possible
#[cfg(debug_assertions)] // only enable instrumentation in development builds
let devtools = tauri_plugin_devtools::init();
let mut builder = tauri::Builder::default();
#[cfg(debug_assertions)]
{
builder = builder.plugin(devtools);
}
builder
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
And then run your app as usual, if everything is set up correctly devtools will print the following message:
Note
In this case we only initialize the devtools plugin for debug applications, which is recommended.
For more information, see the CrabNebula DevTools documentation.
Linux Graphics Issues
On Linux, Tauri renders through WebKitGTK. On some setups, most often NVIDIA GPUs, WebKitGTK and the graphics driver disagree and you get anything from a blank window to subtle rendering problems. This page collects the known symptoms and workarounds. See tauri-apps/tauri#9394 for the original reports.
Common symptoms
- The window opens but stays blank or white.
- The window flickers, especially while resizing.
- The app dies on resize with no useful error output.
- Console shows
AcceleratedSurfaceDMABuf was unable to construct a complete framebuffer. - Console shows
Gdk-Message: Error 71 (Protocol error) dispatching to Wayland display.
Most of these come from the WebKitGTK DMABUF renderer requesting buffer formats the NVIDIA driver does not provide. See the WebKitGTK bug tracker and the NVIDIA forums for upstream discussion.
Workarounds
Try these in order. The earlier ones keep hardware acceleration.
- Make sure kernel mode setting is on. NVIDIA drivers older than 545 often need
nvidia_drm.modeset=1as a kernel parameter. - Set
__NV_DISABLE_EXPLICIT_SYNC=1. This often fixes the WaylandError 71crash without a performance cost. - Set
WEBKIT_DISABLE_DMABUF_RENDERER=1. Fixes the DMABUF framebuffer error and theError 71crash, at the cost of the faster rendering path. - Set
WEBKIT_DISABLE_COMPOSITING_MODE=1. Last resort for the silent crash on resize. This disables accelerated compositing entirely.
You can set these in your shell to test, or set them in main() before the webview is created so users do not have to:
fn main() {
// Workaround for WebKitGTK on NVIDIA, see tauri-apps/tauri#9394
#[cfg(target_os = "linux")]
std::env::set_var("WEBKIT_DISABLE_DMABUF_RENDERER", "1");
tauri::Builder::default()
// ...
}
Only ship an unconditional override like this if you have verified your app is affected. It disables a faster path for everyone, including users on working setups.
Silent failures: WebGL and canvas
Not every problem crashes or shows an error. WebGL and canvas content can silently land on a slow path while the rest of the app looks fine. Two things make this hard to detect from inside your frontend:
- WebGL2 context creation succeeds even when the result is backed by a software rasterizer or a slow presentation path. There is no error to catch.
- WebKitGTK masks the WebGL renderer string for fingerprinting protection.
WEBGL_debug_renderer_inforeportsApple GPUon every Linux machine, so you cannot check what is actually behind the context.
In practice this shows up as high input latency or low frame rates in WebGL heavy views (terminal emulators, editors, maps, charts), while the same code is fast in a regular browser. If your app has a WebGL rendering path, give it a non WebGL fallback on Linux and consider exposing a setting so users can switch, instead of trusting the context to tell you.
Debug in Neovim
There are many different plugins that can be used to debug Rust code in Neovim. This guide will show you how to set up nvim-dap and some additional plugins to debug Tauri application.
Prerequisites
nvim-dap extension requires codelldb binary. Download the version for your system from https://github.com/vadimcn/codelldb/releases and unzip it. We will point to it later in the nvim-dap configuration.
Configuring nvim-dap
Install nvim-dap and nvim-dap-ui plugins. Follow the instructions provided on their github pages or simply use your favourite plugin manager. Note that nvim-dap-ui requires nvim-nio plugin.
Next, setup the plugin in your Neovim configuration:
init.lua
local dap = require("dap")
dap.adapters.codelldb = {
type = 'server',
port = "${port}",
executable = {
-- Change this to your path!
command = '/opt/codelldb/adapter/codelldb',
args = {"--port", "${port}"},
}
}
dap.configurations.rust= {
{
name = "Launch file",
type = "codelldb",
request = "launch",
program = function()
return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/target/debug/', 'file')
end,
cwd = '${workspaceFolder}',
stopOnEntry = false
},
}
This setup will ask you to point to the Tauri App binary you want to debug each time you lanuch the debugger.
Optionally, you can setup nvim-dap-ui plugin to toggle debugger view automatically each time debugging session starts and stops:
init.lua
local dapui = require("dapui")
dapui.setup()
dap.listeners.before.attach.dapui_config = function()
dapui.open()
end
dap.listeners.before.launch.dapui_config = function()
dapui.open()
end
dap.listeners.before.event_terminated.dapui_config = function()
dapui.close()
end
dap.listeners.before.event_exited.dapui_config = function()
dapui.close()
end
Lastly, you can change the default way the breakpoints are displayed in the editor:
init.lua
vim.fn.sign_define('DapBreakpoint',{ text ='🟥', texthl ='', linehl ='', numhl =''})
vim.fn.sign_define('DapStopped',{ text ='▶️', texthl ='', linehl ='', numhl =''})
Starting the dev server
Since we’re not using Tauri CLI to launch the app the development server will not start automatically. To control the state of development server from Neovim you can use the overseer plugin.
Best way to control tasks running in background is to use VS Code style task configuration. To do this create a .vscode/tasks.json file in the projects directory.
You can find example task configuration for project using trunk below.
.vscode/tasks.json
{
"version": "2.0.0",
"tasks": [
{
"type": "process",
"label": "dev server",
"command": "trunk",
"args": ["serve"],
"isBackground": true,
"presentation": {
"revealProblems": "onProblem"
},
"problemMatcher": {
"pattern": {
"regexp": "^error:.*",
"file": 1,
"line": 2
},
"background": {
"activeOnStart": false,
"beginsPattern": ".*Rebuilding.*",
"endsPattern": ".*server listening at:.*"
}
}
}
]
}
Example key bindings
Below you can find example key bindings to start and control debugging sessions.
init.lua
vim.keymap.set('n', '<F5>', function() dap.continue() end)
vim.keymap.set('n', '<F6>', function() dap.disconnect({ terminateDebuggee = true }) end)
vim.keymap.set('n', '<F10>', function() dap.step_over() end)
vim.keymap.set('n', '<F11>', function() dap.step_into() end)
vim.keymap.set('n', '<F12>', function() dap.step_out() end)
vim.keymap.set('n', '<Leader>b', function() dap.toggle_breakpoint() end)
vim.keymap.set('n', '<Leader>o', function() overseer.toggle() end)
vim.keymap.set('n', '<Leader>R', function() overseer.run_template() end)
Debug in JetBrains IDEs
In this guide, we’ll be setting up JetBrains RustRover for debugging the Core Process of your Tauri app. It also mostly applies to IntelliJ and CLion.
Setting up a Cargo project
Depending on which frontend stack is used in a project, the project directory may or may not be a Cargo project. By default, Tauri places the Rust project in a subdirectory called src-tauri. It creates a Cargo project in the root directory only if Rust is used for frontend development as well.
If there’s no Cargo.toml file at the top level, you need to attach the project manually. Open the Cargo tool window (in the main menu, go to View | Tool Windows | Cargo), click + (Attach Cargo Project) on the toolbar, and select the src-tauri/Cargo.toml file.
Alternatively, you could create a top-level Cargo workspace manually by adding the following file to the project’s root directory:
Cargo.toml
[workspace]
members = ["src-tauri"]
Before you proceed, make sure that your project is fully loaded. If the Cargo tool window shows all the modules and targets of the workspace, you’re good to go.
Setting up Run Configurations
You will need to set up two separate Run/Debug configurations:
- one for launching the Tauri app in debugging mode,
- another one for running your frontend development server of choice.
Tauri App
- In the main menu, go to Run | Edit Configurations.
- In the Run/Debug Configurations dialog:
- To create a new configuration, click + on the toolbar and select Cargo.
With that created, we need to configure RustRover, so it instructs Cargo to build our app without any default features. This will tell Tauri to use your development server instead of reading assets from the disk. Normally this flag is passed by the Tauri CLI, but since we’re completely sidestepping that here, we need to pass the flag manually.
Now we can optionally rename the Run/Debug Configuration to something more memorable, in this example we called it “Run Tauri App”, but you can name it whatever you want.
Development Server
The above configuration will use Cargo directly to build the Rust application and attach the debugger to it. This means we completely sidestep the Tauri CLI, so features like the beforeDevCommand and beforeBuildCommand will not be executed. We need to take care of that by running the development server manually.
To create the corresponding Run configuration, you need to check the actual development server in use. Look for the src-tauri/tauri.conf.json file and find the following line:
"beforeDevCommand": "pnpm dev"
For npm, pnpm, or yarn, you could use the npm Run Configuration, for example:
Make sure you have the correct values in the Command, Scripts, and Package Manager fields.
If your development server is trunk for Rust-based WebAssembly frontend frameworks, you could use the generic Shell Script Run Configuration:
Launching a Debugging Session
To launch a debugging session, you first need to run your development server, and then start debugging the Tauri App by clicking the Debug button next to the Run Configurations Switcher. RustRover will automatically recognize breakpoints placed in any Rust file in your project and stop on the first one hit.
From this point, you can explore the values of your variables, step further into the code, and check what’s going at runtime in detail.
Debug in VS Code
This guide will walk you through setting up VS Code for debugging the Core Process of your Tauri app.
All platforms with vscode-lldb extension
Prerequisites
Install the vscode-lldb extension.
Configure launch.json
Create a .vscode/launch.json file and paste the below JSON contents into it:
.vscode/launch.json
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Tauri Development Debug",
"cargo": {
"args": [
"build",
"--manifest-path=./src-tauri/Cargo.toml",
"--no-default-features"
]
},
// task for the `beforeDevCommand` if used, must be configured in `.vscode/tasks.json`
"preLaunchTask": "ui:dev"
},
{
"type": "lldb",
"request": "launch",
"name": "Tauri Production Debug",
"cargo": {
"args": ["build", "--release", "--manifest-path=./src-tauri/Cargo.toml"]
},
// task for the `beforeBuildCommand` if used, must be configured in `.vscode/tasks.json`
"preLaunchTask": "ui:build"
}
]
}
This uses cargo directly to build the Rust application and load it in both development and production modes.
Note that it does not use the Tauri CLI, so exclusive CLI features are not executed. The beforeDevCommand and beforeBuildCommand scripts must be executed beforehand or configured as a task in the preLaunchTask field. Below is an example .vscode/tasks.json file that has two tasks, one for a beforeDevCommand that spawns a development server and one for beforeBuildCommand:
.vscode/tasks.json
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "ui:dev",
"type": "shell",
// `dev` keeps running in the background
// ideally you should also configure a `problemMatcher`
// see https://code.visualstudio.com/docs/editor/tasks#_can-a-background-task-be-used-as-a-prelaunchtask-in-launchjson
"isBackground": true,
// change this to your `beforeDevCommand`:
"command": "yarn",
"args": ["dev"]
},
{
"label": "ui:build",
"type": "shell",
// change this to your `beforeBuildCommand`:
"command": "yarn",
"args": ["build"]
}
]
}
Now you can set breakpoints in src-tauri/src/main.rs or any other Rust file and start debugging by pressing F5.
With Visual Studio Windows Debugger on Windows
Visual Studio Windows Debugger is a Windows-only debugger that is generally faster than vscode-lldb with better support for some Rust features such as enums.
Prerequisites
Install the C/C++ extension and follow https://code.visualstudio.com/docs/cpp/config-msvc#_prerequisites to install Visual Studio Windows Debugger.
Configure launch.json and tasks.json
.vscode/launch.json
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch App Debug",
"type": "cppvsdbg",
"request": "launch",
// change the exe name to your actual exe name
// (to debug release builds, change `target/debug` to `release/debug`)
"program": "${workspaceRoot}/src-tauri/target/debug/your-app-name-here.exe",
"cwd": "${workspaceRoot}",
"preLaunchTask": "ui:dev"
}
]
}
Note that it does not use the Tauri CLI, so exclusive CLI features are not executed. The tasks.json is the same as with lldb, except you need to add a config group and target your preLaunchTask from launch.json to it if you want it to always compile before launching.
Here is an example of running a dev server (equivalent of beforeDevCommand) and the compilation (cargo build) as a group, to use it, change the preLaunchTask config in launch.json to dev (or anything you named your group).
.vscode/tasks.json
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build:debug",
"type": "cargo",
"command": "build",
"options": {
"cwd": "${workspaceRoot}/src-tauri"
}
},
{
"label": "ui:dev",
"type": "shell",
// `dev` keeps running in the background
// ideally you should also configure a `problemMatcher`
// see https://code.visualstudio.com/docs/editor/tasks#_can-a-background-task-be-used-as-a-prelaunchtask-in-launchjson
"isBackground": true,
// change this to your `beforeDevCommand`:
"command": "yarn",
"args": ["dev"]
},
{
"label": "dev",
"dependsOn": ["build:debug", "ui:dev"],
"group": {
"kind": "build"
}
}
]
}
App Icons
Tauri ships with a default iconset based on its logo. This is NOT what you want when you ship your application. To remedy this common situation, Tauri provides the icon command that will take an input file ("./app-icon.png" by default) and create all the icons needed for the various platforms.
Note on filetypes
icon.icns= macOSicon.ico= Windows*.png= LinuxSquare*Logo.png&StoreLogo.png= Currently unused but intended for AppX/MS Store targets.
Some icon types may be used on platforms other than those listed above (especially png). Therefore we recommend including all icons even if you intend to only build for a subset of platforms.
Command Usage
-
npm
npm run tauri icon -
yarn
yarn tauri icon -
pnpm
pnpm tauri icon -
deno
deno task tauri icon -
cargo
cargo tauri icon
> pnpm tauri icon --help
Generate various icons for all major platforms
Usage: pnpm run tauri icon [OPTIONS] [INPUT]
Arguments:
[INPUT] Path to the source icon (squared PNG or SVG file with transparency) [default: ./app-icon.png]
Options:
-o, --output <OUTPUT> Output directory. Default: 'icons' directory next to the tauri.conf.json file
-v, --verbose... Enables verbose logging
-p, --png <PNG> Custom PNG icon sizes to generate. When set, the default icons are not generated
--ios-color <IOS_COLOR> The background color of the iOS icon - string as defined in the W3C's CSS Color Module Level 4 <https://www.w3.org/TR/css-color-4/> [default: #fff]
-h, --help Print help
-V, --version Print version
The desktop icons will be placed in your src-tauri/icons folder by default, where they will be included in your built app automatically. If you want to source your icons from a different location, you can edit this part of the tauri.conf.json file:
{
"bundle": {
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
]
}
}
The mobile icons will be placed into the Xcode and Android Studio projects directly!
Creating icons manually
If you prefer to build these icons yourself, for example if you want to have a simpler design for small sizes or because you don’t want to depend on the CLI’s internal image resizing, you must make sure your icons meet some requirements:
icon.icns: The required layer sizes and names for theicnsfile are described in the Tauri repoicon.ico: Theicofile must include layers for 16, 24, 32, 48, 64 and 256 pixels. For an optimal display of the ICO image in development, the 32px layer should be the first layer.png: The requirements for the png icons are: width == height, RGBA (RGB + Transparency), and 32bit per pixel (8bit per channel). Commonly expected sizes on desktop are 32, 128, 256, and 512 pixels. We recommend to at least match the output oftauri icon:32x32.png,128x128.png,128x128@2x.png, andicon.png.
Android
On Android you will need png icons with the same requirements but in different sizes. They will also need to be placed directly in the Android Studio project:
-
src-tauri/gen/android/app/src/main/res/-
mipmap-hdpi/ic_launcher.png&ic_launcher_round.png: 49x49pxic_launcher_foreground.png: 162x162px
-
mipmap-mdpi/ic_launcher.png&ic_launcher_round.png: 48x48pxic_launcher_foreground.png: 108x108px
-
mipmap-xhdpi/ic_launcher.png&ic_launcher_round.png: 96x96pxic_launcher_foreground.png: 216x216px
-
mipmap-xxhdpi/ic_launcher.png&ic_launcher_round.png: 144x144pxic_launcher_foreground.png: 324x324px
-
mipmap-xxxhdpi/ic_launcher.png&ic_launcher_round.png: 192x192pxic_launcher_foreground.png: 432x432px
-
If tauri icon cannot be used, we recommend checking out Android Studio’s Image Asset Studio instead.
iOS
On iOS you will need png icons with the same requirements but without transparency and in different sizes. They will also need to be placed directly in the Xcode project into src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/. The following icons are expected:
- 20px in 1x, 2x, 3x, with an extra icon
- 29px in 1x, 2x, 3x, with an extra icon
- 40px in 1x, 2x, 3x, with an extra icon
- 60px in 2x, 3x
- 76px in 1x, 2x
- 83.5px in 2x
- 512px in 2x saved as
AppIcon-512@2x.png
The file names are in the format of AppIcon-{size}x{size}@{scaling}{extra}.png. For the 20px icons this means you need icons in sizes 20x20, 40x40 and 60x60 named as AppIcon-20x20@1x.png, AppIcon-20x20@2x.png, AppIcon-20x20@3x.png and 2x saved additionally as AppIcon-20x20@2x-1.png (“extra icon”).
Plugin Development
Plugin Development
This guide is for developing Tauri plugins. If you’re looking for a list of the currently available plugins and how to use them then visit the Features and Recipes list.
Plugins are able to hook into the Tauri lifecycle, expose Rust code that relies on the web view APIs, handle commands with Rust, Kotlin or Swift code, and much more.
Tauri offers a windowing system with web view functionality, a way to send messages between the Rust process and the web view, and an event system along with several tools to enhance the development experience. By design, the Tauri core does not contain features not needed by everyone. Instead it offers a mechanism to add external functionalities into a Tauri application called plugins.
A Tauri plugin is composed of a Cargo crate and an optional NPM package that provides API bindings for its commands and events. Additionally, a plugin project can include an Android library project and a Swift package for iOS. You can learn more about developing plugins for Android and iOS in the Mobile Plugin Development guide.
Naming Convention
Tauri plugins have a prefix followed by the plugin name. The plugin name is specified on the plugin configuration under tauri.conf.json > plugins.
By default Tauri prefixes your plugin crate with tauri-plugin-. This helps your plugin to be discovered by the Tauri community and to be used with the Tauri CLI. When initializing a new plugin project, you must provide its name. The generated crate name will be tauri-plugin-{plugin-name} and the JavaScript NPM package name will be tauri-plugin-{plugin-name}-api (although we recommend using an NPM scope if possible). The Tauri naming convention for NPM packages is @scope-name/plugin-{plugin-name}.
Initialize Plugin Project
To bootstrap a new plugin project, run plugin new. If you do not need the NPM package, use the --no-api CLI flag. If you want to initialize the plugin with Android and/or iOS support, use the --android and/or --ios flags.
After installing, you can run the following to create a plugin project:
-
npm
npx @tauri-apps/cli plugin new [name]
This will initialize the plugin at the directory tauri-plugin-[name] and, depending on the used CLI flags, the resulting project will look like this:
. tauri-plugin-[name]/
├── src/ - Rust code
│ ├── commands.rs - Defines the commands the webview can use
| ├── desktop.rs - Desktop implementation
| ├── error.rs - Default error type to use in returned results
│ ├── lib.rs - Re-exports appropriate implementation, setup state...
│ ├── mobile.rs - Mobile implementation
│ └── models.rs - Shared structs
├── permissions/ - This will host (generated) permission files for commands
├── android - Android library
├── ios - Swift package
├── guest-js - Source code of the JavaScript API bindings
├── dist-js - Transpiled assets from guest-js
├── Cargo.toml - Cargo crate metadata
└── package.json - NPM package metadata
If you have an existing plugin and would like to add Android or iOS capabilities to it, you can use plugin android add and plugin ios add to bootstrap the mobile library projects and guide you through the changes needed.
Declaring Platform Support
Plugins can declare which platforms they support, and to what extent, in the [package.metadata.platforms.support] section of the crate’s Cargo.toml:
Cargo.toml
[package.metadata.platforms.support]
windows = { level = "full" }
linux = { level = "full" }
macos = { level = "full" }
android = { level = "partial", notes = "Access is restricted to the Application folder by default" }
ios = { level = "none" }
Each key is a platform (windows, linux, macos, android, ios) and accepts two fields:
level(required):"full"if the plugin works as intended,"partial"if it works with limitations, or"none"if the platform isn’t supported.notes(optional): a short description of the caveats or limitations. It renders as Markdown on the plugin’s page. In the support table it shows up as plain text in a tooltip.
The support table and the platform filter on the Features & Recipes page are generated from this metadata.
Mobile Plugin Development
Plugins can run native mobile code written in Kotlin (or Java) and Swift. The default plugin template includes an Android library project using Kotlin and a Swift package. It includes an example mobile command showing how to trigger its execution from Rust code.
Read more about developing plugins for mobile in the Mobile Plugin Development guide.
Plugin Configuration
In the Tauri application where the plugin is used, the plugin configuration is specified on tauri.conf.json where plugin-name is the name of the plugin:
{
"build": { ... },
"tauri": { ... },
"plugins": {
"plugin-name": {
"timeout": 30
}
}
}
The plugin’s configuration is set on the Builder and is parsed at runtime. Here is an example of the Config struct being used to specify the plugin configuration:
src/lib.rs
use serde::Deserialize;
use tauri::{
plugin::{Builder, TauriPlugin},
Runtime,
};
// Define the plugin config
#[derive(Deserialize)]
pub struct Config {
timeout: usize,
}
pub fn init<R: Runtime>() -> TauriPlugin<R, Config> {
// Make the plugin config optional
// by using `Builder::<R, Option<Config>>` instead
Builder::<R, Config>::new("<plugin-name>")
.setup(|app, api| {
let timeout = api.config().timeout;
Ok(())
})
.build()
}
Lifecycle Events
Plugins can hook into several lifecycle events:
- setup: Plugin is being initialized
- on_navigation: Web view is attempting to perform navigation
- on_webview_ready: New window is being created
- on_event: Event loop events
- on_drop: Plugin is being deconstructed
There are additional lifecycle events for mobile plugins.
setup
- When: Plugin is being initialized
- Why: Register mobile plugins, manage state, run background tasks
src/lib.rs
use tauri::{Manager, plugin::Builder};
use std::{collections::HashMap, sync::Mutex, time::Duration};
struct DummyStore(Mutex<HashMap<String, String>>);
Builder::new("<plugin-name>")
.setup(|app, api| {
app.manage(DummyStore(Default::default()));
let app_ = app.clone();
std::thread::spawn(move || {
loop {
app_.emit("tick", ());
std::thread::sleep(Duration::from_secs(1));
}
});
Ok(())
})
on_navigation
- When: Web view is attempting to perform navigation
- Why: Validate the navigation or track URL changes
Returning false cancels the navigation.
src/lib.rs
use tauri::plugin::Builder;
Builder::new("<plugin-name>")
.on_navigation(|window, url| {
println!("window {} is navigating to {}", window.label(), url);
// Cancels the navigation if forbidden
url.scheme() != "forbidden"
})
on_webview_ready
- When: New window has been created
- Why: Execute an initialization script for every window
src/lib.rs
use tauri::plugin::Builder;
Builder::new("<plugin-name>")
.on_webview_ready(|window| {
window.listen("content-loaded", |event| {
println!("webview content has been loaded");
});
})
on_event
- When: Event loop events
- Why: Handle core events such as window events, menu events and application exit requested
With this lifecycle hook you can be notified of any event loop events.
src/lib.rs
use std::{collections::HashMap, fs::write, sync::Mutex};
use tauri::{plugin::Builder, Manager, RunEvent};
struct DummyStore(Mutex<HashMap<String, String>>);
Builder::new("<plugin-name>")
.setup(|app, _api| {
app.manage(DummyStore(Default::default()));
Ok(())
})
.on_event(|app, event| {
match event {
RunEvent::ExitRequested { api, .. } => {
// user requested a window to be closed and there's no windows left
// we can prevent the app from exiting:
api.prevent_exit();
}
RunEvent::Exit => {
// app is going to exit, you can cleanup here
let store = app.state::<DummyStore>();
write(
app.path().app_local_data_dir().unwrap().join("store.json"),
serde_json::to_string(&*store.0.lock().unwrap()).unwrap(),
)
.unwrap();
}
_ => {}
}
})
on_drop
- When: Plugin is being deconstructed
- Why: Execute code when the plugin has been destroyed
See Drop for more information.
src/lib.rs
use tauri::plugin::Builder;
Builder::new("<plugin-name>")
.on_drop(|app| {
// plugin has been destroyed...
})
Exposing Rust APIs
The plugin APIs defined in the project’s desktop.rs and mobile.rs are exported to the user as a struct with the same name as the plugin (in pascal case). When the plugin is setup, an instance of this struct is created and managed as a state so that users can retrieve it at any point in time with a Manager instance (such as AppHandle, App, or Window) through the extension trait defined in the plugin.
For example, the global-shortcut plugin defines a GlobalShortcut struct that can be read by using the global_shortcut method of the GlobalShortcutExt trait:
src-tauri/src/lib.rs
use tauri_plugin_global_shortcut::GlobalShortcutExt;
tauri::Builder::default()
.plugin(tauri_plugin_global_shortcut::init())
.setup(|app| {
app.global_shortcut().register(...);
Ok(())
})
Adding Commands
Commands are defined in the commands.rs file. They are regular Tauri applications commands. They can access the AppHandle and Window instances directly, access state, and take input the same way as application commands. Read the Commands guide for more details on Tauri commands.
This command shows how to get access to the AppHandle and Window instance via dependency injection, and takes two input parameters (on_progress and url):
src/commands.rs
use tauri::{command, ipc::Channel, AppHandle, Runtime, Window};
#[command]
async fn upload<R: Runtime>(app: AppHandle<R>, window: Window<R>, on_progress: Channel, url: String) {
// implement command logic here
on_progress.send(100).unwrap();
}
To expose the command to the webview, you must hook into the invoke_handler() call in lib.rs:
src/lib.rs
Builder::new("<plugin-name>")
.invoke_handler(tauri::generate_handler![commands::upload])
Define a binding function in webview-src/index.ts so that plugin users can easily call the command in JavaScript:
import { invoke, Channel } from '@tauri-apps/api/core'
export async function upload(url: string, onProgressHandler: (progress: number) => void): Promise<void> {
const onProgress = new Channel<number>()
onProgress.onmessage = onProgressHandler
await invoke('plugin:<plugin-name>|upload', { url, onProgress })
}
Be sure to build the TypeScript code prior to testing it.
Command Permissions
By default your commands are not accessible by the frontend. If you try to execute one of them, you will get a denied error rejection. To actually expose commands, you also need to define permissions that allow each command.
Permission Files
Permissions are defined as JSON or TOML files inside the permissions directory. Each file can define a list of permissions, a list of permission sets and your plugin’s default permission.
Permissions
A permission describes privileges of your plugin commands. It can allow or deny a list of commands and associate command-specific and global scopes.
permissions/start-server.toml
"$schema" = "schemas/schema.json"
[[permission]]
identifier = "allow-start-server"
description = "Enables the start_server command."
commands.allow = ["start_server"]
[[permission]]
identifier = "deny-start-server"
description = "Denies the start_server command."
commands.deny = ["start_server"]
Scope
Scopes allow your plugin to define deeper restrictions to individual commands. Each permission can define a list of scope objects that define something to be allowed or denied either specific to a command or globally to the plugin.
Let’s define an example struct that will hold scope data for a list of binaries a shell plugin is allowed to spawn:
src/scope.rs
#[derive(Debug, schemars::JsonSchema)]
pub struct Entry {
pub binary: String,
}
Command Scope
Your plugin consumer can define a scope for a specific command in their capability file (see the documentation). You can read the command-specific scope with the tauri::ipc::CommandScope struct:
src/commands.rs
use tauri::ipc::CommandScope;
use crate::scope::Entry;
async fn spawn<R: tauri::Runtime>(app: tauri::AppHandle<R>, command_scope: CommandScope<'_, Entry>) -> Result<()> {
let allowed = command_scope.allows();
let denied = command_scope.denies();
todo!()
}
Global Scope
When a permission does not define any commands to be allowed or denied, it’s considered a scope permission and it should only define a global scope for your plugin:
permissions/spawn-node.toml
[[permission]]
identifier = "allow-spawn-node"
description = "This scope permits spawning the `node` binary."
[[permission.scope.allow]]
binary = "node"
You can read the global scope with the tauri::ipc::GlobalScope struct:
src/commands.rs
use tauri::ipc::GlobalScope;
use crate::scope::Entry;
async fn spawn<R: tauri::Runtime>(app: tauri::AppHandle<R>, scope: GlobalScope<'_, Entry>) -> Result<()> {
let allowed = scope.allows();
let denied = scope.denies();
todo!()
}
Note
We recommend checking both global and command scopes for flexibility
Schema
The scope entry requires the schemars dependency to generate a JSON schema so the plugin consumers know the format of the scope and have autocomplete in their IDEs.
To define the schema, first add the dependency to your Cargo.toml file:
# we need to add schemars to both dependencies and build-dependencies because the scope.rs module is shared between the app code and build script
[dependencies]
schemars = "0.8"
[build-dependencies]
schemars = "0.8"
In your build script, add the following code:
build.rs
#[path = "src/scope.rs"]
mod scope;
const COMMANDS: &[&str] = &[];
fn main() {
tauri_plugin::Builder::new(COMMANDS)
.global_scope_schema(schemars::schema_for!(scope::Entry))
.build();
}
Permission Sets
Permission sets are groups of individual permissions that helps users manage your plugin with a higher level of abstraction. For instance if a single API uses multiple commands or if there’s a logical connection between a collection of commands, you should define a set containing them:
permissions/websocket.toml
"$schema" = "schemas/schema.json"
[[set]]
identifier = "allow-websocket"
description = "Allows connecting and sending messages through a WebSocket"
permissions = ["allow-connect", "allow-send"]
Default Permission
The default permission is a special permission set with identifier default. It’s recommended that you enable required commands by default. For instance the http plugin is useless without the request command allowed:
permissions/default.toml
"$schema" = "schemas/schema.json"
[default]
description = "Allows making HTTP requests"
permissions = ["allow-request"]
Autogenerated Permissions
The easiest way to define permissions for each of your commands is to use the autogeneration option defined in your plugin’s build script defined in the build.rs file. Inside the COMMANDS const, define the list of commands in snake_case (should match the command function name) and Tauri will automatically generate an allow-$commandname and a deny-$commandname permissions.
The following example generates the allow-upload and deny-upload permissions:
src/commands.rs
const COMMANDS: &[&str] = &["upload"];
fn main() {
tauri_plugin::Builder::new(COMMANDS).build();
}
See the Permissions Overview documentation for more information.
Managing State
A plugin can manage state in the same way a Tauri application does. Read the State Management guide for more information.
Mobile Plugin Development
Plugin Development
Be sure that you’re familiar with the concepts covered in the Plugin Development guide as many concepts in this guide build on top of foundations covered there.
Plugins can run native mobile code written in Kotlin (or Java) and Swift. The default plugin template includes an Android library project using Kotlin and a Swift package including an example mobile command showing how to trigger its execution from Rust code.
Initialize Plugin Project
Follow the steps in the Plugin Development guide to initialize a new plugin project.
If you have an existing plugin and would like to add Android or iOS capabilities to it, you can use plugin android init and plugin ios init to bootstrap the mobile library projects and guide you through the changes needed.
The default plugin template splits the plugin’s implementation into two separate modules: desktop.rs and mobile.rs.
The desktop implementation uses Rust code to implement a functionality, while the mobile implementation sends a message to the native mobile code to execute a function and get a result back. If shared logic is needed across both implementations, it can be defined in lib.rs:
src/lib.rs
use tauri::Runtime;
impl<R: Runtime> <plugin-name><R> {
pub fn do_something(&self) {
// do something that is a shared implementation between desktop and mobile
}
}
This implementation simplifies the process of sharing an API that can be used both by commands and Rust code.
Develop an Android Plugin
A Tauri plugin for Android is defined as a Kotlin class that extends app.tauri.plugin.Plugin and is annotated with app.tauri.annotation.TauriPlugin. Each method annotated with app.tauri.annotation.Command can be called by Rust or JavaScript.
Tauri uses Kotlin by default for the Android plugin implementation, but you can switch to Java if you prefer. After generating a plugin, right click the Kotlin plugin class in Android Studio and select the “Convert Kotlin file to Java file” option from the menu. Android Studio will guide you through the project migration to Java.
Develop an iOS Plugin
A Tauri plugin for iOS is defined as a Swift class that extends the Plugin class from the Tauri package. Each function with the @objc attribute and the (_ invoke: Invoke) parameter (for example @objc private func download(_ invoke: Invoke) { }) can be called by Rust or JavaScript.
The plugin is defined as a Swift package so that you can use its package manager to manage dependencies.
Plugin Configuration
Refer to the Plugin Configuration section of the Plugin Development guide for more details on developing plugin configurations.
The plugin instance on mobile has a getter for the plugin configuration:
-
Android
import android.app.Activity import android.webkit.WebView import app.tauri.annotation.TauriPlugin import app.tauri.annotation.InvokeArg @InvokeArg class Config { var timeout: Int? = 3000 } @TauriPlugin class ExamplePlugin(private val activity: Activity): Plugin(activity) { private var timeout: Int? = 3000 override fun load(webView: WebView) { getConfig(Config::class.java).let { this.timeout = it.timeout } } } -
iOS
struct Config: Decodable { let timeout: Int? } class ExamplePlugin: Plugin { var timeout: Int? = 3000 @objc public override func load(webview: WKWebView) { do { let config = try parseConfig(Config.self) self.timeout = config.timeout } catch {} } }
Lifecycle Events
Plugins can hook into several lifecycle events:
- load: When the plugin is loaded into the web view
- onNewIntent: Android only, when the activity is re-launched
There are also the additional lifecycle events for plugins in the Plugin Development guide.
load
- When: When the plugin is loaded into the web view
- Why: Execute plugin initialization code
-
Android
import android.app.Activity import android.webkit.WebView import app.tauri.annotation.TauriPlugin @TauriPlugin class ExamplePlugin(private val activity: Activity): Plugin(activity) { override fun load(webView: WebView) { // perform plugin setup here } } -
iOS
class ExamplePlugin: Plugin { @objc public override func load(webview: WKWebView) { let timeout = self.config["timeout"] as? Int ?? 30 } }
onNewIntent
Note: This is only available on Android.
- When: When the activity is re-launched. See Activity#onNewIntent for more information.
- Why: Handle application re-launch such as when a notification is clicked or a deep link is accessed.
import android.app.Activity
import android.content.Intent
import app.tauri.annotation.TauriPlugin
@TauriPlugin
class ExamplePlugin(private val activity: Activity): Plugin(activity) {
override fun onNewIntent(intent: Intent) {
// handle new intent event
}
}
Adding Mobile Commands
There is a plugin class inside the respective mobile projects where commands can be defined that can be called by the Rust code:
-
Android
import android.app.Activity import app.tauri.annotation.Command import app.tauri.annotation.TauriPlugin @TauriPlugin class ExamplePlugin(private val activity: Activity): Plugin(activity) { @Command fun openCamera(invoke: Invoke) { val ret = JSObject() ret.put("path", "/path/to/photo.jpg") invoke.resolve(ret) } }If you want to use a Kotlin
suspendfunction, you need to use a custom coroutine scopeimport android.app.Activity import app.tauri.annotation.Command import app.tauri.annotation.TauriPlugin // Change to Dispatchers.IO if it is intended for fetching data val scope = CoroutineScope(Dispatchers.Default + SupervisorJob()) @TauriPlugin class ExamplePlugin(private val activity: Activity): Plugin(activity) { @Command fun openCamera(invoke: Invoke) { scope.launch { openCameraInner(invoke) } } private suspend fun openCameraInner(invoke: Invoke) { val ret = JSObject() ret.put("path", "/path/to/photo.jpg") invoke.resolve(ret) } }Note
On Android native commands are scheduled on the main thread. Performing long-running operations will cause the UI to freeze and potentially “Application Not Responding” (ANR) error.
If you need to wait for some blocking IO, you can launch a corouting like that:
CoroutineScope(Dispatchers.IO).launch { val result = myLongRunningOperation() invoke.resolve(result) } -
iOS
class ExamplePlugin: Plugin { @objc public func openCamera(_ invoke: Invoke) throws { invoke.resolve(["path": "/path/to/photo.jpg"]) } }
Use the tauri::plugin::PluginHandle to call a mobile command from Rust:
use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use tauri::Runtime;
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CameraRequest {
quality: usize,
allow_edit: bool,
}
#[derive(Deserialize)]
pub struct Photo {
path: PathBuf,
}
impl<R: Runtime> <plugin-name;pascal-case><R> {
pub fn open_camera(&self, payload: CameraRequest) -> crate::Result<Photo> {
self
.0
.run_mobile_plugin("openCamera", payload)
.map_err(Into::into)
}
}
Command Arguments
Arguments are serialized to commands and can be parsed on the mobile plugin with the Invoke::parseArgs function, taking a class describing the argument object.
Android
On Android, the arguments are defined as a class annotated with @app.tauri.annotation.InvokeArg. Inner objects must also be annotated:
import android.app.Activity
import android.webkit.WebView
import app.tauri.annotation.Command
import app.tauri.annotation.InvokeArg
import app.tauri.annotation.TauriPlugin
@InvokeArg
internal class OpenAppArgs {
lateinit var name: String
var timeout: Int? = null
}
@InvokeArg
internal class OpenArgs {
lateinit var requiredArg: String
var allowEdit: Boolean = false
var quality: Int = 100
var app: OpenAppArgs? = null
}
@TauriPlugin
class ExamplePlugin(private val activity: Activity): Plugin(activity) {
@Command
fun openCamera(invoke: Invoke) {
val args = invoke.parseArgs(OpenArgs::class.java)
}
}
Note
Optional arguments are defined as var <argumentName>: Type? = null
Arguments with default values are defined as var <argumentName>: Type = <default-value>
Required arguments are defined as lateinit var <argumentName>: Type
iOS
On iOS, the arguments are defined as a class that inherits Decodable. Inner objects must also inherit the Decodable protocol:
class OpenAppArgs: Decodable {
let name: String
var timeout: Int?
}
class OpenArgs: Decodable {
let requiredArg: String
var allowEdit: Bool?
var quality: UInt8?
var app: OpenAppArgs?
}
class ExamplePlugin: Plugin {
@objc public func openCamera(_ invoke: Invoke) throws {
let args = try invoke.parseArgs(OpenArgs.self)
invoke.resolve(["path": "/path/to/photo.jpg"])
}
}
Note
Optional arguments are defined as var <argumentName>: Type?
Arguments with default values are NOT supported. Use a nullable type and set the default value on the command function instead.
Required arguments are defined as let <argumentName>: Type
Calling Rust From Mobile Plugins
It is often preferable to write plugin code in Rust, for performance and reusability. While Tauri doesn’t directly provide a mechanism to call Rust from your plugin code, using JNI on Android and FFI on iOS allows plugins to call shared code, even when the application WebView is suspended.
Android
In your plugin’s Cargo.toml, add the jni crate as a dependency:
[target.'cfg(target_os = "android")'.dependencies]
jni = "0.21"
Load the application library statically and define native functions in your Kotlin code. In this example, the Kotlin class is com.example.HelloWorld, we need to reference the full package name from the Rust side.
private const val TAG = "MyPlugin"
init {
try {
// Load the native library (libapp_lib.so)
// This is the shared library built by Cargo with crate-type = ["cdylib"]
System.loadLibrary("app_lib")
Log.d(TAG, "Successfully loaded libapp_lib.so")
} catch (e: UnsatisfiedLinkError) {
Log.e(TAG, "Failed to load libapp_lib.so", e)
throw e
}
}
external fun helloWorld(name: String): String?
Then in your plugin’s Rust code, define the function JNI will look for. The function format is Java_package_class_method, so for our class above this becomes Java_com_example_HelloWorld_helloWorld to get called by our helloWorld method:
#[cfg(target_os = "android")]
#[no_mangle]
pub extern "system" fn Java_com_example_HelloWorld_helloWorld(
mut env: JNIEnv,
_class: JClass,
name: JString,
) -> jstring {
log::debug!("Calling JNI Hello World!");
let result = format!("Hello, {}!", name);
match env.new_string(result) {
Ok(jstr) => jstr.into_raw(),
Err(e) => {
log::error!("Failed to create JString: {}", e);
std::ptr::null_mut()
}
}
}
iOS
iOS only uses standard C FFI, so doesn’t need any new dependencies. Add the hook in your Swift code, as well as any necessary cleanup. These functions can be named anything valid, but must be annotated with @_silgen_name(FFI_FUNC), where FFI_FUNC is a function name to be called from Rust:
@_silgen_name("hello_world_ffi")
private static func helloWorldFFI(_ name: UnsafePointer<CChar>) -> UnsafeMutablePointer<CChar>?
@_silgen_name("free_hello_result_ffi")
private static func freeHelloResult(_ result: UnsafeMutablePointer<CChar>)
static func helloWorld(name: String) -> String? {
// Call Rust FFI
let resultPtr = name.withCString({ helloWorldFFI($0) })
// Convert C string to Swift String
let result = String(cString: resultPtr)
// Free the C string
freeHelloResult(resultPtr)
return result
}
Then, implement the Rust side. The extern functions here must match the @_silgen_name annotations on the Swift side:
#[no_mangle]
pub unsafe extern "C" fn hello_world_ffi(c_name: *const c_char) -> *mut c_char {
let name = match CStr::from_ptr(c_name).to_str() {
Ok(s) => s,
Err(e) => {
log::error!("[iOS FFI] Failed to convert C string: {}", e);
return std::ptr::null_mut();
}
};
let result = format!("Hello, {}!", name);
match CString::new(result) {
Ok(c_str) => c_str.into_raw(),
Err(e) => {
log::error!("[iOS FFI] Failed to create C string: {}", e);
std::ptr::null_mut()
}
}
}
#[no_mangle]
pub unsafe extern "C" fn free_hello_result_ffi(result: *mut c_char) {
if !result.is_null() {
drop(CString::from_raw(result));
}
}
Android 16KB Memory Pages
Google is moving to make 16KB memory pages a requirement in all new Android app submissions. Building with an NDK version 28 or higher should automatically generate bundles that meet this requirement, but in the event an older NDK version must be used or generated files aren’t 16KB aligned, the following can be added to .cargo/config.toml to flag this to rustc:
[target.aarch64-linux-android]
rustflags = ["-C", "link-arg=-Wl,-z,max-page-size=16384"]
Permissions
If a plugin requires permissions from the end user, Tauri simplifies the process of checking and requesting permissions.
-
Android
First define the list of permissions needed and an alias to identify each group in code. This is done inside the
TauriPluginannotation:@TauriPlugin( permissions = [ Permission(strings = [Manifest.permission.POST_NOTIFICATIONS], alias = "postNotification") ] ) class ExamplePlugin(private val activity: Activity): Plugin(activity) { } -
iOS
First override the
checkPermissionsandrequestPermissionsfunctions:class ExamplePlugin: Plugin { @objc open func checkPermissions(_ invoke: Invoke) { invoke.resolve(["postNotification": "prompt"]) } @objc public override func requestPermissions(_ invoke: Invoke) { // request permissions here // then resolve the request invoke.resolve(["postNotification": "granted"]) } }
Tauri automatically implements two commands for the plugin: checkPermissions and requestPermissions. Those commands can be directly called from JavaScript or Rust:
-
JavaScript
import { invoke, PermissionState } from '@tauri-apps/api/core' interface Permissions { postNotification: PermissionState } // check permission state const permission = await invoke<Permissions>('plugin:<plugin-name>|checkPermissions') if (permission.postNotification === 'prompt-with-rationale') { // show information to the user about why permission is needed } // request permission if (permission.postNotification.startsWith('prompt')) { const state = await invoke<Permissions>('plugin:<plugin-name>|requestPermissions', { permissions: ['postNotification'] }) } -
Rust
use serde::{Serialize, Deserialize}; use tauri::{plugin::PermissionState, Runtime}; #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct PermissionResponse { pub post_notification: PermissionState, } #[derive(Serialize)] #[serde(rename_all = "camelCase")] struct RequestPermission { post_notification: bool, } impl<R: Runtime> Notification<R> { pub fn request_post_notification_permission(&self) -> crate::Result<PermissionState> { self.0 .run_mobile_plugin::<PermissionResponse>("requestPermissions", RequestPermission { post_notification: true }) .map(|r| r.post_notification) .map_err(Into::into) } pub fn check_permissions(&self) -> crate::Result<PermissionResponse> { self.0 .run_mobile_plugin::<PermissionResponse>("checkPermissions", ()) .map_err(Into::into) } }
Plugin Events
Plugins can emit events at any point of time using the trigger function:
-
Android
@TauriPlugin class ExamplePlugin(private val activity: Activity): Plugin(activity) { override fun load(webView: WebView) { trigger("load", JSObject()) } override fun onNewIntent(intent: Intent) { // handle new intent event if (intent.action == Intent.ACTION_VIEW) { val data = intent.data.toString() val event = JSObject() event.put("data", data) trigger("newIntent", event) } } @Command fun openCamera(invoke: Invoke) { val payload = JSObject() payload.put("open", true) trigger("camera", payload) } } -
iOS
class ExamplePlugin: Plugin { @objc public override func load(webview: WKWebView) { trigger("load", data: [:]) } @objc public func openCamera(_ invoke: Invoke) { trigger("camera", data: ["open": true]) } }
The helper functions can then be called from the NPM package by using the addPluginListener helper function:
import { addPluginListener, PluginListener } from '@tauri-apps/api/core';
export async function onRequest(
handler: (url: string) => void
): Promise<PluginListener> {
return await addPluginListener(
'<plugin-name>',
'event-name',
handler
);
}
Capability Required
Listening to plugin events from JavaScript is gated by the same capability and permission system that gates plugin commands. Add the plugin’s permission (commonly <plugin-name>:default, or a specific allow-listen-* permission if the plugin defines one) to the permissions array of a capability under src-tauri/capabilities/:
src-tauri/capabilities/default.json
{
"identifier": "default",
"windows": ["main"],
"permissions": ["<plugin-name>:default"]
}
Refer to the plugin’s own documentation for the exact permission identifiers it exposes.
Embedding Additional Files
You may need to include additional files in your application bundle that aren’t part of your frontend (your frontendDist) directly or which are too big to be inlined into the binary. We call these files resources.
Configuration
To bundle the files of your choice, add the resources property to the bundle object in your tauri.conf.json file.
To include a list of files:
-
Syntax
tauri.conf.json
{ "bundle": { "resources": [ "./path/to/some-file.txt", "/absolute/path/to/textfile.txt", "../relative/path/to/jsonfile.json", "some-folder/", "resources/**/*.md" ] } } -
Explanation
tauri.conf.json5
{ "bundle": { "resources": [ // Will be placed to `$RESOURCE/path/to/some-file.txt` "./path/to/some-file.txt", // The root in an absolute path will be replaced by `_root_`, // so `textfile.txt` will be placed to `$RESOURCE/_root_/absolute/path/to/textfile.txt` "/absolute/path/to/textfile.txt", // `..` in a relative path will be replaced by `_up_`, // so `jsonfile.json` will be placed to `$RESOURCE/_up_/relative/path/to/textfile.txt`, "../relative/path/to/jsonfile.json", // If the path is a directory, the entire directory will be copied to the `$RESOURCE` directory, // preserving the original structures, for example: // - `some-folder/file.txt` -> `$RESOURCE/some-folder/file.txt` // - `some-folder/another-folder/config.json` -> `$RESOURCE/some-folder/another-folder/config.json` // This is the same as `some-folder/**/*` "some-folder/", // You can also include multiple files at once through glob patterns. // All the `.md` files inside `resources` will be placed to `$RESOURCE/resources/`, // preserving their original directory structures, for example: // - `resources/index.md` -> `$RESOURCE/resources/index.md` // - `resources/docs/setup.md` -> `$RESOURCE/resources/docs/setup.md` "resources/**/*.md" ] } }
The bundled files will be in $RESOURCES/ with the original directory structure preserved, for example: ./path/to/some-file.txt -> $RESOURCE/path/to/some-file.txt
To fine control where the files will get copied to, use a map instead:
-
Syntax
tauri.conf.json
{ "bundle": { "resources": { "/absolute/path/to/textfile.txt": "resources/textfile.txt", "relative/path/to/jsonfile.json": "resources/jsonfile.json", "resources/": "", "docs/**/*md": "website-docs/" } } } -
Explanation
tauri.conf.json5
{ "bundle": { "resources": { // `textfile.txt` will be placed to `$RESOURCE/resources/textfile.txt` "/absolute/path/to/textfile.txt": "resources/textfile.txt", // `jsonfile.json` will be placed to `$RESOURCE/resources/jsonfile.json` "relative/path/to/jsonfile.json": "resources/jsonfile.json", // Copy the entire directory to `$RESOURCE`, preserving the original structures, // the target is "" which means it will be placed directly in the resource directory `$RESOURCE`, for example: // - `resources/file.txt` -> `$RESOURCE/file.txt` // - `resources/some-folder/config.json` -> `$RESOURCE/some-folder/config.json` "resources/": "", // When using glob patterns, the behavior is different from the list one, // all the matching files will be placed to the target directory without preserving the original file structures // for example: // - `docs/index.md` -> `$RESOURCE/website-docs/index.md` // - `docs/plugins/setup.md` -> `$RESOURCE/website-docs/setup.md` "docs/**/*md": "website-docs/" } } }
To learn about where $RESOURCE resolves to on each platforms, see the documentation of resource_dir
Source path syntax
In the following explanations “target resource directory” is either the value after the colon in the object notation, or a reconstruction of the original file paths in the array notation.
"dir/file.txt": copies thefile.txtfile into the target resource directory."dir/": copies all files and directories recursively into the target resource directory. Use this if you also want to preserve the file system structure of your files and directories."dir/*": copies all files in thedirdirectory non-recursively (sub-directories will be ignored) into the target resource directory."dir/**: throws an error because**only matches directories and therefore no files can be found."dir/**/*": copies all files in thedirdirectory recursively (all files indir/and all files in all sub-directories) into the target resource directory."dir/**/**: throws an error because**only matches directories and therefore no files can be found.
Resolve resource file paths
To resolve the path for a resource file, instead of manually calculating the path, use the following APIs
-
Rust
On the Rust side, you need an instance of the
PathResolverwhich you can get fromAppandAppHandle, then callPathResolver::resolve:tauri::Builder::default() .setup(|app| { let resource_path = app.path().resolve("lang/de.json", BaseDirectory::Resource)?; Ok(()) })To use it in a command:
#[tauri::command] fn hello(handle: tauri::AppHandle) { let resource_path = handle.path().resolve("lang/de.json", BaseDirectory::Resource)?; } -
JavaScript
To resolve the path in JavaScript, use
resolveResource:import { resolveResource } from '@tauri-apps/api/path'; const resourcePath = await resolveResource('lang/de.json');
Path syntax
The path in the API calls can be either a normal relative path like folder/json_file.json that resolves to $RESOURCE/folder/json_file.json, or a paths like ../relative/folder/toml_file.toml that resolves to $RESOURCE/_up_/relative/folder/toml_file.toml, these APIs use the same rules as you write tauri.conf.json > bundle > resources, for example:
tauri.conf.json
{
"bundle": {
"resources": ["folder/json_file.json", "../relative/folder/toml_file.toml"]
}
}
let json_path = app.path().resolve("folder/json_file.json", BaseDirectory::Resource)?;
let toml_path = app.path().resolve("../relative/folder/toml_file.toml", BaseDirectory::Resource)?;
Android
Currently the resources are stored in the APK as assets so the return value of those APIs are not normal file system paths, we use a special URI prefix asset://localhost/ here that can be used with the fs plugin, with that, you can read the files through FsExt::fs like this:
let resource_path = app.path().resolve("lang/de.json", BaseDirectory::Resource).unwrap();
let json = app.fs().read_to_string(&resource_path);
If you want or must have the resource files to be on a real file system, copy the contents out manually through the fs plugin
Reading resource files
In this example we want to bundle additional i18n json files like this:
.
├── src-tauri/
│ ├── tauri.conf.json
│ ├── lang/
│ │ ├── de.json
│ │ └── en.json
│ └── ...
└── ...
tauri.conf.json
{
"bundle": {
"resources": ["lang/*"]
}
}
lang/de.json
{
"hello": "Guten Tag!",
"bye": "Auf Wiedersehen!"
}
Rust
On the Rust side, you need an instance of the PathResolver which you can get from App and AppHandle:
tauri::Builder::default()
.setup(|app| {
// The path specified must follow the same syntax as defined in
// `tauri.conf.json > bundle > resources`
let resource_path = app.path().resolve("lang/de.json", BaseDirectory::Resource)?;
let json = std::fs::read_to_string(&resource_path).unwrap();
// Or when dealing with Android, use the file system plugin instead
// let json = app.fs().read_to_string(&resource_path);
let lang_de: serde_json::Value = serde_json::from_str(json).unwrap();
// This will print 'Guten Tag!' to the terminal
println!("{}", lang_de.get("hello").unwrap());
Ok(())
})
#[tauri::command]
fn hello(handle: tauri::AppHandle) -> String {
let resource_path = handle.path().resolve("lang/de.json", BaseDirectory::Resource)?;
let json = std::fs::read_to_string(&resource_path).unwrap();
// Or when dealing with Android, use the file system plugin instead
// let json = handle.fs().read_to_string(&resource_path);
let lang_de: serde_json::Value = serde_json::from_str(json).unwrap();
lang_de.get("hello").unwrap()
}
JavaScript
For the JavaScript side, you can either use a command like the one above and call it through await invoke('hello') or access the files using the fs plugin.
When using the fs plugin, in addition to the basic setup, you’ll also need to configure the access control list to enable any plugin APIs you need as well as the permissions to access the $RESOURCE folder:
src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
"core:default",
+"fs:allow-read-text-file",
+"fs:allow-resource-read-recursive"
]
}
Note
Here we use fs:allow-resource-read-recursive to allow for full recursive read access to the complete $RESOURCE folder, files, and subdirectories. For more information, read Scope Permissions for other options, or Scopes for more fine-grained control.
import { resolveResource } from '@tauri-apps/api/path';
import { readTextFile } from '@tauri-apps/plugin-fs';
const resourcePath = await resolveResource('lang/de.json');
const langDe = JSON.parse(await readTextFile(resourcePath));
console.log(langDe.hello); // This will print 'Guten Tag!' to the devtools console
Permissions
Since we replace ../ to _up_ in relative paths and the root to _root_ in absolute paths when using a list, those files will be in sub folders inside the resource directory, to allow those paths in Tauri’s permission system, use $RESOURCE/**/* to allow recursive access to those files
Examples
With a file bundled like this:
tauri.conf.json
{
"bundle": {
"resources": ["../relative/path/to/jsonfile.json"]
}
}
To use it with the fs plugin:
src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
"core:default",
+"fs:allow-stat",
+"fs:allow-read-text-file",
+"fs:allow-resource-read-recursive",
+ {
+"identifier": "fs:scope",
+"allow": ["$RESOURCE/**/*"],
+"deny": ["$RESOURCE/secret.txt"]
+ }
]
}
To use it with the opener plugin:
src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
"core:default",
+ {
+"identifier": "opener:allow-open-path",
+"allow": [
+ {
+"path": "$RESOURCE/**/*"
+ }
+ ]
+ }
]
}
Embedding External Binaries
You may need to embed external binaries to add additional functionality to your application or prevent users from installing additional dependencies (e.g., Node.js or Python). We call this binary a sidecar.
Binaries are executables written in any programming language. Common use cases are Python CLI applications or API servers bundled using pyinstaller.
To bundle the binaries of your choice, you can add the externalBin property to the bundle object in your tauri.conf.json. The externalBin configuration expects a list of strings targeting binaries either with absolute or relative paths.
Here is a Tauri configuration snippet to illustrate a sidecar configuration:
src-tauri/tauri.conf.json
{
"bundle": {
"externalBin": [
"/absolute/path/to/sidecar",
"../relative/path/to/binary",
"binaries/my-sidecar"
]
}
}
Note
The relative paths are relative to the tauri.conf.json file which is in the src-tauri directory. So binaries/my-sidecar would represent <PROJECT ROOT>/src-tauri/binaries/my-sidecar.
To make the external binary work on each supported architecture, a binary with the same name and a -$TARGET_TRIPLE suffix must exist on the specified path. For instance, "externalBin": ["binaries/my-sidecar"] requires a src-tauri/binaries/my-sidecar-x86_64-unknown-linux-gnu executable on Linux or src-tauri/binaries/my-sidecar-aarch64-apple-darwin on Mac OS with Apple Silicon.
You can find your current platform’s -$TARGET_TRIPLE suffix by running the following command:
rustc --print host-tuple
This directly outputs your host’s target triple (e.g., x86_64-unknown-linux-gnu or aarch64-apple-darwin).
Note
The --print host-tuple flag was added in Rust 1.84.0. If you’re using an older version, you’ll need to parse the output of rustc -Vv instead:
# Unix (Linux/macOS)
rustc -Vv | grep host | cut -f2 -d' '
# Windows PowerShell
rustc -Vv | Select-String "host:" | ForEach-Object {$_.Line.split(" ")[1]}
Here’s a Node.js script to append the target triple to a binary:
import { execSync } from 'child_process';
import fs from 'fs';
const extension = process.platform === 'win32' ? '.exe' : '';
const targetTriple = execSync('rustc --print host-tuple').toString().trim();
if (!targetTriple) {
console.error('Failed to determine platform target triple');
}
fs.renameSync(
`src-tauri/binaries/sidecar${extension}`,
`src-tauri/binaries/sidecar-${targetTriple}${extension}`
);
Note that this script will not work if you compile for a different architecture than the one its running on, so only use it as a starting point for your own build scripts.
Running it from Rust
Note
Please follow the shell plugin guide first to set up and initialize the plugin correctly. Without the plugin being initialized and configured the example won’t work.
On the Rust side, import the tauri_plugin_shell::ShellExt trait and call the shell().sidecar() function on the AppHandle:
use tauri_plugin_shell::ShellExt;
use tauri_plugin_shell::process::CommandEvent;
use tauri::Emitter;
let sidecar_command = app.shell().sidecar("my-sidecar").unwrap();
let (mut rx, mut child) = sidecar_command
.spawn()
.expect("Failed to spawn sidecar");
tauri::async_runtime::spawn(async move {
// read events such as stdout
while let Some(event) = rx.recv().await {
if let CommandEvent::Stdout(line_bytes) = event {
let line = String::from_utf8_lossy(&line_bytes);
app
.emit("message", Some(format!("'{}'", line)))
.expect("failed to emit event");
// write to stdin
child.write("message from Rust\n".as_bytes()).unwrap();
}
}
});
Note
The sidecar() function expects just the filename, NOT the whole path configured in the externalBin array.
Given the following configuration:
src-tauri/tauri.conf.json
{
"bundle": {
"externalBin": ["binaries/app", "my-sidecar", "../scripts/sidecar"]
}
}
The appropriate way to execute the sidecar is by calling app.shell().sidecar(name) where name is either "app", "my-sidecar" or "sidecar" instead of "binaries/app" for instance.
You can place this code inside a Tauri command to easily pass the AppHandle or you can store a reference to the AppHandle in the builder script to access it elsewhere in your application.
Running it from JavaScript
When running the sidecar, Tauri requires you to give the sidecar permission to run the execute or spawn method on the child process. To grant this permission, go to the file <PROJECT ROOT>/src-tauri/capabilities/default.json and add the section below to the permissions array. Don’t forget to name your sidecar according to the relative path mentioned earlier.
src-tauri/capabilities/default.json
{
"permissions": [
"core:default",
+ {
+"identifier": "shell:allow-execute",
+"allow": [
+ {
+"name": "binaries/app",
+"sidecar": true
+ }
+ ]
+ }
]
}
Note
The shell:allow-execute identifier is used because the sidecar’s child process will be started using the command.execute() method. To run it with command.spawn(), you need to change the identifier to shell:allow-spawn or add another entry to the array with the same structure as the one above, but with the identifier set to shell:allow-spawn.
In the JavaScript code, import the Command class from the @tauri-apps/plugin-shell module and use the sidecar static method.
import { Command } from '@tauri-apps/plugin-shell';
const command = Command.sidecar('binaries/my-sidecar');
const output = await command.execute();
Note
The string provided to Command.sidecar must match one of the strings defined in the externalBin configuration array.
Passing arguments
You can pass arguments to Sidecar commands just like you would for running normal Command.
Arguments can be either static (e.g. -o or serve) or dynamic (e.g. <file_path> or localhost:<PORT>). A value of true will allow any arguments to be passed to the command. false will disable all arguments. If neither true or false is set, you define the arguments in the exact order in which you’d call them. Static arguments are defined as-is, while dynamic arguments can be defined using a regular expression.
First, define the arguments that need to be passed to the sidecar command in src-tauri/capabilities/default.json:
src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
"core:default",
+ {
+"identifier": "shell:allow-execute",
+"allow": [
+ {
+"args": [
+"arg1",
+"-a",
+"--arg2",
+ {
+"validator": "\\S+"
+ }
+ ],
+"name": "binaries/my-sidecar",
+"sidecar": true
+ }
+ ]
+ }
]
}
Note
If you are migrating from Tauri v1, the migrate command in Tauri v2 CLI should take care of this for you. Read Automated Migration for more.
Then, to call the sidecar command, simply pass in all the arguments as an array.
In Rust:
use tauri_plugin_shell::ShellExt;
#[tauri::command]
async fn call_my_sidecar(app: tauri::AppHandle) {
let sidecar_command = app
.shell()
.sidecar("my-sidecar")
.unwrap()
.args(["arg1", "-a", "--arg2", "any-string-that-matches-the-validator"]);
let (mut _rx, mut _child) = sidecar_command.spawn().unwrap();
}
In JavaScript:
import { Command } from '@tauri-apps/plugin-shell';
// notice that the args array matches EXACTLY what is specified in `capabilities/default.json`.
const command = Command.sidecar('binaries/my-sidecar', [
'arg1',
'-a',
'--arg2',
'any-string-that-matches-the-validator',
]);
const output = await command.execute();
State Management
In a Tauri application, you often need to keep track of the current state of your application or manage the lifecycle of things associated with it. Tauri provides an easy way to manage the state of your application using the Manager API, and read it when commands are called.
Here is a simple example:
use tauri::{Builder, Manager};
struct AppData {
welcome_message: &'static str,
}
fn main() {
Builder::default()
.setup(|app| {
app.manage(AppData {
welcome_message: "Welcome to Tauri!",
});
Ok(())
})
.run(tauri::generate_context!())
.unwrap();
}
You can later access your state with any type that implements the Manager trait, for example the App instance:
let data = app.state::<AppData>();
For more info, including accessing state in commands, see the Accessing State section.
Mutability
In Rust, you cannot directly mutate values which are shared between multiple threads or when ownership is controlled through a shared pointer such as Arc (or Tauri’s State). Doing so could cause data races (for example, two writes happening simultaneously).
To work around this, you can use a concept known as interior mutability. For example, the standard library’s Mutex can be used to wrap your state. This allows you to lock the value when you need to modify it, and unlock it when you are done.
use std::sync::Mutex;
use tauri::{Builder, Manager};
#[derive(Default)]
struct AppState {
counter: u32,
}
fn main() {
Builder::default()
.setup(|app| {
app.manage(Mutex::new(AppState::default()));
Ok(())
})
.run(tauri::generate_context!())
.unwrap();
}
The state can now be modified by locking the mutex:
let state = app.state::<Mutex<AppState>>();
// Lock the mutex to get mutable access:
let mut state = state.lock().unwrap();
// Modify the state:
state.counter += 1;
At the end of the scope, or when the MutexGuard is otherwise dropped, the mutex is unlocked automatically so that other parts of your application can access and mutate the data within.
When to use an async mutex
To quote the Tokio documentation, it’s often fine to use the standard library’s Mutex instead of an async mutex such as the one Tokio provides:
Contrary to popular belief, it is ok and often preferred to use the ordinary Mutex from the standard library in asynchronous code … The primary use case for the async mutex is to provide shared mutable access to IO resources such as a database connection.
It’s a good idea to read the linked documentation fully to understand the trade-offs between the two. One reason you would need an async mutex is if you need to hold the MutexGuard across await points.
Do you need Arc?
It’s common to see Arc used in Rust to share ownership of a value across multiple threads (usually paired with a Mutex in the form of Arc<Mutex<T>>). However, you don’t need to use Arc for things stored in State because Tauri will do this for you.
In case State’s lifetime requirements prevent you from moving your state into a new thread you can instead move an AppHandle into the thread and then retrieve your state as shown below in the “Access state with the Manager trait” section. AppHandles are deliberately cheap to clone for use-cases like this.
Accessing State
Access state in commands
#[tauri::command]
fn increase_counter(state: State<'_, Mutex<AppState>>) -> u32 {
let mut state = state.lock().unwrap();
state.counter += 1;
state.counter
}
For more information on commands, see Calling Rust from the Frontend.
Async commands
If you are using async commands and want to use Tokio’s async Mutex, you can set it up the same way and access the state like this:
#[tauri::command]
async fn increase_counter(state: State<'_, Mutex<AppState>>) -> Result<u32, ()> {
let mut state = state.lock().await;
state.counter += 1;
Ok(state.counter)
}
Note that the return type must be Result if you use asynchronous commands.
Access state with the Manager trait
Sometimes you may need to access the state outside of commands, such as in a different thread or in an event handler like on_window_event. In such cases, you can use the state() method of types that implement the Manager trait (such as the AppHandle) to get the state:
use std::sync::Mutex;
use tauri::{Builder, Window, WindowEvent, Manager};
#[derive(Default)]
struct AppState {
counter: u32,
}
// In an event handler:
fn on_window_event(window: &Window, _event: &WindowEvent) {
// Get a handle to the app so we can get the global state.
let app_handle = window.app_handle();
let state = app_handle.state::<Mutex<AppState>>();
// Lock the mutex to mutably access the state.
let mut state = state.lock().unwrap();
state.counter += 1;
}
fn main() {
Builder::default()
.setup(|app| {
app.manage(Mutex::new(AppState::default()));
Ok(())
})
.on_window_event(on_window_event)
.run(tauri::generate_context!())
.unwrap();
}
This method is useful when you cannot rely on command injection. For example, if you need to move the state into a thread where using an AppHandle is easier, or if you are not in a command context.
Mismatching Types
Caution
If you use the wrong type for the State parameter, you will get a runtime panic instead of compile time error.
For example, if you use State<'_, AppState> instead of State<'_, Mutex<AppState>>, there won’t be any state managed with that type.
If you prefer, you can wrap your state with a type alias to prevent this mistake:
use std::sync::Mutex;
#[derive(Default)]
struct AppStateInner {
counter: u32,
}
type AppState = Mutex<AppStateInner>;
However, make sure to use the type alias as it is, and not wrap it in a Mutex a second time, otherwise you will run into the same issue.
Tests
Techniques for testing inside and outside the Tauri runtime
Tauri offers support for both unit and integration testing utilizing a mock runtime. Under the mock runtime, native webview libraries are not executed. See more about the mock runtime here.
Tauri also provides support for end-to-end testing utilizing the WebDriver protocol. WebdriverIO Tauri testing supports Windows, Linux, and macOS; the WebDriver protocol can also be driven directly on Windows and Linux, as macOS provides no desktop WebDriver client. See more about WebDriver support here.
We offer tauri-action to help run GitHub actions, but any sort of CI/CD runner can be used with Tauri as long as each platform has the required libraries installed to compile against.
Mock Tauri APIs
When writing your frontend tests, having a “fake” Tauri environment to simulate windows or intercept IPC calls is common, so-called mocking. The @tauri-apps/api/mocks module provides some helpful tools to make this easier for you:
Caution
Remember to clear mocks after each test run to undo mock state changes between runs! See clearMocks() docs for more info.
IPC Requests
Most commonly, you want to intercept IPC requests; this can be helpful in a variety of situations:
- Ensure the correct backend calls are made
- Simulate different results from backend functions
Tauri provides the mockIPC function to intercept IPC requests. You can find more about the specific API in detail here.
Note
The following examples use Vitest, but you can use any other frontend testing library such as jest.
Mocking Commands for invoke
import { beforeAll, expect, test } from "vitest";
import { randomFillSync } from "crypto";
import { mockIPC } from "@tauri-apps/api/mocks";
import { invoke } from "@tauri-apps/api/core";
// jsdom doesn't come with a WebCrypto implementation
beforeAll(() => {
Object.defineProperty(window, 'crypto', {
value: {
// @ts-ignore
getRandomValues: (buffer) => {
return randomFillSync(buffer);
},
},
});
});
test("invoke simple", async () => {
mockIPC((cmd, args) => {
// simulated rust command called "add" that just adds two numbers
if(cmd === "add") {
return (args.a as number) + (args.b as number);
}
});
});
Sometimes you want to track more information about an IPC call; how many times was the command invoked? Was it invoked at all? You can use mockIPC() with other spying and mocking tools to test this:
import { beforeAll, expect, test, vi } from "vitest";
import { randomFillSync } from "crypto";
import { mockIPC } from "@tauri-apps/api/mocks";
import { invoke } from "@tauri-apps/api/core";
// jsdom doesn't come with a WebCrypto implementation
beforeAll(() => {
Object.defineProperty(window, 'crypto', {
value: {
// @ts-ignore
getRandomValues: (buffer) => {
return randomFillSync(buffer);
},
},
});
});
test("invoke", async () => {
mockIPC((cmd, args) => {
// simulated rust command called "add" that just adds two numbers
if(cmd === "add") {
return (args.a as number) + (args.b as number);
}
});
// we can use the spying tools provided by vitest to track the mocked function
const spy = vi.spyOn(window.__TAURI_INTERNALS__, "invoke");
expect(invoke("add", { a: 12, b: 15 })).resolves.toBe(27);
expect(spy).toHaveBeenCalled();
});
To mock IPC requests to a sidecar or shell command you need to grab the ID of the event handler when spawn() or execute() is called and use this ID to emit events the backend would send back:
mockIPC(async (cmd, args) => {
if (args.message.cmd === 'execute') {
const eventCallbackId = `_${args.message.onEventFn}`;
const eventEmitter = window[eventCallbackId];
// 'Stdout' event can be called multiple times
eventEmitter({
event: 'Stdout',
payload: 'some data sent from the process',
});
// 'Terminated' event must be called at the end to resolve the promise
eventEmitter({
event: 'Terminated',
payload: {
code: 0,
signal: 'kill',
},
});
}
});
See also
mockIPC fakes invoke under the mock runtime — no real webview or Rust backend runs. To mock the same commands in end-to-end tests, against a running app or your frontend in a browser, @wdio/tauri-service provides an equivalent browser.tauri.mock(). See WebDriver testing.
Mocking Events
There is partial support of the Event System to simulate events emitted by your Rust code via the shouldMockEvents option:
import { mockIPC, clearMocks } from '@tauri-apps/api/mocks';
import { emit, listen } from '@tauri-apps/api/event';
import { afterEach, expect, test, vi } from 'vitest';
test('mocked event', () => {
mockIPC(() => {}, { shouldMockEvents: true }); // enable event mocking
const eventHandler = vi.fn();
listen('test-event', eventHandler);
emit('test-event', { foo: 'bar' });
expect(eventHandler).toHaveBeenCalledWith({
event: 'test-event',
payload: { foo: 'bar' },
});
});
emitTo and emit_filter are not supported yet.
Windows
Sometimes you have window-specific code (a splash screen window, for example), so you need to simulate different windows. You can use the mockWindows() method to create fake window labels. The first string identifies the “current” window (i.e., the window your JavaScript believes itself in), and all other strings are treated as additional windows.
Note
mockWindows() only fakes the existence of windows but no window properties. To simulate window properties, you need to intercept the correct calls using mockIPC()
import { beforeAll, expect, test } from 'vitest';
import { randomFillSync } from 'crypto';
import { mockWindows } from '@tauri-apps/api/mocks';
// jsdom doesn't come with a WebCrypto implementation
beforeAll(() => {
Object.defineProperty(window, 'crypto', {
value: {
// @ts-ignore
getRandomValues: (buffer) => {
return randomFillSync(buffer);
},
},
});
});
test('invoke', async () => {
mockWindows('main', 'second', 'third');
const { getCurrent, getAll } = await import('@tauri-apps/api/webviewWindow');
expect(getCurrent()).toHaveProperty('label', 'main');
expect(getAll().map((w) => w.label)).toEqual(['main', 'second', 'third']);
});
WebDriver
WebDriver Testing
WebDriver is a standardized interface to interact with web documents, primarily intended for automated testing. The recommended way to use it with Tauri is WebdriverIO and the @wdio/tauri-service, which works on Windows, Linux, and macOS. Maintained under the WebdriverIO project, it provides Tauri API access through browser.tauri.execute(), command (IPC) mocking, frontend and backend log capture, and multiremote.
By default the service runs an embedded WebDriver server inside your app, so no external driver is needed on any platform — and this is how macOS is supported. It can also drive the platform’s native WebDriver through tauri-driver on Windows and Linux, or CrabNebula’s cross-platform fork of tauri-driver on all platforms (a paid API key is required for macOS). Whichever route you choose, the service detects your application binary, and on the tauri-driver route it keeps the Edge WebDriver in sync on Windows for you.
The quickest way to scaffold a project is the WebdriverIO starter:
npm create wdio@latest ./
Pick Desktop Testing and choose Tauri at the framework prompt. A minimal configuration looks like this:
export const config: WebdriverIO.Config = {
services: [
[
'tauri',
{
appBinaryPath: './src-tauri/target/release/my-tauri-app',
driverProvider: 'embedded',
},
],
],
};
Setting this up uses two small Tauri plugins, both optional depending on your requirements:
tauri-plugin-wdio-webdriverruns the embedded WebDriver server. It’s required for theembeddedprovider (the default) — the service drives your app through it, with no external driver, and it’s how macOS is supported. You can skip it if you want to use theexternalorcrabnebulaprovider instead.tauri-plugin-wdioenables backend access including:browser.tauri.execute(), command (IPC) mocking, and log capture.
See Plugin Setup for the full steps, and the CrabNebula setup guide if you use that provider.
For fast, renderer-only tests there is also a browser mode that runs your Tauri frontend in plain Chrome against a Vite dev server — no Tauri binary, driver, or plugin required. It intercepts invoke() calls so you can mock commands and assert on their arguments with the same WDIO API. See the browser mode guide.
WebdriverIO Tauri documentationFull setup, configuration, and API reference for @wdio/tauri-service
Example Applications
Complete, runnable examples that use the service live in the WebdriverIO desktop-mobile repository.
Continuous Integration (CI)
The WebDriver CI guide explains how to run these tests under GitHub Actions and the concepts behind it.
Driving tauri-driver directly
If you are not using Node.js, prefer Selenium, or are integrating WebDriver into a custom test harness, you can drive tauri-driver directly instead of using the service. Driven directly, only Windows and Linux are supported on desktop, as macOS has no WKWebView driver tool available (use the service’s embedded WebDriver server for macOS).
Manual WebDriver setupInstall and drive tauri-driver yourself (Windows and Linux only)
Continuous Integration
WebDriver Testing
It is possible to run WebDriver tests with tauri-driver on your CI. The following example uses the WebdriverIO example we previously built together and GitHub Actions.
The WebDriver tests are executed on Linux by creating a fake display. Some CI systems such as GitHub Actions also support running WebDriver tests on Windows.
GitHub Actions
The following GitHub Actions assumes:
- The Tauri application is in the
src-taurifolder. - The WebDriverIO test runner is in the
e2e-testsdirectory and runs whenyarn testis used in that directory.
.github/workflows/webdriver.yml
# run this action when the repository is pushed to
on: [push]
# the name of our workflow
name: WebDriver
jobs:
# a single job named test
test:
# the display name of the test job
name: WebDriverIO Test Runner
# run on the matrix platform
runs-on: ${{ matrix.platform }}
strategy:
# do not fail other matrix runs if one fails
fail-fast: false
# set all platforms our test should run on
matrix:
platform: [ubuntu-latest, windows-latest]
# the steps our job runs **in order**
steps:
# checkout the code on the workflow runner
- uses: actions/checkout@v4
# install system dependencies that Tauri needs to compile on Linux.
# note the extra dependencies for `tauri-driver` to run which are: `webkit2gtk-driver` and `xvfb`
- name: Tauri dependencies
if: matrix.platform == 'ubuntu-latest'
run: |
sudo apt-get update &&
sudo apt-get install -y \
libwebkit2gtk-4.1-dev \
libayatana-appindicator3-dev \
webkit2gtk-driver \
xvfb
# install a matching Microsoft Edge Driver version using msedgedriver-tool
- name: install msdgedriver (Windows)
if: matrix.platform == 'windows-latest'
run: |
cargo install --git https://github.com/chippers/msedgedriver-tool
& "$HOME/.cargo/bin/msedgedriver-tool.exe"
$PWD.Path >> $env:GITHUB_PATH
# install latest stable Rust release
- name: Setup rust-toolchain stable
uses: dtolnay/rust-toolchain@stable
# setup caching for the Rust target folder
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri
# we run our Rust tests before the webdriver tests to avoid testing a broken application
- name: Cargo test
run: cargo test
# install the latest stable node version at the time of writing
- name: Node 24
uses: actions/setup-node@v4
with:
node-version: 24
cache: 'yarn'
# install the application Node.js dependencies with Yarn
- name: Yarn install
run: yarn install --frozen-lockfile
# install the e2e-tests Node.js dependencies with Yarn
- name: Yarn install
run: yarn install --frozen-lockfile
working-directory: e2e-tests
# install the latest version of `tauri-driver`.
# note: the tauri-driver version is independent of any other Tauri versions
- name: Install tauri-driver
run: cargo install tauri-driver --locked
# run the WebdriverIO test suite on Linux.
# we run it through `xvfb-run` (the dependency we installed earlier) to have a fake
# display server which allows our application to run headless without any changes to the code
- name: WebdriverIO (Linux)
if: matrix.platform == 'ubuntu-latest'
run: xvfb-run yarn test
working-directory: e2e-tests
# run the WebdriverIO test suite on Windows.
# in this case we can run the tests directly.
- name: WebdriverIO (Windows)
if: matrix.platform == 'windows-latest'
run: yarn test
working-directory: e2e-tests
Selenium
Note
Make sure to go through the prerequisites instructions to be able to follow this guide.
This WebDriver testing example will use Selenium and a popular Node.js testing suite. You are expected to already have Node.js installed, along with npm or yarn although the finished example project uses pnpm.
Create a Directory for the Tests
Let’s create a space to write these tests in our project. We will be using a nested directory for this example project as we will later also go over other frameworks, but typically you will only need to use one. Create the directory we will use with mkdir -p e2e-tests. The rest of this guide will assume you are inside the e2e-tests directory.
Initializing a Selenium Project
We will be using a pre-existing package.json to bootstrap this test suite because we have already chosen specific dependencies to use and want to showcase a simple working solution. The bottom of this section has a collapsed guide on how to set it up from scratch.
package.json:
{
"name": "selenium",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"test": "mocha"
},
"dependencies": {
"chai": "^5.2.1",
"mocha": "^11.7.1",
"selenium-webdriver": "^4.34.0"
}
}
We have a script that runs Mocha as a test framework exposed as the test command. We also have various dependencies that we will be using to run the tests. Mocha as the testing framework, Chai as the assertion library, and selenium-webdriver which is the Node.js Selenium package.
Click me if you want to see how to set a project up from scratch
If you want to install the dependencies from scratch, just run the following command.
-
npm
npm install mocha chai selenium-webdriver -
yarn
yarn add mocha chai selenium-webdriver
I suggest also adding a "test": "mocha" item in the package.json "scripts" key so that running Mocha can be called simply with
-
npm
npm test -
yarn
yarn test
Testing
Unlike the WebdriverIO Test Suite, Selenium does not come out of the box with a Test Suite and leaves it up to the developer to build those out. We chose Mocha, which is pretty neutral and not related to WebDrivers, so our script will need to do a bit of work to set up everything for us in the correct order. Mocha expects a testing file at test/test.js by default, so let’s create that file now.
test/test.js:
import os from 'os';
import path from 'path';
import { expect } from 'chai';
import { spawn, spawnSync } from 'child_process';
import { Builder, By, Capabilities } from 'selenium-webdriver';
import { fileURLToPath } from 'url';
const __dirname = fileURLToPath(new URL('.', import.meta.url));
// create the path to the expected application binary
const application = path.resolve(
__dirname,
'..',
'..',
'src-tauri',
'target',
'debug',
'tauri-app'
);
// keep track of the webdriver instance we create
let driver;
// keep track of the tauri-driver process we start
let tauriDriver;
let exit = false;
before(async function () {
// set timeout to 2 minutes to allow the program to build if it needs to
this.timeout(120000);
// ensure the app has been built
spawnSync('yarn', ['tauri', 'build', '--debug', '--no-bundle'], {
cwd: path.resolve(__dirname, '../..'),
stdio: 'inherit',
shell: true,
});
// start tauri-driver
tauriDriver = spawn(
path.resolve(os.homedir(), '.cargo', 'bin', 'tauri-driver'),
[],
{ stdio: [null, process.stdout, process.stderr] }
);
tauriDriver.on('error', (error) => {
console.error('tauri-driver error:', error);
process.exit(1);
});
tauriDriver.on('exit', (code) => {
if (!exit) {
console.error('tauri-driver exited with code:', code);
process.exit(1);
}
});
const capabilities = new Capabilities();
capabilities.set('tauri:options', { application });
capabilities.setBrowserName('wry');
// start the webdriver client
driver = await new Builder()
.withCapabilities(capabilities)
.usingServer('http://127.0.0.1:4444/')
.build();
});
after(async function () {
// stop the webdriver session
await closeTauriDriver();
});
describe('Hello Tauri', () => {
it('should be cordial', async () => {
const text = await driver.findElement(By.css('body > h1')).getText();
expect(text).to.match(/^[hH]ello/);
});
it('should be excited', async () => {
const text = await driver.findElement(By.css('body > h1')).getText();
expect(text).to.match(/!$/);
});
it('should be easy on the eyes', async () => {
// selenium returns color css values as rgb(r, g, b)
const text = await driver
.findElement(By.css('body'))
.getCssValue('background-color');
const rgb = text.match(/^rgb\((?<r>\d+), (?<g>\d+), (?<b>\d+)\)$/).groups;
expect(rgb).to.have.all.keys('r', 'g', 'b');
const luma = 0.2126 * rgb.r + 0.7152 * rgb.g + 0.0722 * rgb.b;
expect(luma).to.be.lessThan(100);
});
});
async function closeTauriDriver() {
exit = true;
// kill the tauri-driver process
tauriDriver.kill();
// stop the webdriver session
await driver.quit();
}
function onShutdown(fn) {
const cleanup = () => {
try {
fn();
} finally {
process.exit();
}
};
process.on('exit', cleanup);
process.on('SIGINT', cleanup);
process.on('SIGTERM', cleanup);
process.on('SIGHUP', cleanup);
process.on('SIGBREAK', cleanup);
}
onShutdown(() => {
closeTauriDriver();
});
If you are familiar with JS testing frameworks, describe, it, and expect should look familiar. We also have semi-complex before() and after() callbacks to set up and teardown mocha. Lines that are not the tests themselves have comments explaining the setup and teardown code. If you were familiar with the Spec file from the WebdriverIO example, you notice a lot more code that isn’t tests, as we have to set up a few more WebDriver related items.
Running the Test Suite
Now that we are all set up with our dependencies and our test script, let’s run it!
-
npm
npm test -
yarn
yarn test
We should see output the following output:
➜ selenium git:(main) ✗ yarn test
yarn run v1.22.11
$ Mocha
Hello Tauri
✔ should be cordial (120ms)
✔ should be excited
✔ should be easy on the eyes
3 passing (588ms)
Done in 0.93s.
We can see that our Hello Tauri test suite we created with describe had all 3 items we created with it pass their tests!
With Selenium and some hooking up to a test suite, we just enabled e2e testing without modifying our Tauri application at all!
WebdriverIO
Note
Make sure to go through the prerequisites instructions to be able to follow this guide.
Using the WebdriverIO Tauri service?
This guide wires WebdriverIO up to tauri-driver by hand so you can see how the pieces fit together. Most projects should use the @wdio/tauri-service instead, which automates all of this and supports macOS — see the WebDriver overview.
This WebDriver testing example will use WebdriverIO, and its testing suite. It is expected to have Node.js already installed, along with npm or yarn although the finished example project uses pnpm.
Create a Directory for the Tests
Let’s create a space to write these tests in our project. We will be using a nested directory for this example project as we will later also go over other frameworks, but typically you only need to use one. Create the directory we will use with mkdir e2e-tests. The rest of this guide assumes you are inside the e2e-tests directory.
Initializing a WebdriverIO Project
We will be using a pre-existing package.json to bootstrap this test suite because we have already chosen specific WebdriverIO config options and want to showcase a simple working solution. The bottom of this section has a collapsed guide on setting it up from scratch.
package.json:
{
"name": "webdriverio",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"test": "wdio run wdio.conf.js"
},
"dependencies": {
"@wdio/cli": "^9.19.0"
},
"devDependencies": {
"@wdio/local-runner": "^9.19.0,
"@wdio/mocha-framework": "^9.19.0",
"@wdio/spec-reporter": "^9.19.0"
}
}
We have a script that runs a WebdriverIO config as a test suite exposed as the test command. We also have various dependencies added by the @wdio/cli command when we first set it up. In short, these dependencies are for the most simple setup using a local WebDriver runner, Mocha as the test framework, and a simple Spec Reporter.
Click me if you want to see how to set a project up from scratch
The CLI is interactive, and you may choose the tools to work with yourself. Note that you will likely diverge from the rest of the guide, and you need to set up the differences yourself.
Let’s add the WebdriverIO CLI to this npm project.
-
npm
npm install @wdio/cli -
yarn
yarn add @wdio/cli
To then run the interactive config command to set up a WebdriverIO test suite, you can then run:
-
npm
npx wdio config -
yarn
yarn wdio config
Config
You may have noticed that the test script in our package.json mentions a file wdio.conf.js. That’s the WebdriverIO config file which controls most aspects of our testing suite.
wdio.conf.js:
import os from 'os';
import path from 'path';
import { spawn, spawnSync } from 'child_process';
import { fileURLToPath } from 'url';
const __dirname = fileURLToPath(new URL('.', import.meta.url));
// keep track of the `tauri-driver` child process
let tauriDriver;
let exit = false;
export const config = {
host: '127.0.0.1',
port: 4444,
specs: ['./develop/tests/specs/**/*.js'],
maxInstances: 1,
capabilities: [
{
maxInstances: 1,
'tauri:options': {
application: '../src-tauri/target/debug/tauri-app',
},
},
],
reporters: ['spec'],
framework: 'mocha',
mochaOpts: {
ui: 'bdd',
timeout: 60000,
},
// ensure the rust project is built since we expect this binary to exist for the webdriver sessions
onPrepare: () => {
// Remove the extra `--` if you're not using npm!
spawnSync(
'npm',
['run', 'tauri', 'build', '--', '--debug', '--no-bundle'],
{
cwd: path.resolve(__dirname, '..'),
stdio: 'inherit',
shell: true,
}
);
},
// ensure we are running `tauri-driver` before the session starts so that we can proxy the webdriver requests
beforeSession: () => {
tauriDriver = spawn(
path.resolve(os.homedir(), '.cargo', 'bin', 'tauri-driver'),
[],
{ stdio: [null, process.stdout, process.stderr] }
);
tauriDriver.on('error', (error) => {
console.error('tauri-driver error:', error);
process.exit(1);
});
tauriDriver.on('exit', (code) => {
if (!exit) {
console.error('tauri-driver exited with code:', code);
process.exit(1);
}
});
},
// clean up the `tauri-driver` process we spawned at the start of the session
// note that afterSession might not run if the session fails to start, so we also run the cleanup on shutdown
afterSession: () => {
closeTauriDriver();
},
};
function closeTauriDriver() {
exit = true;
tauriDriver?.kill();
}
function onShutdown(fn) {
const cleanup = () => {
try {
fn();
} finally {
process.exit();
}
};
process.on('exit', cleanup);
process.on('SIGINT', cleanup);
process.on('SIGTERM', cleanup);
process.on('SIGHUP', cleanup);
process.on('SIGBREAK', cleanup);
}
// ensure tauri-driver is closed when our test process exits
onShutdown(() => {
closeTauriDriver();
});
If you are interested in the properties on the config object, we suggest reading the documentation. For non-WDIO specific items, there are comments explaining why we are running commands in onPrepare, beforeSession, and afterSession. We also have our specs set to "./test/specs/**/*.js", so let’s create a spec now.
Spec
A spec contains the code that is testing your actual application. The test runner will load these specs and automatically run them as it sees fit. Let’s create our spec now in the directory we specified.
test/specs/example.e2e.js:
// calculates the luma from a hex color `#abcdef`
function luma(hex) {
if (hex.startsWith('#')) {
hex = hex.substring(1);
}
const rgb = parseInt(hex, 16);
const r = (rgb >> 16) & 0xff;
const g = (rgb >> 8) & 0xff;
const b = (rgb >> 0) & 0xff;
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
}
describe('Hello Tauri', () => {
it('should be cordial', async () => {
const header = await $('body > h1');
const text = await header.getText();
expect(text).toMatch(/^[hH]ello/);
});
it('should be excited', async () => {
const header = await $('body > h1');
const text = await header.getText();
expect(text).toMatch(/!$/);
});
it('should be easy on the eyes', async () => {
const body = await $('body');
const backgroundColor = await body.getCSSProperty('background-color');
expect(luma(backgroundColor.parsed.hex)).toBeLessThan(100);
});
});
The luma function on top is just a helper function for one of our tests and is not related to the actual testing of the application. If you are familiar with other testing frameworks, you may notice similar functions being exposed that are used, such as describe, it, and expect. The other APIs, such as items like $ and its exposed methods, are covered by the WebdriverIO API docs.
Running the Test Suite
Now that we are all set up with config and a spec let’s run it!
-
npm
npm test -
yarn
yarn test
We should see output the following output:
➜ webdriverio git:(main) ✗ yarn test
yarn run v1.22.11
$ wdio run wdio.conf.js
Execution of 1 workers started at 2021-08-17T08:06:10.279Z
[0-0] RUNNING in undefined - /develop/tests/specs/example.e2e.js
[0-0] PASSED in undefined - /develop/tests/specs/example.e2e.js
"spec" Reporter:
------------------------------------------------------------------
[wry 0.12.1 linux #0-0] Running: wry (v0.12.1) on linux
[wry 0.12.1 linux #0-0] Session ID: 81e0107b-4d38-4eed-9b10-ee80ca47bb83
[wry 0.12.1 linux #0-0]
[wry 0.12.1 linux #0-0] » /develop/tests/specs/example.e2e.js
[wry 0.12.1 linux #0-0] Hello Tauri
[wry 0.12.1 linux #0-0] ✓ should be cordial
[wry 0.12.1 linux #0-0] ✓ should be excited
[wry 0.12.1 linux #0-0] ✓ should be easy on the eyes
[wry 0.12.1 linux #0-0]
[wry 0.12.1 linux #0-0] 3 passing (244ms)
Spec Files: 1 passed, 1 total (100% completed) in 00:00:01
Done in 1.98s.
We see the Spec Reporter tell us that all 3 tests from the test/specs/example.e2e.js file, along with the final report Spec Files: 1 passed, 1 total (100% completed) in 00:00:01.
Using the WebdriverIO test suite, we just easily enabled e2e testing for our Tauri application from just a few lines of configuration and a single command to run it! Even better, we didn’t have to modify the application at all.
Manual setup
Driving tauri-driver directly without the WebdriverIO Tauri service
This page covers driving tauri-driver directly, without the @wdio/tauri-service. Reach for it if you are not using Node.js, prefer Selenium, or are integrating WebDriver into a custom test harness. For most projects the service is the easier path — it automates everything below and additionally supports macOS. See the WebDriver overview to get started with it.
When driving tauri-driver directly, only Windows and Linux are supported on desktop, as macOS has no WKWebView driver tool available. iOS and Android work through Appium 2, but the process is not currently streamlined.
System Dependencies
Install the latest tauri-driver or update an existing installation by running:
cargo install tauri-driver --locked
Because we currently utilize the platform’s native WebDriver server, there are some requirements for running tauri-driver on supported platforms.
Linux
We use WebKitWebDriver on Linux platforms. Check if this binary exists already by running the which WebKitWebDriver command as some distributions bundle it with the regular WebKit package. Other platforms may have a separate package for them, such as webkit2gtk-driver on Debian-based distributions.
Windows
Make sure to grab the version of Microsoft Edge Driver that matches your Windows Edge version that the application is being built and tested on. This should almost always be the latest stable version on up-to-date Windows installs. If the two versions do not match, you may experience your WebDriver testing suite hanging while trying to connect.
You can use the msedgedriver-tool to download the appropriate Microsoft Edge Driver:
cargo install --git https://github.com/chippers/msedgedriver-tool
& "$HOME/.cargo/bin/msedgedriver-tool.exe"
The download contains a binary called msedgedriver.exe. tauri-driver looks for that binary in the $PATH so make sure it’s either available on the path or use the --native-driver option on tauri-driver. You may want to download this automatically as part of the CI setup process to ensure the Edge, and Edge Driver versions stay in sync on Windows CI machines. A guide on how to do this may be added at a later date.
Example Applications
Below are step-by-step guides to show how to create a minimal example application that is tested with WebDriver.
If you prefer to see the result of the guide and look over a finished minimal codebase that utilizes it, you can look at https://github.com/tauri-apps/webdriver-example.
Continuous Integration (CI)
The above examples also comes with a CI script to test with GitHub Actions, but you may still be interested in the below WebDriver CI guide as it explains the concept a bit more.
Updating Dependencies
Update npm Packages
If you are using the tauri package:
-
npm
npm install @tauri-apps/cli@latest @tauri-apps/api@latest -
yarn
yarn up @tauri-apps/cli @tauri-apps/api -
pnpm
pnpm update @tauri-apps/cli @tauri-apps/api --latest
You can also detect what the latest version of Tauri is on the command line, using:
-
npm
npm outdated @tauri-apps/cli -
yarn
yarn outdated @tauri-apps/cli -
pnpm
pnpm outdated @tauri-apps/cli
Update Cargo Packages
You can check for outdated packages with cargo outdated or on the crates.io pages: tauri / tauri-build.
Go to src-tauri/Cargo.toml and change tauri and tauri-build to
[build-dependencies]
tauri-build = "%version%"
[dependencies]
tauri = { version = "%version%" }
where %version% is the corresponding version number from above.
Then do the following:
cd src-tauri
cargo update
Alternatively, you can run the cargo upgrade command provided by cargo-edit which does all of this automatically.
Sync npm Packages and Cargo Crates versions
Since the JavaScript APIs rely on Rust code in the backend, adding a new feature requires upgrading both sides to ensure compatibility. Please make sure you have the same minor version of the npm package @tauri-apps/api and cargo crate tauri synced
And for the plugins, we might introduce this type of changes in patch releases, so we bump the npm package and cargo crate versions together, and you need to keep the exact versions synced, for example, you need the same version (e.g. 2.2.1) of the npm package @tauri-apps/plugin-fs and cargo crate tauri-plugin-fs
Distribute
Information on the tooling you need to distribute your application either to the platform app stores or as platform-specific installers
Tauri provides the tooling you need to distribute your application either to the platform app stores or as platform-specific installers.
Building
Tauri builds your application directly from its CLI via the build, android build and ios build commands.
-
npm
npm run tauri build -
yarn
yarn tauri build -
pnpm
pnpm tauri build -
deno
deno task tauri build -
bun
bun tauri build -
cargo
cargo tauri build
See the distributing section to learn more about the configuration options available for each bundle and how to distribute them to your users.
Note
Most platforms requires code signing. See the signing section for more information.
Bundling
By default the build command automatically bundles your application for the configured formats.
If you need further customization on how the platform bundles are generated, you can split the build and bundle steps:
-
npm
npm run tauri build -- --no-bundle # bundle for distribution outside the macOS App Store npm run tauri bundle -- --bundles app,dmg # bundle for App Store distribution npm run tauri bundle -- --bundles app --config src-tauri/tauri.appstore.conf.json -
yarn
yarn tauri build --no-bundle # bundle for distribution outside the macOS App Store yarn tauri bundle --bundles app,dmg # bundle for App Store distribution yarn tauri bundle --bundles app --config src-tauri/tauri.appstore.conf.json -
pnpm
pnpm tauri build --no-bundle # bundle for distribution outside the macOS App Store pnpm tauri bundle --bundles app,dmg # bundle for App Store distribution pnpm tauri bundle --bundles app --config src-tauri/tauri.appstore.conf.json -
deno
deno task tauri build --no-bundle # bundle for distribution outside the macOS App Store deno task tauri bundle --bundles app,dmg # bundle for App Store distribution deno task tauri bundle --bundles app --config src-tauri/tauri.appstore.conf.json -
bun
bun tauri build --no-bundle # bundle for distribution outside the macOS App Store bun tauri bundle --bundles app,dmg # bundle for App Store distribution bun tauri bundle --bundles app --config src-tauri/tauri.appstore.conf.json -
cargo
cargo tauri build --no-bundle # bundle for distribution outside the macOS App Store cargo tauri bundle --bundles app,dmg # bundle for App Store distribution cargo tauri bundle --bundles app --config src-tauri/tauri.appstore.conf.json
Versioning
Your application version can be defined in the tauri.conf.json > version configuration option, which is the recommended way for managing the app version. If that config value is not set, Tauri uses the package > version value from your src-tauri/Cargo.toml file instead.
Note
Some platforms have some limitations and special cases for the version string. See the individual distribution documentation pages for more information.
Signing
Code signing enhances the security of your application by applying a digital signature to your application’s executables and bundles, validating your identity of the provider of your application.
Signing is required on most platforms. See the documentation for each platform for more information.
macOSCode signing and notarization for macOS apps
WindowsCode signing Windows installers
LinuxCode signing Linux packages
AndroidCode signing for Android
iOSCode signing for iOS
Distributing
Learn how to distribute your application for each platform.
Linux
For Linux you can distribute your app using the Debian package, Snap, AppImage, Flatpak, RPM or Arch User Repository (AUR) formats.
AppImageDistribute as an AppImage
AURPublishing To The Arch User Repository
DebianDistribute as a Debian package
RPMDistribute as an RPM package
SnapcraftDistribute on Snapcraft.io
macOS
For macOS you can either distribute your application directly to the App Store or ship a DMG installer as direct download. Both methods requires code signing, and distributing outside the App Store also requires notarization.
App BundleDistribute macOS apps as an App Bundle
App StoreDistribute iOS and macOS apps to the App Store
DMGDistribute macOS apps as Apple Disk Images
Windows
Learn how to distribute to the Microsoft Store or configure a Windows installer.
Microsoft StoreDistribute Windows apps to the Microsoft Store
Windows InstallerDistribute installers for Windows
Android
Distribute your Android application to Google Play.
Google PlayDistribute Android apps to Google Play
iOS
Learn how to upload your application to the App Store.
App StoreDistribute iOS and macOS apps to the App Store
Cloud Services
Distribute your application to Cloud services that globally distribute your application and support auto updates out of the box.
CrabNebula CloudDistribute your app using CrabNebula
App Store
The Apple App Store is the app marketplace maintained by Apple. You can distribute your Tauri app targeting macOS and iOS via this App Store.
This guide only covers details for distributing apps directly to the App Store. See the general App Bundle for more information on macOS distribution options and configurations.
Requirements
Distributing iOS and macOS apps requires enrolling to the Apple Developer program.
Additionally, you must setup code signing for macOS and iOS.
Changing App Icon
After running tauri ios init to setup the Xcode project, you can use the tauri icon command to update the app icons.
-
npm
npm run tauri icon /path/to/app-icon.png -- --ios-color '#fff' -
yarn
yarn tauri icon /path/to/app-icon.png --ios-color '#fff' -
pnpm
pnpm tauri icon /path/to/app-icon.png --ios-color '#fff' -
deno
deno task tauri icon /path/to/app-icon.png --ios-color '#fff' -
bun
bun tauri icon /path/to/app-icon.png --ios-color '#fff' -
cargo
cargo tauri icon /path/to/app-icon.png --ios-color '#fff'
The --ios-color argument defines the background color for the iOS icons.
Setting up
After enrolling to the Apple Developer program, the first step to distribute your Tauri app in the App Store is to register your app in the App Store Connect.
Note
The value provided in the Bundle ID field must match the identifier defined in tauri.conf.json > identifier.
Build and upload
The Tauri CLI can package your app for macOS and iOS. Running on a macOS machine is a requirement.
Tauri derives the CFBundleVersion from the value defined in [tauri.conf.json > version]. You can set a custom bundle version in the [tauri.conf.json > bundle > iOS > bundleVersion] or [tauri.conf.json > bundle > macOS > bundleVersion] configuration if you need a different bundle version scheme e.g. sequential codes:
tauri.conf.json
{
"bundle": {
"iOS": {
+"bundleVersion": "100"
}
}
}
Caution
Code signing is required. See the documentation for macOS and iOS.
Note that Tauri leverages Xcode for the iOS app so you can use Xcode to archive and distribute for iOS instead of the Tauri CLI. To open the iOS project in Xcode for building you must run the following command:
-
npm
npm run tauri ios build -- --open -
yarn
yarn tauri ios build --open -
pnpm
pnpm tauri ios build --open -
deno
deno task tauri ios build --open -
bun
bun tauri ios build --open -
cargo
cargo tauri ios build --open
macOS
To upload your app to the App Store, first you must ensure all required configuration options are set so you can package the App Bundle, create a signed .pkg file and upload it.
The following sections will guide you through the process.
Setup
Your app must include some configurations to be accepted by the App Store verification system.
Tip
The following sections guides you through configuring your app for App Store submissions.
To apply the following config changes only when building for App Store, you can create a separate Tauri configuration file:
"src-tauri/tauri.appstore.conf.json
{
"bundle": {
"macOS": {
"entitlements": "./Entitlements.plist",
"files": {
"embedded.provisionprofile": "path/to/profile-name.provisionprofile"
}
}
}
}
Then merge that config file with the main one when bundling your Tauri app for App Store:
-
npm
npm run tauri build -- --no-bundle npm run tauri bundle -- --bundles app --target universal-apple-darwin --config src-tauri/tauri.appstore.conf.json -
yarn
yarn tauri build --no-bundle yarn tauri bundle --bundles app --target universal-apple-darwin --config src-tauri/tauri.appstore.conf.json -
pnpm
pnpm tauri build --no-bundle pnpm tauri bundle --bundles app --target universal-apple-darwin --config src-tauri/tauri.appstore.conf.json -
deno
deno task tauri build --no-bundle deno task tauri bundle --bundles app --target universal-apple-darwin --config src-tauri/tauri.appstore.conf.json -
bun
bun tauri build --no-bundle bun tauri bundle --bundles app --target universal-apple-darwin --config src-tauri/tauri.appstore.conf.json -
cargo
cargo tauri build --no-bundle cargo tauri bundle --bundles app --target universal-apple-darwin --config src-tauri/tauri.appstore.conf.json
This is particularly useful when setting up your CI/CD to upload your app to the App Store while not requiring the provision profile locally or when compiling the app for distribution outside the App Store.
- Category
Your app must define its tauri.conf.json > bundle > category to be displayed in the App Store:
tauri.conf.json
{
"bundle": {
+"category": "Utility"
}
}
- Provisioning profile
You must also create a provisioning profile for your app to be accepted by Apple.
In the Identifiers page, create a new App ID and make sure its “Bundle ID” value matches the identifier set in tauri.conf.json > identifier.
Navigate to the Profiles page to create a new provisioning profile. For App Store macOS distribution, it must be a “Mac App Store Connect” profile. Select the appropriate App ID and link the certificate you are using for code signing.
After creating the provisioning profile, download it and save it to a known location and configure Tauri to include it in your app bundle:
tauri.conf.json
{
"bundle": {
"macOS": {
+"files": {
+"embedded.provisionprofile": "path/to/profile-name.provisionprofile"
+ }
}
}
}
- Info.plist
Your app must comply with encryption export regulations. See the official documentation for more information.
Create a Info.plist file in the src-tauri folder:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ITSAppUsesNonExemptEncryption</key>
<false/> # or `true` if your app uses encryption
</dict>
</plist>
- Entitlements
Your app must include the App Sandbox capability to be distributed in the App Store. Additionally, you must also set your App ID and Team ID in the code signing entitlements.
Create a Entitlements.plist file in the src-tauri folder:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.application-identifier</key>
<string>$TEAM_ID.$IDENTIFIER</string>
<key>com.apple.developer.team-identifier</key>
<string>$TEAM_ID</string>
</dict>
</plist>
Note that you must replace $IDENTIFIER with the tauri.conf.json > identifier value and $TEAM_ID with your Apple Developer team ID, which can be found in the App ID Prefix section in the Identifier you created for the provisioning profile.
And reference that file in the macOS bundle configuration tauri.conf.json > bundle > macOS > entitlements:
tauri.conf.json
{
"bundle": {
"macOS": {
+"entitlements": "./Entitlements.plist"
}
}
}
You now must build your application with code signing enabled for the entitlements to apply.
Make sure your app works when running in an App Sandbox context.
Build
You must upload your macOS application as a .pkg file to the App Store. Run the following command to package your app as a macOS App Bundle (.app extension):
tauri build --bundles app --target universal-apple-darwin
Note
The above command creates an Universal App Binary application, supporting both Apple Silicon and Intel processors.
If you prefer to only support Apple Silicon instead, you must change tauri.conf.json > bundle > macOS > minimumSystemVersion to 12.0:
tauri.conf.json
{
"bundle": {
"macOS": {
+"minimumSystemVersion": "12.0"
}
}
}
And change the CLI command and output path based on the Mac system you are running:
-
if your build system uses an Apple Silicon chip, remove the
--target universal-apple-darwinarguments and usetarget/releaseinstead oftarget/universal-apple-darwin/releasein the paths referenced below. -
if your build system uses an Intel chip:
-
install the Rust Apple Silicon target:
rustup target add aarch64-apple-darwin -
change the
universal-apple-darwinargument toaarch64-apple-darwinand usetarget/aarch64-apple-darwin/releaseinstead oftarget/universal-apple-darwin/releasein the paths referenced below.
-
See the App Bundle distribution guide for more information on configuration options.
To generate a signed .pkg from your app bundle, run the following command:
xcrun productbuild --sign "<certificate signing identity>" --component "target/universal-apple-darwin/release/bundle/macos/$APPNAME.app" /Applications "$APPNAME.pkg"
Note that you must replace $APPNAME with your app name.
Note
You must sign the PKG with a Mac Installer Distribution signing certificate.
Upload
Now you can use the altool CLI to upload your app PKG to the App Store:
xcrun altool --upload-app --type macos --file "$APPNAME.pkg" --apiKey $APPLE_API_KEY_ID --apiIssuer $APPLE_API_ISSUER
Note that altool requires an App Store Connect API key to upload your app. See the authentication section for more information.
Your app will then be validated by Apple and available in TestFlight if approved.
iOS
To build your iOS app, run the tauri ios build command:
-
npm
npm run tauri ios build -- --export-method app-store-connect -
yarn
yarn tauri ios build --export-method app-store-connect -
pnpm
pnpm tauri ios build --export-method app-store-connect -
deno
deno task tauri ios build --export-method app-store-connect -
bun
bun tauri ios build --export-method app-store-connect -
cargo
cargo tauri ios build --export-method app-store-connect
The generated IPA file can be found in src-tauri/gen/apple/build/arm64/$APPNAME.ipa.
Note that you must replace $APPNAME with your app name.
Now you can use the altool CLI to upload your iOS app to the App Store:
xcrun altool --upload-app --type ios --file "src-tauri/gen/apple/build/arm64/$APPNAME.ipa" --apiKey $APPLE_API_KEY_ID --apiIssuer $APPLE_API_ISSUER
Note that altool requires an App Store Connect API key to upload your app. See the authentication section for more information.
Your app will then be validated by Apple and available in TestFlight if approved.
Authentication
The iOS and macOS apps are uploaded using altool, which uses an App Store Connect API key to authenticate.
To create a new API key, open the App Store Connect’s Users and Access page, select the Integrations > Individual Keys tab, click on the Add button and select a name and the Developer access. The APPLE_API_ISSUER (Issuer ID) is presented above the keys table, and the APPLE_API_KEY_ID is the value on the Key ID column on that table. You also need to download the private key, which can only be done once and is only visible after a page reload (the button is shown on the table row for the newly created key). The private key file path must be saved as AuthKey\_<APPLE_API_KEY_ID>.p8 in one of these directories:<current-working-directory>/private_keys, ~/private_keys, ~/.private_keysor~/.appstoreconnect/private_keys.
AppImage
AppImage is a distribution format that does not rely on the system installed packages and instead bundles all dependencies and files needed by the application. For this reason, the output file is larger but easier to distribute since it is supported on many Linux distributions and can be executed without installation. The user just needs to make the file executable (chmod a+x MyProject.AppImage) and can then run it (./MyProject.AppImage).
AppImages are convenient, simplifying the distribution process if you cannot make a package targeting the distribution’s package manager. Still, you should carefully use it as the file size grows from the 2-6 MB range to 70+ MB.
Note
GUI apps on macOS and Linux do not inherit the $PATH from your shell dotfiles (.bashrc, .bash_profile, .zshrc, etc). Check out Tauri’s fix-path-env-rs crate to fix this issue.
Limitations
Core libraries such as glibc frequently break compatibility with older systems. For this reason, you must build your Tauri application using the oldest base system you intend to support that also provides Tauri v2’s required WebKitGTK 4.1 packages. Ubuntu 22.04 and Debian 12 are suitable baseline examples because they provide libwebkit2gtk-4.1-dev from their standard package repositories. Building on a newer base system can raise the minimum glibc version required by your app, so when running on an older system, you may face a runtime error like /usr/lib/libc.so.6: version 'GLIBC_2.33' not found. We recommend using a Docker container or GitHub Actions to build your Tauri application for Linux.
See the issues tauri-apps/tauri#1355 and rust-lang/rust#57497, in addition to the AppImage guide for more information.
Multimedia support via GStreamer
If your app plays audio/video you need to enable tauri.conf.json > bundle > linux > appimage > bundleMediaFramework. This will increase the size of the AppImage bundle to include additional gstreamer files needed for media playback. This flag is currently only fully supported on Ubuntu build systems. Make sure that your build system has all the plugins your app may need at runtime.
Caution
GStreamer plugins in the ugly package are licensed in a way that may make it hard to distribute them as part of your app.
Custom Files
To include custom files in the AppImage that you do not want to include via Tauri’s resources feature, you can provide a list of files or folders in tauri.conf.json > bundle > linux > appimage > files. The configuration object maps the path in the AppImage to the path to the file on your filesystem, relative to the tauri.conf.json file. Here’s an example configuration:
tauri.conf.json
{
"bundle": {
"linux": {
"appimage": {
"files": {
"/usr/share/README.md": "../README.md", // copies the ../README.md file to <appimage>/usr/share/README.md
"/usr/assets": "../assets/" // copies the entire ../assets directory to <appimage>/usr/assets
}
}
}
}
}
Note
Note that the destination paths must currently begin with /usr/.
AppImages for ARM-based devices
August 2025 Update
Github has released publicly available ubuntu-22.04-arm and ubuntu-24.04-arm runners. You can use these to build your app with no changes, a typical build should take ~10 minutes.
linuxdeploy, the AppImage tooling Tauri uses, currently does not support cross-compiling ARM AppImages. This means ARM AppImages can only be built on ARM devices or emulators.
Check out our GitHub Action guide for an example workflow that leverages QEMU to build the app. Note that this is extremely slow and only recommended in public repositories where Build Minutes are free. In private repositories GitHub’s ARM runners should be more cost-efficient and much easier to set up.
AUR
Publishing To The Arch User Repository
Setup
First go to https://aur.archlinux.org and make an account. Be sure to add the proper ssh keys. Next, clone an empty git repository using this command.
git clone https://aur.archlinux.org/your-repo-name
After completing the steps above, create a file with the name PKGBUILD. Once the file is created you can move onto the next step.
Writing a PKGBUILD file
PKGBUILD
pkgname=<pkgname>
pkgver=1.0.0
pkgrel=1
pkgdesc="Description of your app"
arch=('x86_64' 'aarch64')
url="https://github.com/<user>/<project>"
license=('MIT')
depends=('cairo' 'desktop-file-utils' 'gdk-pixbuf2' 'glib2' 'gtk3' 'hicolor-icon-theme' 'libsoup' 'pango' 'webkit2gtk-4.1')
options=('!strip' '!emptydirs')
install=${pkgname}.install
source_x86_64=("${url}/releases/download/v${pkgver}/appname_${pkgver}_amd64.deb")
source_aarch64=("${url}/releases/download/v${pkgver}/appname_${pkgver}_arm64.deb")
- At the top of the file, define your package name and assign it the variable
pkgname. - Set your
pkgvervariable. Typically it is best to use this variable in the source variable to increase maintainability. - The
pkgdescvariable on your aur repo’s page and tells vistors what your app does. - The
archvariable controls what architectures can install your package. - The
urlvariable, while not required, helps to make your package appear more professional. - The
installvariable specifies the name of .install script which will be run when the package is installed, removed or upgraded. - The
dependsvariable includes a list of items that are required to make your app run. For any Tauri app you must include all of the dependencies shown above. - The
sourcevariable is required and defines the location where your upstream package is. You can make asourcearchitecture specific by adding the architecture to the end of the variable name.
Generating .SRCINFO
In order to push your repo to the aur you must generate an .SRCINFO file. This can be done with this command.
makepkg --printsrcinfo > .SRCINFO
Testing
Testing the app is extremely simple. All you have to do is run makepkg within the same directory as the PKGBUILD file and see if it works
Publishing
Finally, after the testing phase is over, you can publish the application to AUR (Arch User Repository) with these commands.
git add .
git commit -m "Initial Commit"
git push
If all goes well, your repository should now appear on the AUR website.
Examples
Extracting From A Debian Package
PKGBUILD
# Maintainer:
# Contributor:
pkgname=<pkgname>
pkgver=1.0.0
pkgrel=1
pkgdesc="Description of your app"
arch=('x86_64' 'aarch64')
url="https://github.com/<user>/<project>"
license=('MIT')
depends=('cairo' 'desktop-file-utils' 'gdk-pixbuf2' 'glib2' 'gtk3' 'hicolor-icon-theme' 'libsoup' 'pango' 'webkit2gtk-4.1')
options=('!strip' '!debug')
install=${pkgname}.install
source_x86_64=("${url}/releases/download/v${pkgver}/appname_${pkgver}_amd64.deb")
source_aarch64=("${url}/releases/download/v${pkgver}/appname_${pkgver}_arm64.deb")
sha256sums_x86_64=('ca85f11732765bed78f93f55397b4b4cbb76685088553dad612c5062e3ec651f')
sha256sums_aarch64=('ed2dc3169d34d91188fb55d39867713856dd02a2360ffe0661cb2e19bd701c3c')
package() {
# Extract package data
tar -xvf data.tar.gz -C "${pkgdir}"
}
my-tauri-app.install
post_install() {
gtk-update-icon-cache -q -t -f usr/share/icons/hicolor
update-desktop-database -q
}
post_upgrade() {
post_install
}
post_remove() {
gtk-update-icon-cache -q -t -f usr/share/icons/hicolor
update-desktop-database -q
}
Building from source
PKGBUILD
# Maintainer:
pkgname=<pkgname>-git
pkgver=<pkgver>
pkgrel=1
pkgdesc="Description of your app"
arch=('x86_64' 'aarch64')
url="https://github.com/<user>/<project>"
license=('MIT')
depends=('cairo' 'desktop-file-utils' 'gdk-pixbuf2' 'glib2' 'gtk3' 'hicolor-icon-theme' 'libsoup' 'pango' 'webkit2gtk-4.1')
makedepends=('git' 'openssl' 'appmenu-gtk-module' 'libappindicator-gtk3' 'librsvg' 'cargo' 'pnpm' 'nodejs')
provides=('<pkgname>')
conflicts=('<binname>' '<pkgname>')
source=("git+${url}.git")
sha256sums=('SKIP')
pkgver() {
cd <project>
( set -o pipefail
git describe --long --abbrev=7 2>/dev/null | sed 's/\([^-]*-g\)/r\1/;s/-/./g' ||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short=7 HEAD)"
)
}
prepare() {
cd <project>
pnpm install
}
build() {
cd <project>
pnpm tauri build -b deb
}
package() {
cp -a <project>/src-tauri/target/release/bundle/deb/<project>_${pkgver}_*/data/* "${pkgdir}"
}
Distributing with CrabNebula Cloud
CrabNebula is an official Tauri partner providing services and tooling for Tauri applications. The CrabNebula Cloud is a platform for application distribution that seamlessly integrates with the Tauri updater.
The Cloud offers a Content Delivery Network (CDN) that is capable of shipping your application installers and updates globally while being cost effective and exposing download metrics.
With the CrabNebula Cloud service it is simple to implement multiple release channels, download buttons for your application website and more.
Setting up your Tauri app to use the Cloud is easy: all you need to do is to sign in to the Cloud website using your GitHub account, create your organization and application and install its CLI to create a release and upload the Tauri bundles. Additionally, a GitHub Action is provided to simplify the process of using the CLI on GitHub workflows.
For more information, see the CrabNebula Cloud documentation.
Debian
The stock Debian package generated by the Tauri bundler has everything you need to ship your application to Debian-based Linux distributions, defining your application’s icons, generating a Desktop file, and specifying the dependencies libwebkit2gtk-4.1-0 and libgtk-3-0, along with libappindicator3-1 if your app uses the system tray.
Note
GUI apps on macOS and Linux do not inherit the $PATH from your shell dotfiles (.bashrc, .bash_profile, .zshrc, etc). Check out Tauri’s fix-path-env-rs crate to fix this issue.
Limitations
Core libraries such as glibc frequently break compatibility with older systems. For this reason, you must build your Tauri application using the oldest base system you intend to support that also provides Tauri v2’s required WebKitGTK 4.1 packages. Ubuntu 22.04 and Debian 12 are suitable baseline examples because they provide libwebkit2gtk-4.1-dev from their standard package repositories. Building on a newer base system can raise the minimum glibc version required by your app, so when running on an older system, you may face a runtime error like /usr/lib/libc.so.6: version 'GLIBC_2.33' not found. We recommend using a Docker container or GitHub Actions to build your Tauri application for Linux.
See the issues tauri-apps/tauri#1355 and rust-lang/rust#57497, in addition to the AppImage guide for more information.
Custom Files
Tauri exposes a few configurations for the Debian package in case you need more control.
If your app depends on additional system dependencies you can specify them in tauri.conf.json > bundle > linux > deb.
To include custom files in the Debian package, you can provide a list of files or folders in tauri.conf.json > bundle > linux > deb > files. The configuration object maps the path in the Debian package to the path to the file on your filesystem, relative to the tauri.conf.json file. Here’s an example configuration:
{
"bundle": {
"linux": {
"deb": {
"files": {
"/usr/share/README.md": "../README.md", // copies the README.md file to /usr/share/README.md
"/usr/share/assets": "../assets/" // copies the entire assets directory to /usr/share/assets
}
}
}
}
}
Cross-Compiling for ARM-based Devices
This guide covers manual compilation. Check out our GitHub Action guide for an example workflow that leverages QEMU to build the app. This will be much slower but will also be able to build AppImages.
Manual compilation is suitable when you don’t need to compile your application frequently and prefer a one-time setup. The following steps expect you to use a Linux distribution based on Debian/Ubuntu.
-
Install Rust targets for your desired architecture
- For ARMv7 (32-bit):
rustup target add armv7-unknown-linux-gnueabihf - For ARMv8 (ARM64, 64-bit):
rustup target add aarch64-unknown-linux-gnu
- For ARMv7 (32-bit):
-
Install the corresponding linker for your chosen architecture
- For ARMv7:
sudo apt install gcc-arm-linux-gnueabihf - For ARMv8 (ARM64):
sudo apt install gcc-aarch64-linux-gnu
- For ARMv7:
-
Open or create the file
<project-root>/.cargo/config.tomland add the following configurations accordingly[target.armv7-unknown-linux-gnueabihf] linker = "arm-linux-gnueabihf-gcc" [target.aarch64-unknown-linux-gnu] linker = "aarch64-linux-gnu-gcc" -
Enable the respective architecture in the package manager
- For ARMv7:
sudo dpkg --add-architecture armhf - For ARMv8 (ARM64):
sudo dpkg --add-architecture arm64
- For ARMv7:
-
Adjusting Package Sources
On Debian, this step should not be necessary, but on other distributions, you might need to edit /etc/apt/sources.list to include the ARM architecture variant. For example on Ubuntu 22.04 add these lines to the bottom of the file (Remember to replace jammy with the codename of your Ubuntu version):
deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy main restricted deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates main restricted deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy universe deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates universe deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy multiverse deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates multiverse deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-backports main restricted universe multiverse deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security main restricted deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security universe deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security multiverseThen, to prevent issues with the main packages, you have to add the correct main architecture to all other lines the file contained beforehand. For standard 64-bit systems you need to add [arch=amd64], the full file on Ubuntu 22.04 then looks similar to this:
Show solution
# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to # newer versions of the distribution. deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy main restricted # deb-src http://archive.ubuntu.com/ubuntu/ jammy main restricted ## Major bug fix updates produced after the final release of the ## distribution. deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy-updates main restricted # deb-src http://archive.ubuntu.com/ubuntu/ jammy-updates main restricted ## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu ## team. Also, please note that software in universe WILL NOT receive any ## review or updates from the Ubuntu security team. deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy universe # deb-src http://archive.ubuntu.com/ubuntu/ jammy universe deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy-updates universe # deb-src http://archive.ubuntu.com/ubuntu/ jammy-updates universe ## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu ## team, and may not be under a free licence. Please satisfy yourself as to ## your rights to use the software. Also, please note that software in ## multiverse WILL NOT receive any review or updates from the Ubuntu ## security team. deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy multiverse # deb-src http://archive.ubuntu.com/ubuntu/ jammy multiverse deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy-updates multiverse ## N.B. software from this repository may not have been tested as ## extensively as that contained in the main release, although it includes ## newer versions of some applications which may provide useful features. ## Also, please note that software in backports WILL NOT receive any review ## or updates from the Ubuntu security team. deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy-backports main restricted universe multiverse # deb-src http://archive.ubuntu.com/ubuntu/ jammy-backports main restricted universe multiverse deb [arch=amd64] http://security.ubuntu.com/ubuntu/ jammy-security main restricted # deb-src http://security.ubuntu.com/ubuntu/ jammy-security main restricted deb [arch=amd64] http://security.ubuntu.com/ubuntu/ jammy-security universe # deb-src http://security.ubuntu.com/ubuntu/ jammy-security universe deb [arch=amd64] http://security.ubuntu.com/ubuntu/ jammy-security multiverse # deb-src http://security.ubuntu.com/ubuntu/ jammy-security multiverse deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy main restricted deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates main restricted deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy universe deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates universe deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy multiverse deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates multiverse deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-backports main restricted universe multiverse deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security main restricted deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security universe deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security multiverse -
Update the package information:
sudo apt-get update && sudo apt-get upgrade -y -
Install the required webkitgtk library for your chosen architecture
- For ARMv7:
sudo apt install libwebkit2gtk-4.1-dev:armhf - For ARMv8 (ARM64):
sudo apt install libwebkit2gtk-4.1-dev:arm64
- For ARMv7:
-
Install OpenSSL or use a vendored version
This is not always required so you may want to proceed first and check if you see errors like
Failed to find OpenSSL development headers.-
Either install the development headers system-wide:
- For ARMv7:
sudo apt install libssl-dev:armhf - For ARMv8 (ARM64):
sudo apt install libssl-dev:arm64
- For ARMv7:
-
Or enable the vendor feature for the OpenSSL Rust crate which will affect all other Rust dependencies using the same minor version. You can do so by adding this to the dependencies section in your
Cargo.tomlfile:
openssl-sys = {version = "0.9", features = ["vendored"]} -
-
Set the
PKG_CONFIG_SYSROOT_DIRto the appropriate directory based on your chosen architecture- For ARMv7:
export PKG_CONFIG_SYSROOT_DIR=/usr/arm-linux-gnueabihf/ - For ARMv8 (ARM64):
export PKG_CONFIG_SYSROOT_DIR=/usr/aarch64-linux-gnu/
- For ARMv7:
-
Build the app for your desired ARM version
- For ARMv7: cargo tauri build –target armv7-unknown-linux-gnueabihf
- For ARMv8 (ARM64): cargo tauri build –target aarch64-unknown-linux-gnu
Choose the appropriate set of instructions based on whether you want to cross-compile your Tauri application for ARMv7 or ARMv8 (ARM64). Please note that the specific steps may vary depending on your Linux distribution and setup.
DMG
The DMG (Apple Disk Image) format is a common macOS installer file that wraps your App Bundle in a user-friendly installation window.
The installer window includes your app icon and the Applications folder icon, where the user is expected to drag the app icon to the Applications folder icon to install it. It is the most common installation method for macOS applications distributed outside the App Store.
This guide only covers details for distributing apps outside the App Store using the DMG format. See the App Bundle distribution guide for more information on macOS distribution options and configurations. To distribute your macOS app in the App Store, see the App Store distribution guide.
To create an Apple Disk Image for your app you can use the Tauri CLI and run the tauri build command in a Mac computer:
-
npm
npm run tauri build -- --bundles dmg -
yarn
yarn tauri build --bundles dmg -
pnpm
pnpm tauri build --bundles dmg -
deno
deno task tauri build --bundles dmg -
bun
bun tauri build --bundles dmg -
cargo
cargo tauri build --bundles dmg
Note
GUI apps on macOS and Linux do not inherit the $PATH from your shell dotfiles (.bashrc, .bash_profile, .zshrc, etc). Check out Tauri’s fix-path-env-rs crate to fix this issue.
Window background
You can set a custom background image to the DMG installation window with the [tauri.conf.json > bundle > macOS > dmg > background] configuration option:
tauri.conf.json
{
"bundle": {
"macOS": {
+"dmg": {
+"background": "./images/"
+ }
}
}
}
For instance your DMG background image can include an arrow to indicate to the user that it must drag the app icon to the Applications folder.
Window size and position
The default window size is 660x400. If you need a different size to fit your custom background image, set the [tauri.conf.json > bundle > macOS > dmg > windowSize] configuration:
tauri.conf.json
{
"bundle": {
"macOS": {
"dmg": {
+"windowSize": {
+"width": 800,
+"height": 600
+ }
}
}
}
}
Additionally you can set the initial window position via [tauri.conf.json > bundle > macOS > dmg > windowPosition]:
tauri.conf.json
{
"bundle": {
"macOS": {
"dmg": {
+"windowPosition": {
+"x": 400,
+"y": 400
+ }
}
}
}
}
Icon position
You can change the app and Applications folder icon position with the appPosition and applicationFolderPosition configuration values respectively:
tauri.conf.json
{
"bundle": {
"macOS": {
"dmg": {
+"appPosition": {
+"x": 180,
+"y": 220
+ },
+"applicationFolderPosition": {
+"x": 480,
+"y": 220
+ }
}
}
}
}
Caution
Due to a known issue, icon sizes and positions are not applied when creating DMGs on CI/CD platforms. See tauri-apps/tauri#1731 for more information.
Flathub
-
Open Source
- Get your required tools.
git submodule add https://github.com/flatpak/flatpak-builder-tools.git cd flatpak-builder-tools/node/flatpak_node_generator pipx install . # Change this to your prefered installation method- Generate your sources
-
Yarn
# Generate your Node Sources flatpak-node-generator --no-requests-cache -o node-sources.json yarn /path/to/your/lock/file/yarn.lock # Generate your cargo sources python3 flatpak-builder-tools/cargo/flatpak-cargo-generator.py -o cargo-sources.json src-tauri/Cargo.lock -
NPM
# Generate your Node Sources flatpak-node-generator --no-requests-cache -o node-sources.json npm /path/to/your/lock/file/package-lock.json # Generate your cargo sources python3 flatpak-builder-tools/cargo/flatpak-cargo-generator.py -o cargo-sources.json src-tauri/Cargo.lock
- Create your metainfo Make sure to replace the relevant fields.
<?xml version="1.0" encoding="UTF-8"?> <component type="desktop-application"> <id>org.your.id</id> <launchable type="desktop-id">org.your.id.desktop</launchable> <name>Your Apps Name</name> <developer id="io.github.roseblume.rosemusic"> <name>Your Name</name> </developer> <content_rating type="oars-1.1"> </content_rating> <keywords> <keyword>Keyword1</keyword> <keyword>Keyword2</keyword> </keywords> <branding> <color type="primary" scheme_preference="light">#00ffff</color> <color type="primary" scheme_preference="dark">#0c9aff</color> </branding> <recommends> <display_length compare="ge">360</display_length> </recommends> <summary>Your Summary</summary> <metadata_license>MIT</metadata_license> <project_license>MIT</project_license> <url type="homepage">https://github.com/Your-Username/Your-Repo</url> <supports> <control>pointing</control> <control>keyboard</control> <control>touch</control> </supports> <description> <p> Your Description </p> </description> <screenshots> <screenshot type="default"> <image>https://site.com/your-image.png</image> <caption>Your Caption</caption> </screenshot> </screenshots> <releases> <release version="1.0.0" date="2024-11-02" > <description> <ul> <li>Updated UI</li> <li>Added Electronic Genre</li> </ul> </description> </release> </releases> <update_contact>your-email@place.com</update_contact> </component>Your metadata is recommended to be included into your debian bundle although it is not required. This can be done by adjusting your bundle configuration like so.
"linux": { "deb": { "files": { "/usr/share/metainfo/org.your.id.metainfo.xml": "relative/path/from/your/tauri.conf.json/to/your/org.your.id.metainfo.xml" } } }- Create your manifest
id: org.your.id runtime: org.gnome.Platform runtime-version: '47' sdk: org.gnome.Sdk command: tauri-app finish-args: - --socket=wayland # Permission needed to show the window - --socket=fallback-x11 # Permission needed to show the window on legacy windowing systems - --device=dri # OpenGL, not necessary for all projects - --share=ipc sdk-extensions: - org.freedesktop.Sdk.Extension.node20 - org.freedesktop.Sdk.Extension.rust-stable build-options: append-path: /usr/lib/sdk/node20/bin:/usr/lib/sdk/rust-stable/bin modules: - name: your-command buildsystem: simple env: HOME: /run/build/your-module CARGO_HOME: /run/build/your-module/src-tauri XDG_CACHE_HOME: /run/build/your-module/flatpak-node/cache yarn_config_offline: 'true' yarn_config_cache: /run/build/your-module/flatpak-node/yarn-cache sources: - type: git url: https://github.com/Your-Github-Username/Your-Git-Repo.git tag: v1.2.2 - cargo-sources.json - node-sources.json build-commands: - echo -e 'yarn-offline-mirror "/run/build/your-module/flatpak-node/yarn-mirror"\nyarn-offline-mirror-pruning true' > /run/build/your-module/.yarnrc - mkdir -p src-tauri/.cargo && echo -e '[source.crates-io]\nreplace-with = "vendored-sources"\n\n[source.vendored-sources]\ndirectory = "/run/build/your-module/cargo/vendor"' > src-tauri/.cargo/config.toml - yarn install --offline --immutable --immutable-cache --inline-builds - yarn run tauri build -- -b deb - ar -x src-tauri/target/release/bundle/deb/\*.deb - tar -xf src-tauri/target/release/bundle/deb/your-app/data.tar.gz - install -Dm755 src-tauri/target/release/bundle/deb/your-app/data/usr/bin/your-command /app/bin/your-command - install -Dm644 src-tauri/target/release/bundle/deb/your-app/data/usr/share/applications/your-app.desktop /app/share/applications/org.your.id.desktop - install -Dm644 src-tauri/target/release/bundle/deb/your-app/data/usr/share/icons/hicolor/128x128/apps/your-app.png /app/share/icons/hicolor/128x128/apps/your-app.png - install -Dm644 src-tauri/target/release/bundle/deb/your-app/data/usr/share/icons/hicolor/32x32/apps/your-app.png /app/share/icons/hicolor/32x32/apps/your-app.png - install -Dm644 src-tauri/target/release/bundle/deb/your-app/data/usr/share/icons/hicolor/256x256@2/apps/your-app.png /app/share/icons/hicolor/512x512/apps/your-app.png - install -Dm644 src-tauri/target/release/bundle/deb/your-app/data/usr/share/icons/hicolor/scalable/apps/your-app.svg /app/share/icons/hicolor/scalable/apps/your-app.svg - install -Dm644 src-tauri/target/release/bundle/deb/your-app/data/usr/share/metainfo/org.your.id /app/share/metainfo/org.your.idSubmitting To Flathub
1. Fork The Flathub Repository
2. Clone the Fork
git clone --branch=new-pr git@github.com:your_github_username/flathub.git3. Enter the repository
cd flathub4. Create a new branch
git checkout -b your_app_name5. Open a pull request against the
new-prbranch on github6. Your app will now enter the review process in which you may be asked to make changes to your project.
-
Closed Source
# Generate your Node Sources flatpak-node-generator --no-requests-cache -o node-sources.json yarn /path/to/your/lock/file/yarn.lock # Generate your cargo sources python3 flatpak-builder-tools/cargo/flatpak-cargo-generator.py -o cargo-sources.json src-tauri/Cargo.lock -
Yarn
# Generate your Node Sources flatpak-node-generator --no-requests-cache -o node-sources.json npm /path/to/your/lock/file/package-lock.json # Generate your cargo sources python3 flatpak-builder-tools/cargo/flatpak-cargo-generator.py -o cargo-sources.json src-tauri/Cargo.lock -
NPM
For detailed information on how Flatpak works, you can read Building your first Flatpak
This guide assumes you want to distribute your Flatpak via Flathub, the most commonly used platform for Flatpak distribution. If you plan on using other platforms, please consult their documentation instead.
Prerequisites
To test your app inside the Flatpak runtime you can build the Flatpak locally first before uploading your app to Flathub. This can also be helpful if you want to quickly share development builds.
1. Install
flatpakandflatpak-builderTo build Flatpaks locally you need the
flatpakandflatpak-buildertools. For example on Ubuntu you can run this command:-
Debian
sudo apt install flatpak flatpak-builder -
Arch
sudo pacman -S --needed flatpak flatpak-builder -
Fedora
sudo dnf install flatpak flatpak-builder -
Gentoo
sudo emerge --ask \ sys-apps/flatpak \ dev-util/flatpak-builder
2. Install the Flatpak Runtime
flatpak install flathub org.gnome.Platform//46 org.gnome.Sdk//463. Build the .deb of your tauri-app
4. Create an AppStream MetaInfo file
5. Create the flatpak manifest
flatpak-builder.yaml
id: <identifier> runtime: org.gnome.Platform runtime-version: '47' sdk: org.gnome.Sdk command: <main_binary_name> finish-args: - --socket=wayland # Permission needed to show the window - --socket=fallback-x11 # Permission needed to show the window - --device=dri # OpenGL, not necessary for all projects - --share=ipc - --talk-name=org.kde.StatusNotifierWatcher # Optional: needed only if your app uses the tray icon - --filesystem=xdg-run/tray-icon:create # Optional: needed only if your app uses the tray icon - see an alternative way below # - --env=WEBKIT_DISABLE_COMPOSITING_MODE=1 # Optional: may solve some issues with black webviews on Wayland modules: - name: binary buildsystem: simple sources: # A reference to the previously generated flatpak metainfo file - type: file path: flatpak.metainfo.xml # If you use GitHub releases, you can target an existing remote file - type: file url: https://github.com/your_username/your_repository/releases/download/v1.0.1/yourapp_1.0.1_amd64.deb sha256: 08305b5521e2cf0622e084f2b8f7f31f8a989fc7f407a7050fa3649facd61469 # This is required if you are using a remote source only-arches: [x86_64] # This source is only used on x86_64 Computers # You can also use a local file for testing # - type: file # path: yourapp_1.0.1_amd64.deb build-commands: - set -e # Extract the deb package - mkdir deb-extract - ar -x *.deb --output deb-extract - tar -C deb-extract -xf deb-extract/data.tar.gz # Copy binary - 'install -Dm755 deb-extract/usr/bin/<executable_name> /app/bin/<executable_name>' # If you bundle files with additional resources, you should copy them: - mkdir -p /app/lib/<product_name> - cp -r deb-extract/usr/lib/<product_name>/. /app/lib/<product_name> - find /app/lib/<product_name> -type f -exec chmod 644 {} \; # Copy desktop file + ensure the right icon is set - sed -i 's/^Icon=.*/Icon=<identifier>/' deb-extract/usr/share/applications/<product_name>.desktop - install -Dm644 deb-extract/usr/share/applications/<product_name>.desktop /app/share/applications/<identifier>.desktop # Copy icons - install -Dm644 deb-extract/usr/share/icons/hicolor/128x128/apps/<main_binary_name>.png /app/share/icons/hicolor/128x128/apps/<identifier>.png - install -Dm644 deb-extract/usr/share/icons/hicolor/32x32/apps/<main_binary_name>.png /app/share/icons/hicolor/32x32/apps/<identifier>.png - install -Dm644 deb-extract/usr/share/icons/hicolor/256x256@2/apps/<main_binary_name>.png /app/share/icons/hicolor/256x256@2/apps/<identifier>.png - install -Dm644 flatpak.metainfo.xml /app/share/metainfo/<identifier>.metainfo.xmlThe Gnome 46 runtime includes all dependencies of the standard Tauri app with their correct versions.
Using tray-icon without changing the Flatpak manifest
If you prefer not opening access from your app to $XDG_RUNTIME_DIR (where tray-icon is saved on linux), you can change the path tauri saves the tray image:
TrayIconBuilder::new() .icon(app.default_window_icon().unwrap().clone()) .temp_dir_path(app.path().app_cache_dir().unwrap()) // will save to the cache folder ($XDG_CACHE_HOME) where the app already has permission .build() .unwrap();5. Install, and Test the app
# Install the flatpak flatpak-builder --force-clean --user --disable-cache --repo flatpak-repo flatpak flatpak-builder.yaml # Run it flatpak run <your flatpak id> # or via your desktop environment # Update it flatpak -y --user update <your flatpak id>Adding additional libraries
If your final binary requires more libraries than the default tauri app, you need to add them in your flatpak manifest. There are two ways to do this. For fast local development, it may work to simply include the already built library file (
.so) from your local system. However, this is not recommended for the final build of the flatpak, as your local library file is not built for the flatpak runtime environment. This can introduce various bugs that can be very hard to find. Therefore, it is recommended to build the library your program depends on from source inside the flatpak as a build step.Submitting to flathub
1. Fork The Flathub Repository
2. Clone the Fork
git clone --branch=new-pr git@github.com:your_github_username/flathub.git3. Enter the repository
cd flathub4. Create a new branch
git checkout -b your_app_name5. Add your apps manifest to the branch. Commit your changes, and then push them.
6. Open a pull request against the
new-prbranch on github7. Your app will now enter the review process in which you may be asked to make changes to your project.
When your pull request is approved then you will receive an invitation to edit your apps repository. From here on you can update your app continuously.
You can read more about this in the flatpak documentation
-
-
Debian
sudo apt install flatpak flatpak-builder -
Arch
sudo pacman -S --needed flatpak flatpak-builder -
Fedora
sudo dnf install flatpak flatpak-builder -
Gentoo
sudo emerge --ask \ sys-apps/flatpak \ dev-util/flatpak-builder
Google Play
Google Play is the Android app distribution service maintained by Google.
This guide covers the requirements for publishing your Android app on Google Play.
Note
Tauri uses an Android Studio project under the hood, so any official practice for building and publishing Android apps also apply to your app. See the official documentation for more information.
Requirements
To distribute Android apps in the Play Store you must create a Play Console developer account.
Additionally, you must setup code signing.
See the release checklist for more information.
Changing App Icon
After running tauri android init to setup the Android Studio project, you can use the tauri icon command to update the app icons.
-
npm
npm run tauri icon /path/to/app-icon.png -
yarn
yarn tauri icon /path/to/app-icon.png -
pnpm
pnpm tauri icon /path/to/app-icon.png -
deno
deno task tauri icon /path/to/app-icon.png -
bun
bun tauri icon /path/to/app-icon.png -
cargo
cargo tauri icon /path/to/app-icon.png
Setting up
Once you’ve created a Play Console developer account, you need to register your app on the Google Play Console website. It will guide you through all the required forms and setup tasks.
Build
You can build an Android App Bundle (AAB) to upload to Google Play by running the following command:
-
npm
npm run tauri android build -- --aab -
yarn
yarn tauri android build --aab -
pnpm
pnpm tauri android build --aab -
deno
deno task tauri android build --aab -
bun
bun tauri android build --aab -
cargo
cargo tauri android build --aab
Tauri derives the version code from the value defined in tauri.conf.json > version (versionCode = major*1000000 + minor*1000 + patch). You can set a custom version code in the [tauri.conf.json > bundle > android > versionCode] configuration if you need a different version code scheme e.g. sequential codes:
tauri.conf.json
{
"bundle": {
"android": {
+"versionCode": 100
}
}
}
Build APKs
The AAB format is the recommended bundle file to upload to Google Play, but it is also possible to generate APKs that can be used for testing or distribution outside the store. To compile APKs for your app you can use the --apk argument:
-
npm
npm run tauri android build -- --apk -
yarn
yarn tauri android build --apk -
pnpm
pnpm tauri android build --apk -
deno
deno task tauri android build --apk -
bun
bun tauri android build --apk -
cargo
cargo tauri android build --apk
Architecture selection
By default Tauri builds your app for all supported architectures (aarch64, armv7, i686 and x86_64). To only compile for a subset of targets, you can use the --target argument:
-
npm
npm run tauri android build -- --aab --target aarch64 --target armv7 -
yarn
yarn tauri android build --aab --target aarch64 --target armv7 -
pnpm
pnpm tauri android build --aab --target aarch64 --target armv7 -
deno
deno task tauri android build --aab --target aarch64 --target armv7 -
bun
bun tauri android build --aab --target aarch64 --target armv7 -
cargo
cargo tauri android build --aab --target aarch64 --target armv7
Separate bundles per architecture
By default the generated AAB and APK is universal, containing all supported targets. To generate individual bundles per target, use the --split-per-abi argument.
Note
This is only useful for testing or distribution outside Google Play, as it reduces the file size but is less convenient to upload. Google Play handles the supported architectures for you.
-
npm
npm run tauri android build -- --apk --split-per-abi -
yarn
yarn tauri android build --apk --split-per-abi -
pnpm
pnpm tauri android build --apk --split-per-abi -
deno
deno task tauri android build --apk --split-per-abi -
bun
bun tauri android build --apk --split-per-abi -
cargo
cargo tauri android build --apk --split-per-abi
Changing the minimum supported Android version
The minimum supported Android version for Tauri apps is Android 7.0 (codename Nougat, SDK 24).
There are some techniques to use newer Android APIs while still supporting older systems. See the Android documentation for more information.
If your app must execute on a newer Android version, you can configure [tauri.conf.json > bundle > android > minSdkVersion]:
tauri.conf.json
{
"bundle": {
"android": {
+"minSdkVersion": 28
}
}
}
Upload
After building your app and generating the Android App Bundle file, which can be found in gen/android/app/build/outputs/bundle/universalRelease/app-universal-release.aab, you can now create a new release and upload it in the Google Play Console.
The first upload must be made manually in the website so it can verify your app signature and bundle identifier. Tauri currently does not offer a way to automate the process of creating Android releases, which must leverage the Google Play Developer API, but it is a work in progress.
macOS Application Bundle
An application bundle is the package format that is executed on macOS. It is a simple directory that includes everything your application requires for successful operation, including your app executable, resources, the Info.plist file and other files such as macOS frameworks.
To package your app as a macOS application bundle you can use the Tauri CLI and run the tauri build command in a Mac computer:
-
npm
npm run tauri build -- --bundles app -
yarn
yarn tauri build --bundles app -
pnpm
pnpm tauri build --bundles app -
deno
deno task tauri build --bundles app -
bun
bun tauri build --bundles app -
cargo
cargo tauri build --bundles app
Note
GUI apps on macOS and Linux do not inherit the $PATH from your shell dotfiles (.bashrc, .bash_profile, .zshrc, etc). Check out Tauri’s fix-path-env-rs crate to fix this issue.
File structure
The macOS app bundle is a directory with the following structure:
├── <productName>.app
│ ├── Contents
│ │ ├── Info.plist
│ │ ├── ...additional files from [`tauri.conf.json > bundle > macOS > files`]
│ ├── MacOS
│ │ ├── <app-name> (app executable)
│ ├── Resources
│ │ ├── icon.icns (app icon)
│ │ ├── ...resources from [`tauri.conf.json > bundle > resources`]
│ ├── _CodeSignature (codesign information generated by Apple)
│ ├── Frameworks
│ ├── PlugIns
│ ├── SharedSupport
See the official documentation for more information.
Native configuration
The app bundle is configured by the Info.plist file, which includes key-value pairs with your app identity and configuration values read by macOS.
Tauri automatically configures the most important properties such as your app binary name, version. bundle identifier, minimum system version and more.
To extend the configuration file, create an Info.plist file in the src-tauri folder and include the key-pairs you desire:
src-tauri/Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSCameraUsageDescription</key>
<string>Request camera access for WebRTC</string>
<key>NSMicrophoneUsageDescription</key>
<string>Request microphone access for WebRTC</string>
</dict>
</plist>
This Info.plist file is merged with the values generated by the Tauri CLI. Be careful when overwriting default values such as application version as they might conflict with other configuration values and introduce unexpected behavior.
See the official Info.plist documentation for more information.
Info.plist localization
The Info.plist file by itself only supports a single language, typically English. If you want to support multiple languages, you can create InfoPlist.strings files for each additional language. Each file belongs in its own language specific lproj directory in the Resources directory in the application bundle.
To bundle these files automatically you can leverage Tauri’s resources feature. To do that, create a file structure in your project following this pattern:
├── src-tauri
│ ├── tauri.conf.json
│ ├── infoplist
│ │ ├── de.lproj
│ │ │ ├── InfoPlist.strings
│ │ ├── fr.lproj
│ │ │ ├── InfoPlist.strings
While the infoplist directory name can be chosen freely, as long as you update it in the resources config below, the lproj directories must follow the <lang-code>.lproj naming and the string catalogue files must be named InfoPlist.strings (capital i and p). For most cases the language code should be a two letter code following BCP 47.
For the Info.plist example shown above, the de.lproj > InfoPlist.strings file could look like this:
de.lproj/InfoPlist.strings
NSCameraUsageDescription = "Kamera Zugriff wird benötigt für WebRTC Funktionalität";
NSMicrophoneUsageDescription = "Mikrofon Zugriff wird benötigt für WebRTC Funktionalität";
Lastly, make Tauri pick up these files by using the resources feature mentioned above:
src-tauri/tauri.conf.json
{
"bundle": {
"resources": {
"infoplist/**": "./"
}
}
}
Entitlements
An entitlement is a special Apple configuration key-value pair that acts as a right or privilege that grants your app particular capabilities, such as act as the user’s default email client and using the App Sandbox feature.
Entitlements are applied when your application is signed. See the code signing documentation for more information.
To define the entitlements required by your application, you must create the entitlements file and configure Tauri to use it.
- Create a
Entitlements.plistfile in thesrc-taurifolder and configure the key-value pairs you app requires:
src-tauri/Entitlements.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
</dict>
</plist>
- Configure Tauri to use the Entitlements.plist file:
tauri.conf.json
{
"bundle": {
"macOS": {
+"entitlements": "./Entitlements.plist"
}
}
}
See the official documentation for more information.
Minimum system version
By default your Tauri application supports macOS 10.13 and above. If you are using an API that requires a newer macOS system and want to enforce that requirement in your app bundle, you can configure the tauri.conf.json > bundle > macOS > minimumSystemVersion value:
tauri.conf.json
{
"bundle": {
"macOS": {
+"minimumSystemVersion": "12.0"
}
}
}
Including macOS frameworks
If your application requires additional macOS frameworks to run, you can list them in the tauri.conf.json > bundle > macOS > frameworks configuration. The frameworks list can include either system or custom frameworks and dylib files.
tauri.conf.json
{
"bundle": {
"macOS": {
+"frameworks": [
+"CoreAudio",
+"./libs/libmsodbcsql.18.dylib",
+"./frameworks/MyApp.framework"
+ ]
}
}
}
Note
- To reference a system framework you can just use its name (without the .framework extension) instead of absolute path
- System frameworks must exist in either the
$HOME/Library/Frameworks,/Library/Frameworks/, or/Network/Library/Frameworks/ - To reference local frameworks and dylib files you must use the complete path to the framework, relative to the
src-tauridirectory
Adding custom files
You can use the tauri.conf.json > bundle > macOS > files configuration to add custom files to your application bundle, which maps the destination path to its source relative to the tauri.conf.json file. The files are added to the <product-name>.app/Contents folder.
tauri.conf.json
{
"bundle": {
"macOS": {
+"files": {
+"embedded.provisionprofile": "./profile-name.provisionprofile",
+"SharedSupport/docs.md": "./docs/index.md"
+ }
}
}
}
In the above example, the profile-name.provisionprofile file is copied to <product-name>.app/Contents/embedded.provisionprofile and the docs/index.md file is copied to <product-name>.app/Contents/SharedSupport/docs.md.
Microsoft Store
Microsoft Store is the Windows app store operated by Microsoft.
This guide only covers details for distributing Windows Apps directly to the Microsoft Store. See the Windows Installer guide for more information on Windows installer distribution options and configurations.
Requirements
To publish apps on the Microsoft Store you must have a Microsoft account and enroll as a developer either as an individual or as a company.
Changing App Icon
The Tauri CLI can generate all icons your app needs, including Microsoft Store icons. Use the tauri icon command to generate app icons from a single PNG or SVG source:
-
npm
npm run tauri icon /path/to/app-icon.png -
yarn
yarn tauri icon /path/to/app-icon.png -
pnpm
pnpm tauri icon /path/to/app-icon.png -
deno
deno task tauri icon /path/to/app-icon.png -
bun
bun tauri icon /path/to/app-icon.png -
cargo
cargo tauri icon /path/to/app-icon.png
Setting up
After you have enrolled as a developer with your Microsoft account you need to register your app in the Apps and Games page. Click New Product, select EXE or MSI app and reserve a unique name for your app.
Build and upload
Currently Tauri only generates EXE and MSI installers, so you must create a Microsoft Store application that only links to the unpacked application. The installer linked in the Microsoft Installer must be offline, handle auto-updates and be code signed.
See the official publish documentation for more information.
Offline Installer
The Windows installer distributed through the Microsoft Store must use the Offline Installer Webview2 installation option.
To only apply this installer configuration when bundling for Microsoft Store, you can define a separate Tauri configuration file:
"src-tauri/tauri.microsoftstore.conf.json
{
"bundle": {
"windows": {
"webviewInstallMode": {
"type": "offlineInstaller"
}
}
}
}
Then merge that config file with the main one when bundling your Tauri app for Microsoft Store:
-
npm
npm run tauri build -- --no-bundle npm run tauri bundle -- --config src-tauri/tauri.microsoftstore.conf.json -
yarn
yarn tauri build --no-bundle yarn tauri bundle --config src-tauri/tauri.microsoftstore.conf.json -
pnpm
pnpm tauri build --no-bundle pnpm tauri bundle --config src-tauri/tauri.microsoftstore.conf.json -
deno
deno task tauri build --no-bundle deno task tauri bundle --config src-tauri/tauri.microsoftstore.conf.json -
bun
bun tauri build --no-bundle bun tauri bundle --config src-tauri/tauri.microsoftstore.conf.json -
cargo
cargo tauri build --no-bundle cargo tauri bundle --config src-tauri/tauri.microsoftstore.conf.json
This is particularly useful when setting up your CI/CD to upload your app to the Microsoft Store while having a separate configuration for the Windows installer you distribute outside the app store.
Silent install
The Microsoft Store requires Win32 installers to support silent installation. If your installer does not install silently, your submission is rejected with an error such as:
10.2.9.2 Security - Package Submissions | Win32 products must install silently.
When you register your installer in Partner Center you must provide the silent install parameters so the Store can run it unattended. Tauri’s NSIS -setup.exe installer installs silently with the /S flag (note the uppercase S):
MyApp_x64-setup.exe /S
Enter /S as the silent install argument in the installer parameters of your Microsoft Store product. If you distribute the MSI installer instead, use the standard msiexec flag /quiet.
Publisher
Your application publisher name cannot match the application product name.
If the publisher configuration value is not set, Tauri derives it from the second part of your bundle identifier. Since the publisher name cannot match the product name, the following configuration is invalid:
tauri.conf.json
{
"productName": "Example",
"identifier": "com.example.app"
}
In this case you can define the publisher value separately to fix this conflict:
tauri.conf.json
{
"productName": "Example",
"identifier": "com.example.app",
+"bundle": {
+"publisher": "Example Inc."
+ }
}
Upload
After building the Windows installer for Microsoft Store, you can upload it to the distribution service of your choice and link it in your application page in the Microsoft Store website.
CrabNebula Cloud
Distributing with CrabNebula Cloud
CrabNebula is an official Tauri partner providing services and tooling for Tauri applications. The CrabNebula Cloud is a platform for application distribution that seamlessly integrates with the Tauri updater.
The Cloud offers a Content Delivery Network (CDN) that is capable of shipping your application installers and updates globally while being cost effective and exposing download metrics.
With the CrabNebula Cloud service it is simple to implement multiple release channels, download buttons for your application website and more.
Setting up your Tauri app to use the Cloud is easy: all you need to do is to sign in to the Cloud website using your GitHub account, create your organization and application and install its CLI to create a release and upload the Tauri bundles. Additionally, a GitHub Action is provided to simplify the process of using the CLI on GitHub workflows.
For more information, see the CrabNebula Cloud documentation.
GitHub
This guide will show you how to use tauri-action in GitHub Actions to easily build and upload your app, and how to make Tauri’s updater query the newly created GitHub release for updates.
Lastly, it will also show how to set up a more complicated build pipeline for Linux Arm AppImages.
Code Signing
To set up code signing for Windows and macOS in your workflow, follow the specific guide for each platform:
If you build a macOS app without an Apple signing certificate, configure an ad-hoc signing identity. This can avoid macOS treating Apple Silicon builds downloaded from GitHub releases as damaged.
Getting Started
To set up tauri-action you must first set up a GitHub repository. You can also use this action on a repository that does not have Tauri configured yet since it can automatically initialize Tauri for you, please see the action’s readme for necessary configuration options.
Go to the Actions tab on your GitHub project page and select “New workflow”, then choose “Set up a workflow yourself”. Replace the file with the workflow from below or from one of the action’s examples.
Configuration
Please see the tauri-action readme for all available configuration options.
When your app is not on the root of the repository, use the projectPath input.
You may freely modify the workflow name, change its triggers, and add more steps such as npm run lint or npm run test. The important part is that you keep the below line at the end of the workflow since this runs the build script and releases your app.
How to Trigger
The release workflow shown below and in the tauri-action examples is triggered by pushed to the release branch. The action automatically creates a git tag and a title for the GitHub release using the application version.
As another example, you can also change the trigger to run the workflow on the push of a version git tag such as app-v0.7.0:
name: 'publish'
on:
push:
tags:
- 'app-v*'
For a full list of possible trigger configurations, check out the official GitHub documentation.
Example Workflow
Below is an example workflow that has been set up to run every time you push to the release branch.
This workflow will build and release your app for Windows x64, Linux x64, Linux Arm64, macOS x64 and macOS Arm64 (M1 and above).
The steps this workflow takes are:
- Checkout the repository using
actions/checkout@v7. - Install Linux system dependencies required to build the app.
- Set up Node.js LTS and a cache for global npm/yarn/pnpm package data using
actions/setup-node@v6. - Set up Rust and a cache for Rust’s build artifacts using
dtolnay/rust-toolchain@stableandswatinem/rust-cache@v2. - Install the frontend dependencies and, if not configured as
beforeBuildCommand, run the web app’s build script. - Lastly, it uses
tauri-apps/tauri-action@v1to runtauri build, generate the artifacts, and create a GitHub release.
name: 'publish'
on:
workflow_dispatch:
push:
branches:
- release
jobs:
publish-tauri:
permissions:
contents: write
strategy:
fail-fast: false
matrix:
include:
- platform: 'macos-latest' # for Arm based macs (M1 and above).
args: '--target aarch64-apple-darwin'
- platform: 'macos-latest' # for Intel based macs.
args: '--target x86_64-apple-darwin'
- platform: 'ubuntu-22.04'
args: ''
- platform: 'ubuntu-22.04-arm' # Only available in public repos.
args: ''
- platform: 'windows-latest'
args: ''
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v7
- name: install dependencies (ubuntu only)
if: matrix.platform == 'ubuntu-22.04' || matrix.platform == 'ubuntu-22.04-arm' # This must match the platform value defined above.
run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf xdg-utils
- name: setup node
uses: actions/setup-node@v6
with:
node-version: lts/*
cache: 'npm' # Set this to npm, yarn or pnpm.
- name: install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
# Those targets are only used on macos runners so it's in an `if` to slightly speed up windows and linux builds.
targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
- name: Rust cache
uses: swatinem/rust-cache@v2
with:
# This matches tauri's default project layout. Change this if you have a different layout.
workspaces: './src-tauri -> target'
- name: install frontend dependencies
# If you don't have `beforeBuildCommand` configured you may want to build your frontend here too.
run: npm install # change this to npm, yarn or pnpm depending on which one you use.
- uses: tauri-apps/tauri-action@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tagName: app-v__VERSION__ # the action automatically replaces __VERSION__ with the app version.
releaseName: 'App v__VERSION__'
releaseBody: 'See the assets to download this version and install.'
releaseDraft: true
prerelease: false
args: ${{ matrix.args }}
For more configuration options, check out the tauri-action repository and its examples.
Caution
Carefully read through the Usage limits, billing, and administration documentation for GitHub Actions.
Arm Runner Compilation
August 2025 Update
Github has released publicly available ubuntu-22.04-arm and ubuntu-24.04-arm runners. You can use these to build your app for Arm64 in public repos with the workflow example above.
This workflow uses pguyot/arm-runner-action to compile directly on an emulated Arm runner. This bridges the gap for missing cross-architecture build support in the AppImage tooling.
Danger
arm-runner-action is much slower than GitHub’s standard runners, so be careful in private repositories where you’re invoiced for build minutes. An uncached build for a fresh create-tauri-app project needs ~1 hour.
name: 'Publish Linux Arm builds'
on:
workflow_dispatch:
push:
branches:
- release
jobs:
build:
runs-on: ubuntu-22.04
strategy:
matrix:
arch: [aarch64, armv7l]
include:
- arch: aarch64
cpu: cortex-a72
base_image: https://dietpi.com/downloads/images/DietPi_RPi5-ARMv8-Bookworm.img.xz
deb: arm64
rpm: aarch64
appimage: aarch64
- arch: armv7l
cpu: cortex-a53
deb: armhfp
rpm: arm
appimage: armhf
base_image: https://dietpi.com/downloads/images/DietPi_RPi-ARMv7-Bookworm.img.xz
steps:
- uses: actions/checkout@v3
- name: Cache rust build artifacts
uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri
cache-on-failure: true
- name: Build app
uses: pguyot/arm-runner-action@v2.6.5
with:
base_image: ${{ matrix.base_image }}
cpu: ${{ matrix.cpu }}
bind_mount_repository: true
image_additional_mb: 10240
optimize_image: no
#exit_on_fail: no
commands: |
# Prevent Rust from complaining about $HOME not matching eid home
export HOME=/root
# Workaround to CI worker being stuck on Updating crates.io index
export CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse
# Install setup prerequisites
apt-get update -y --allow-releaseinfo-change
apt-get autoremove -y
apt-get install -y --no-install-recommends --no-install-suggests curl libwebkit2gtk-4.1-dev build-essential libssl-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev patchelf libfuse2 file
curl https://sh.rustup.rs -sSf | sh -s -- -y
. "$HOME/.cargo/env"
curl -fsSL https://deb.nodesource.com/setup_lts.x | bash
apt-get install -y nodejs
# Install frontend dependencies
npm install
# Build the application
npm run tauri build -- --verbose
- name: Get app version
run: echo "APP_VERSION=$(jq -r .version src-tauri/tauri.conf.json)" >> $GITHUB_ENV
# TODO: Combine this with the basic workflow and upload the files to the Release.
- name: Upload deb bundle
uses: actions/upload-artifact@v3
with:
name: Debian Bundle
path: ${{ github.workspace }}/src-tauri/target/release/bundle/deb/appname_${{ env.APP_VERSION }}_${{ matrix.deb }}.deb
- name: Upload rpm bundle
uses: actions/upload-artifact@v3
with:
name: RPM Bundle
path: ${{ github.workspace }}/src-tauri/target/release/bundle/rpm/appname-${{ env.APP_VERSION }}-1.${{ matrix.rpm }}.rpm
- name: Upload appimage bundle
uses: actions/upload-artifact@v3
with:
name: AppImage Bundle
path: ${{ github.workspace }}/src-tauri/target/release/bundle/appimage/appname_${{ env.APP_VERSION }}_${{ matrix.appimage }}.AppImage
Troubleshooting
GitHub Environment Token
The GitHub Token is automatically issued by GitHub for each workflow run without further configuration, which means there is no risk of secret leakage. This token however only has read permissions by default and you may get a “Resource not accessible by integration” error when running the workflow. If this happens, you may need to add write permissions to this token. To do this, go to your GitHub project settings, select Actions, scroll down to Workflow permissions, and check “Read and write permissions”.
You can see the GitHub Token being passed to the workflow via this line in the workflow:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RPM
Note
Some sections in this guide are optional. This includes configuring scripts and certain other steps. Feel free to adapt the instructions based on your specific needs and requirements.
This guide covers how to distribute and manage RPM packages, including retrieving package information, configuring scripts, setting dependencies, and signing packages.
Note
GUI apps on macOS and Linux do not inherit the $PATH from your shell dotfiles (.bashrc, .bash_profile, .zshrc, etc). Check out Tauri’s fix-path-env-rs crate to fix this issue.
Limitations
Core libraries such as glibc frequently break compatibility with older systems. For this reason, you must build your Tauri application using the oldest base system you intend to support that also provides Tauri v2’s required WebKitGTK 4.1 packages. Ubuntu 22.04 and Debian 12 are suitable baseline examples because they provide libwebkit2gtk-4.1-dev from their standard package repositories. Building on a newer base system can raise the minimum glibc version required by your app, so when running on an older system, you may face a runtime error like /usr/lib/libc.so.6: version 'GLIBC_2.33' not found. We recommend using a Docker container or GitHub Actions to build your Tauri application for Linux.
See the issues tauri-apps/tauri#1355 and rust-lang/rust#57497, in addition to the AppImage guide for more information.
Configuring the RPM package
Tauri allows you to configure the RPM package by adding scripts, setting dependencies, adding a license, including custom files, and more. For detailed information about configurable options, please refer to: RpmConfig.
Add post, pre-install/remove script to the package
The RPM package manager allows you to run scripts before or after the installation or removal of the package. For example, you can use these scripts to start a service after the package is installed.
Here’s an example of how to add these scripts:
- Create a folder named
scriptsin thesrc-tauridirectory in your project.
mkdir src-tauri/scripts
- Create the script files in the folder.
touch src-tauri/scripts/postinstall.sh \
touch src-tauri/scripts/preinstall.sh \
touch src-tauri/scripts/preremove.sh \
touch src-tauri/scripts/postremove.sh
Now if we look inside /src-tauri/scripts we will see:
ls src-tauri/scripts/
postinstall.sh postremove.sh preinstall.sh preremove.sh
- Add some content to the scripts
preinstall.sh
echo "-------------"
echo "This is pre"
echo "Install Value: $1"
echo "Upgrade Value: $1"
echo "Uninstall Value: $1"
echo "-------------"
postinstall.sh
echo "-------------"
echo "This is post"
echo "Install Value: $1"
echo "Upgrade Value: $1"
echo "Uninstall Value: $1"
echo "-------------"
preremove.sh
echo "-------------"
echo "This is preun"
echo "Install Value: $1"
echo "Upgrade Value: $1"
echo "Uninstall Value: $1"
echo "-------------"
postremove.sh
echo "-------------"
echo "This is postun"
echo "Install Value: $1"
echo "Upgrade Value: $1"
echo "Uninstall Value: $1"
echo "-------------"
- Add the scripts to the
tauri.conf.jsonfile
tauri.conf.json
{
"bundle": {
"linux": {
"rpm": {
"epoch": 0,
"files": {},
"release": "1",
// add the script here
"preInstallScript": "/path/to/your/project/src-tauri/scripts/prescript.sh",
"postInstallScript": "/path/to/your/project/src-tauri/scripts/postscript.sh",
"preRemoveScript": "/path/to/your/project/src-tauri/scripts/prescript.sh",
"postRemoveScript": "/path/to/your/project/src-tauri/scripts/postscript.sh"
}
}
}
}
Setting the Conflict, Provides, Depends, Files, Obsoletes, DesktopTemplate, and Epoch
-
conflict: Prevents the installation of the package if it conflicts with another package. For example, if you update an RPM package that your app depends on and the new version is incompatible with your app.
-
provides: Lists the RPM dependencies that your application provides.
-
depends: Lists the RPM dependencies that your application needs to run.
-
files: Specifies which files to include in the package.
-
obsoletes: Lists the RPM dependencies that your application obsoletes.
Note
If this package is installed, packages listed as “obsoletes” will be automatically removed if present.
-
desktopTemplate: Adds a custom desktop file to the package.
-
epoch: Defines weighted dependencies based on version numbers.
Caution
It is not recommended to use epoch unless necessary, as it alters how the package manager compares package versions. For more information about epoch, please check: RPM Packaging Guide.
To use these options, add the following to your tauri.conf.json :
tauri.conf.json
{
"bundle": {
"linux": {
"rpm": {
"postRemoveScript": "/path/to/your/project/src-tauri/scripts/postscript.sh",
"conflicts": ["oldLib.rpm"],
"depends": ["newLib.rpm"],
"obsoletes": ["veryoldLib.rpm"],
"provides": ["coolLib.rpm"],
"desktopTemplate": "/path/to/your/project/src-tauri/desktop-template.desktop"
}
}
}
}
Add a license to the package
To add a license to the package, add the following to the src-tauri/cargo.toml or in the src-tauri/tauri.conf.json file:
src-tauri/cargo.toml
[package]
name = "tauri-app"
version = "0.0.0"
description = "A Tauri App"
authors = ["you"]
edition = "2021"
license = "MIT" # add the license here
# ... rest of the file
And for src-tauri/tauri.conf.json
src-tauri/tauri.conf.json
{
"bundle": {
"licenseFile": "../LICENSE", // put the path to the license file here
"license": "MIT" // add the license here
}
}
Building the RPM package
To build the RPM package, you can use the following command:
-
npm
npm run tauri build -
yarn
yarn tauri build -
pnpm
pnpm tauri build -
deno
deno task tauri build -
bun
bun tauri build -
cargo
cargo tauri build
This command will build the RPM package in the src-tauri/target/release/bundle/rpm directory.
Signing the RPM package
Tauri allows you to sign the package with the key you have in your system during the build process. To do this, you will need to generate a GPG key.
Generate a GPG key
To generate a GPG key you can use the following command:
gpg --gen-key
Follow the instruction to generate the key.
Once the key is generated, you will need to add it to your environment variable. You can do this by adding the following to your .bashrc or .zshrc file or just export it in the terminal:
export TAURI_SIGNING_RPM_KEY=$(cat /home/johndoe/my_super_private.key)
If you have a passphrase for the key, you can add it to the environment variable:
export TAURI_SIGNING_RPM_KEY_PASSPHRASE=password
Now you can build the package with the following command:
-
npm
npm run tauri build -
yarn
yarn tauri build -
pnpm
pnpm tauri build -
deno
deno task tauri build -
bun
bun tauri build -
cargo
cargo tauri build
Verify the signature
Note
This should be done only to test the signature locally.
Before verifying the signature, you will need to create and import the public key to the RPM database:
gpg --export -a 'Tauri-App' > RPM-GPG-KEY-Tauri-App
sudo rpm --import RPM-GPG-KEY-Tauri-App
Now that the key is imported, we have to edit the ~/.rpmmacros file to utilize the key.
~/.rpmmacros
%_signature gpg
%_gpg_path /home/johndoe/.gnupg
%_gpg_name Tauri-App
%_gpgbin /usr/bin/gpg2
%__gpg_sign_cmd %{__gpg} \
gpg --force-v3-sigs --digest-algo=sha1 --batch --no-verbose --no-armor \
--passphrase-fd 3 --no-secmem-warning -u "%{_gpg_name}" \
-sbo %{__signature_filename} %{__plaintext_filename}
Finally, you can verify the package using the following command:
rpm -v --checksig tauri-app-0.0.0-1.x86_64.rpm
Debugging the RPM package
In this section, we will see how to debug the RPM package by checking the content of the package and getting information about the package.
Getting information about the package
To get information about your package, such as the version, release, and architecture, use the following command:
rpm -qip package_name.rpm
Query specific information about the package
For example, if you want to get the name, version, release, architecture, and size of the package, use the following command:
rpm -qp --queryformat '[%{NAME} %{VERSION} %{RELEASE} %{ARCH} %{SIZE}\n]' package_name.rpm
Note
--queryformat is a format string that can be used to get specific information about the package. The information that can be retrieved is from the rpm -qip command.
Checking the content of the package
To check the content of the package, use the following command:
rpm -qlp package_name.rpm
This command will list all the files that are included in the package.
Debugging scripts
To debug post/pre-install/remove scripts, use the following command:
rpm -qp --scripts package_name.rpm
This command will print the content of the scripts.
Checking dependencies
To check the dependencies of the package, use the following command:
rpm -qp --requires package_name.rpm
List packages that depend on a specific package
To list the packages that depend on a specific package, use the following command:
rpm -q --whatrequires package_name.rpm
Debugging Installation Issues
If you encounter issues during the installation of an RPM package, you can use the -vv (very verbose) option to get detailed output:
rpm -ivvh package_name.rpm
Or for an already installed package:
rpm -Uvvh package_name.rpm
Cross-Compiling for ARM-based Devices
This guide covers manual compilation. Check out our GitHub Action guide for an example workflow that leverages QEMU to build the app. This will be much slower but will also be able to build AppImages.
Manual compilation is suitable when you don’t need to compile your application frequently and prefer a one-time setup. The following steps expect you to use a Linux distribution based on Debian/Ubuntu.
-
Install Rust targets for your desired architecture
- For ARMv7 (32-bit):
rustup target add armv7-unknown-linux-gnueabihf - For ARMv8 (ARM64, 64-bit):
rustup target add aarch64-unknown-linux-gnu
- For ARMv7 (32-bit):
-
Install the corresponding linker for your chosen architecture
- For ARMv7:
sudo apt install gcc-arm-linux-gnueabihf - For ARMv8 (ARM64):
sudo apt install gcc-aarch64-linux-gnu
- For ARMv7:
-
Open or create the file
<project-root>/.cargo/config.tomland add the following configurations accordingly[target.armv7-unknown-linux-gnueabihf] linker = "arm-linux-gnueabihf-gcc" [target.aarch64-unknown-linux-gnu] linker = "aarch64-linux-gnu-gcc" -
Enable the respective architecture in the package manager
- For ARMv7:
sudo dpkg --add-architecture armhf - For ARMv8 (ARM64):
sudo dpkg --add-architecture arm64
- For ARMv7:
-
Adjusting Package Sources
On Debian, this step should not be necessary, but on other distributions, you might need to edit /etc/apt/sources.list to include the ARM architecture variant. For example on Ubuntu 22.04 add these lines to the bottom of the file (Remember to replace jammy with the codename of your Ubuntu version):
deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy main restricted deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates main restricted deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy universe deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates universe deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy multiverse deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates multiverse deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-backports main restricted universe multiverse deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security main restricted deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security universe deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security multiverseThen, to prevent issues with the main packages, you have to add the correct main architecture to all other lines the file contained beforehand. For standard 64-bit systems you need to add [arch=amd64], the full file on Ubuntu 22.04 then looks similar to this:
Show solution
# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to # newer versions of the distribution. deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy main restricted # deb-src http://archive.ubuntu.com/ubuntu/ jammy main restricted ## Major bug fix updates produced after the final release of the ## distribution. deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy-updates main restricted # deb-src http://archive.ubuntu.com/ubuntu/ jammy-updates main restricted ## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu ## team. Also, please note that software in universe WILL NOT receive any ## review or updates from the Ubuntu security team. deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy universe # deb-src http://archive.ubuntu.com/ubuntu/ jammy universe deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy-updates universe # deb-src http://archive.ubuntu.com/ubuntu/ jammy-updates universe ## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu ## team, and may not be under a free licence. Please satisfy yourself as to ## your rights to use the software. Also, please note that software in ## multiverse WILL NOT receive any review or updates from the Ubuntu ## security team. deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy multiverse # deb-src http://archive.ubuntu.com/ubuntu/ jammy multiverse deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy-updates multiverse ## N.B. software from this repository may not have been tested as ## extensively as that contained in the main release, although it includes ## newer versions of some applications which may provide useful features. ## Also, please note that software in backports WILL NOT receive any review ## or updates from the Ubuntu security team. deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy-backports main restricted universe multiverse # deb-src http://archive.ubuntu.com/ubuntu/ jammy-backports main restricted universe multiverse deb [arch=amd64] http://security.ubuntu.com/ubuntu/ jammy-security main restricted # deb-src http://security.ubuntu.com/ubuntu/ jammy-security main restricted deb [arch=amd64] http://security.ubuntu.com/ubuntu/ jammy-security universe # deb-src http://security.ubuntu.com/ubuntu/ jammy-security universe deb [arch=amd64] http://security.ubuntu.com/ubuntu/ jammy-security multiverse # deb-src http://security.ubuntu.com/ubuntu/ jammy-security multiverse deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy main restricted deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates main restricted deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy universe deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates universe deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy multiverse deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates multiverse deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-backports main restricted universe multiverse deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security main restricted deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security universe deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security multiverse -
Update the package information:
sudo apt-get update && sudo apt-get upgrade -y -
Install the required webkitgtk library for your chosen architecture
- For ARMv7:
sudo apt install libwebkit2gtk-4.1-dev:armhf - For ARMv8 (ARM64):
sudo apt install libwebkit2gtk-4.1-dev:arm64
- For ARMv7:
-
Install OpenSSL or use a vendored version
This is not always required so you may want to proceed first and check if you see errors like
Failed to find OpenSSL development headers.-
Either install the development headers system-wide:
- For ARMv7:
sudo apt install libssl-dev:armhf - For ARMv8 (ARM64):
sudo apt install libssl-dev:arm64
- For ARMv7:
-
Or enable the vendor feature for the OpenSSL Rust crate which will affect all other Rust dependencies using the same minor version. You can do so by adding this to the dependencies section in your
Cargo.tomlfile:
openssl-sys = {version = "0.9", features = ["vendored"]} -
-
Set the
PKG_CONFIG_SYSROOT_DIRto the appropriate directory based on your chosen architecture- For ARMv7:
export PKG_CONFIG_SYSROOT_DIR=/usr/arm-linux-gnueabihf/ - For ARMv8 (ARM64):
export PKG_CONFIG_SYSROOT_DIR=/usr/aarch64-linux-gnu/
- For ARMv7:
-
Build the app for your desired ARM version
- For ARMv7: cargo tauri build –target armv7-unknown-linux-gnueabihf
- For ARMv8 (ARM64): cargo tauri build –target aarch64-unknown-linux-gnu
Choose the appropriate set of instructions based on whether you want to cross-compile your Tauri application for ARMv7 or ARMv8 (ARM64). Please note that the specific steps may vary depending on your Linux distribution and setup.
Android Code Signing
To publish on the Play Store, you need to sign your app with a digital certificate.
Android App Bundles and APKs must be signed before being uploaded for distribution.
Google also provides an additional signing mechanism for Android App Bundles distributed in the Play Store. See the official Play App Signing documentation for more information.
Creating a keystore and upload key
Android signing requires a Java Keystore file that can be generated using the official keytool CLI:
-
macOS/Linux
keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload -
Windows
keytool -genkey -v -keystore $env:USERPROFILE\upload-keystore.jks -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 -alias upload
This command stores the upload-keystore.jks file in your home directory. If you want to store it elsewhere, change the argument you pass to the -keystore parameter.
Tip
- The
keytoolcommand might not be in your PATH. You may find it installed in the JDK that is installed with Android Studio:
-
Linux
/opt/android-studio/jbr/bin/keytool ...argsAndroid Studio directory path depends on your Linux distribution
-
macOS
/Applications/Android\ Studio.app/Contents/jbr/Contents/Home/bin/keytool ...args -
Windows
C:\\Program Files\\Android\\Android Studio\\jbr\\bin\\keytool.exe ...args
Security Warning
Keep the keystore file private; don’t check it into public source control!
See the official documentation for more information.
Configure the signing key
Create a file named [project]/src-tauri/gen/android/keystore.properties that contains a reference to your keystore:
password=<password defined when keytool was executed>
keyAlias=upload
storeFile=<location of the key store file, such as /Users/<user name>/upload-keystore.jks or C:\\Users\\<user name>\\upload-keystore.jks>
Security Warning
Keep the keystore.properties file private; don’t check it into public source control.
You will usually generate this file in your CI/CD platform. The following snippet contains an example job step for GitHub Actions:
- name: setup Android signing
run: |
cd src-tauri/gen/android
echo "keyAlias=${{ secrets.ANDROID_KEY_ALIAS }}" > keystore.properties
echo "password=${{ secrets.ANDROID_KEY_PASSWORD }}" >> keystore.properties
base64 -d <<< "${{ secrets.ANDROID_KEY_BASE64 }}" > $RUNNER_TEMP/keystore.jks
echo "storeFile=$RUNNER_TEMP/keystore.jks" >> keystore.properties
In this example the keystore was exported to base64 with base64 -i /path/to/keystore.jks and set as the ANDROID_KEY_BASE64 secret.
Configure Gradle to use the signing key
Configure gradle to use your upload key when building your app in release mode by editing the [project]/src-tauri/gen/android/app/build.gradle.kts file.
Tip
There are multiple different build.gradle.kts files in a typical Android project. If there is no buildTypes block you’re looking at the wrong file. The one you need is in the app/ directory relative to the keystore file from the prior step.
Click here for a screenshot showing its location in a typical file tree.
-
Add the needed import at the beginning of the file:
import java.io.FileInputStream -
Add the
releasesigning config before thebuildTypesblock:signingConfigs { create("release") { val keystorePropertiesFile = rootProject.file("keystore.properties") val keystoreProperties = Properties() if (keystorePropertiesFile.exists()) { keystoreProperties.load(FileInputStream(keystorePropertiesFile)) } keyAlias = keystoreProperties["keyAlias"] as String keyPassword = keystoreProperties["password"] as String storeFile = file(keystoreProperties["storeFile"] as String) storePassword = keystoreProperties["password"] as String } } buildTypes { ... } -
Use the new
releasesigning config in thereleaseconfig inbuildTypesblock:buildTypes { getByName("release") { signingConfig = signingConfigs.getByName("release") } }
Release builds of your app will now be signed automatically.
iOS Code Signing
Code signing on iOS is required to distribute your application through the official Apple App Store or possibly alternative marketplaces in the European Union and in general to install and execute on end user devices.
Prerequisites
Code signing on iOS requires enrolling to the Apple Developer program, which at the time of writing costs 99$ per year. You also need an Apple device where you perform the code signing. This is required by the signing process and due to Apple’s Terms and Conditions.
To distribute iOS applications you must have your bundle identifier registered in the App Store Connect, an appropriate iOS code signing certificate and a mobile provisioning profile that links them together and enables the iOS capabilities used by your app. These requirements can be either automatically managed by Xcode or provided manually.
Automatic Signing
Letting Xcode manage the signing and provisioning for your app is the most convenient way to export your iOS app to be distributed. It automatically registers your bundle identifier, manages iOS capabilities changes, and configures an appropriate certificate based on your export method.
Automatic signing is enabled by default, and uses the account configured in Xcode to authenticate when used on your local machine.
To register your account, open the Xcode application and open the Settings page in the Xcode > Settings menu, switch to the Accounts tab and click the + icon.
To use the automatic signing in CI/CD platforms you must create an App Store Connect API key and define the APPLE_API_ISSUER, APPLE_API_KEY and APPLE_API_KEY_PATH environment variables.
Open the App Store Connect’s Users and Access page, select the Integrations tab, click on the Add button and select a name and the Admin access. The APPLE_API_ISSUER (Issuer ID) is presented above the keys table, and the APPLE_API_KEY is the value on the Key ID column on that table. You also need to download the private key, which can only be done once and is only visible after a page reload (the button is shown on the table row for the newly created key). The private key file path must be set via the APPLE_API_KEY_PATH environment variable.
Manual Signing
To manually sign your iOS app you can provide the certificate and mobile provisioning profile via environment variables:
- IOS_CERTIFICATE: base64 representation of the certificate exported from the Keychain.
- IOS_CERTIFICATE_PASSWORD: password of the certificate set when exporting it from the Keychain.
- IOS_MOBILE_PROVISION: base64 representation of the provisioning profile.
The following sections explain how to get these values.
Signing Certificate
After enrolling, navigate to the Certificates page to create a new Apple Distribution certificate. Download the new certificate and install it to the macOS Keychain.
To export the certificate key, open the “Keychain Access” app, expand the certificate’s entry, right-click on the key item and select “Export <key-name>” item. Select the path of the exported .p12 file and remember its password.
Run the following base64 command to convert the certificate to base64 and copy it to the clipboard:
base64 -i <path-to-certificate.p12> | pbcopy
The value in the clipboard is now the base64 representation of the signing certificate. Save it and use it as the IOS_CERTIFICATE environment variable value.
The certificate password must be set to the IOS_CERTIFICATE_PASSWORD variable.
Choose Certificate Type
You must use an appropriate certificate type for each export method:
- debugging: Apple Development or iOS App Development
- app-store-connect: Apple Distribution or iOS Distribution (App Store Connect and Ad Hoc)
- ad-hoc: Apple Distribution or iOS Distribution (App Store Connect and Ad Hoc)
Provisioning Profile
Additionally, you must provide the provisioning profile for your application. In the Identifiers page, create a new App ID and make sure its “Bundle ID” value matches the identifier set in the identifier configuration.
Navigate to the Profiles page to create a new provisioning profile. For App Store distribution, it must be an “App Store Connect” profile. Select the appropriate App ID and link the certificate you previously created.
After creating the provisioning profile, download it and run the following base64 command to convert the profile and copy it to the clipboard:
base64 -i <path-to-profile.mobileprovision> | pbcopy
The value in the clipboard is now the base64 representation of the provisioning profile. Save it and use it as the IOS_MOBILE_PROVISION environment variable value.
Now you can build your iOS application and distribute on the App Store!
Linux Code Signing
This guide provides information on code signing for Linux packages. While artifact signing is not required for your application to be deployed on Linux, it can be used to increase trust into your deployed application. Signing the binaries allows your end user to verify that these are genuine and have not been modified by another untrusted entity.
Signing for AppImages
The AppImage can be signed using either gpg or gpg2.
Prerequisites
A key for signing must be prepared. A new one can be generated using:
gpg2 --full-gen-key
Please refer to the gpg or gpg2 documentation for additional information. You should take additional care to back up your private and public keys in a secure location.
Signing
You can embed a signature in the AppImage by setting the following environment variables:
- SIGN: set to
1to sign the AppImage. - SIGN_KEY: optional variable to use a specific GPG Key ID for signing.
- APPIMAGETOOL_SIGN_PASSPHRASE: the signing key password. If unset, gpg shows a dialog so you can input it. You must set this when building in CI/CD platforms.
- APPIMAGETOOL_FORCE_SIGN: by default the AppImage is generated even if signing fails. To exit on errors, you can set this variable to
1.
You can display the signature embedded in the AppImage by running the following command:
./src-tauri/target/release/bundle/appimage/$APPNAME_$VERSION_amd64.AppImage --appimage-signature
Note that you need to change the $APPNAME and $VERSION values with the correct ones based on your configuration.
Caution
The signature is not verified
AppImage does not validate the signature, so you can’t rely on it to check whether the file has been tampered with or not. The user must manually verify the signature using the AppImage validate tool. This requires you to publish your key ID on an authenticated channel (e.g. your website served via TLS), so the end user can view and verify.
See the official AppImage documentation for additional information.
Validate the signature
The AppImage validate tool can be downloaded from here. Select one of the validate-$PLATFORM.AppImage files.
Run the following command to validate the signature:
chmod +x validate-$PLATFORM.AppImage
./validate-$PLATFORM.AppImage $TAURI_OUTPUT.AppImage
If the signature is valid, the output will be:
Validation result: validation successful
Signatures found with key fingerprints: $KEY_ID
====================
Validator report:
Signature checked for key with fingerprint $KEY_ID:
Validation successful
macOS Code Signing
Code signing is required on macOS to allow your application to be listed in the Apple App Store and to prevent a warning that your application is broken and can not be started, when downloaded from the browser.
Prerequisites
Code signing on macOS requires an Apple Developer account which is either paid (99$ per year) or on the free plan (only for testing and development purposes). You also need an Apple device where you perform the code signing. This is required by the signing process and due to Apple’s Terms and Conditions.
Note
Note when using a free Apple Developer account, you will not be able to notarize your application and it will still show up as not verified when opening the app.
Signing
To setup code signing for macOS you must create an Apple code signing certificate and install it to your Mac computer keychain or export it to be used in CI/CD platforms.
Creating a signing certificate
To create a new signing certificate, you must generate a Certificate Signing Request (CSR) file from your Mac computer. See creating a certificate signing request to learn how to create the CSR for code signing.
On your Apple Developer account, navigate to the Certificates, IDs & Profiles page and click on the Create a certificate button to open the interface to create a new certificate. Choose the appropriate certificate type (Apple Distribution to submit apps to the App Store, and Developer ID Application to ship apps outside the App Store). Upload your CSR, and the certificate will be created.
Note
Only the Apple Developer Account Holder can create Developer ID Application certificates. But it can be associated with a different Apple ID by creating a CSR with a different user email address.
Downloading the certificate
On the Certificates, IDs & Profiles page, click on the certificate you want to use and click on the Download button. It saves a .cer file that installs the certificate on the keychain once opened.
Configuring Tauri
You can configure Tauri to use your certificate when building macOS apps on your local machine or when using CI/CD platforms.
Signing locally
With the certificate installed in your Mac computer keychain, you can configure Tauri to use it for code signing.
The name of the certificate’s keychain entry represents the signing identity, which can also be found by executing:
security find-identity -v -p codesigning
This identity can be provided in the tauri.conf.json > bundle > macOS > signingIdentity configuration option or via the APPLE_SIGNING_IDENTITY environment variable.
Note
A signing certificate is only valid if associated with your Apple ID. An invalid certificate won’t be listed on the Keychain Access > My Certificates tab or the security find-identity -v -p codesigning output. If the certificate does not download to the correct location, make sure the “login” option is selected in Keychain Access under “Default Keychains” when downloading the .cer file.
Signing in CI/CD platforms
To use the certificate in CI/CD platforms, you must export the certificate to a base64 string and configure the APPLE_CERTIFICATE and APPLE_CERTIFICATE_PASSWORD environment variables:
- Open the
Keychain Accessapp, click the My Certificates tab in the login keychain and find your certificate’s entry. - Expand the entry, right-click on the key item, and select
Export "$KEYNAME". - Select the path to save the certificate’s
.p12file and define a password for the exported certificate. - Convert the
.p12file to base64 running the following script on the terminal:
openssl base64 -A -in /path/to/certificate.p12 -out certificate-base64.txt
- Set the contents of the
certificate-base64.txtfile to theAPPLE_CERTIFICATEenvironment variable. - Set the certificate password to the
APPLE_CERTIFICATE_PASSWORDenvironment variable.
Example GitHub Actions configuration
Required secrets:
APPLE_ID- Your Apple ID emailAPPLE_PASSWORD- Your Apple ID passwordAPPLE_CERTIFICATE- The base64 encoded.p12fileAPPLE_CERTIFICATE_PASSWORD- The password for your exported.p12fileKEYCHAIN_PASSWORD- The password for your keychain
Check out the official GitHub guide to learn how to set up secrets.
name: 'build'
on:
push:
branches:
- main
jobs:
build-macos:
needs: prepare
strategy:
matrix:
include:
- args: '--target aarch64-apple-darwin'
arch: 'silicon'
- args: '--target x86_64-apple-darwin'
arch: 'intel'
runs-on: macos-latest
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
steps:
- name: Import Apple Developer Certificate
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
echo $APPLE_CERTIFICATE | base64 --decode > certificate.p12
security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security set-keychain-settings -t 3600 -u build.keychain
security import certificate.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain
security find-identity -v -p codesigning build.keychain
- name: Verify Certificate
run: |
CERT_INFO=$(security find-identity -v -p codesigning build.keychain | grep "Apple Development")
CERT_ID=$(echo "$CERT_INFO" | awk -F'"' '{print $2}')
echo "CERT_ID=$CERT_ID" >> $GITHUB_ENV
echo "Certificate imported."
- uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ env.CERT_ID }}
with:
args: ${{ matrix.args }}
Notarization
To notarize your application, you must provide credentials for Tauri to authenticate with Apple. This can be done via the App Store Connect API, or via your Apple ID.
-
App Store Connect
- Open the App Store Connect’s Users and Access page, select the Integrations tab, click on the Add button and select a name and the Developer access.
- Set the
APPLE_API_ISSUERenvironment variable to the value presented above the keys table. - Set the
APPLE_API_KEYenvironment variable to the value on the Key ID column on that table. - Download the private key, which can only be done once and is only visible after a page reload (the button is shown on the table row for the newly created key).
- Set the
APPLE_API_KEY_PATHenvironment variable to the file path of the downloaded private key.
-
Apple ID
- Set the
APPLE_IDenvironment variable to your Apple account email. - Set the
APPLE_PASSWORDenvironment variable to an app-specific password for your Apple account. - Set the
APPLE_TEAM_IDenvironment variable to your Apple Team ID. You can find your Team ID in your account’s membership page.
- Set the
After setting these environment variables, rerun your Tauri build or bundle command. For example, to build a DMG with pnpm, run pnpm tauri build --bundles dmg again. If you need to skip stapling for an initial notarization pass, append --skip-stapling directly to the Tauri command, such as pnpm tauri build --bundles dmg --skip-stapling.
Note
Notarization is required when using a Developer ID Application certificate.
Ad-Hoc Signing
If you do not wish to provide an Apple-authenticated identity, but still wish to sign your application, you can configure an ad-hoc signature.
This is useful on ARM (Apple Silicon) devices, where code-signing is required for all apps from the Internet.
Caution
Ad-hoc code signing does not prevent MacOS from requiring users to whitelist the installation in their Privacy & Security settings.
To configure an ad-hoc signature, provide the pseudo-identity - to Tauri, e.g.
"signingIdentity": "-"
For details on configuring Tauri’s signing identity, see above.
Windows Code Signing
Code signing is required on Windows to allow your application to be listed in the Microsoft Store and to prevent a SmartScreen warning that your application is not trusted and can not be started, when downloaded from the browser.
It is not required to execute your application on Windows, as long as your end user is okay with ignoring the SmartScreen warning or your user does not download via the browser. This guide covers signing via OV (Organization Validated) certificates and Azure Key Vault. If you use any other signing mechanism not documented here, such as EV (Extended Validation) certificates, check out your certificate issuer documentation and refer to the custom sign command section.
OV Certificates
Danger
This guide only applies to OV code signing certificates acquired before June 1st 2023! For code signing with EV certificates and OV certificates received after that date please consult the documentation of your certificate issuer instead.
Note
If you sign the app with an EV Certificate, it’ll receive an immediate reputation with Microsoft SmartScreen and won’t show any warnings to users.
If you opt for an OV Certificate, which is generally cheaper and available to individuals, Microsoft SmartScreen will still show a warning to users when they download the app. It might take some time until your certificate builds enough reputation. You may opt for submitting your app to Microsoft for manual review. Although not guaranteed, if the app does not contain any malicious code, Microsoft may grant additional reputation and potentially remove the warning for that specific uploaded file.
See the comparison to learn more about OV vs EV certificates.
Prerequisites
- Windows - you can likely use other platforms, but this tutorial uses Powershell native features.
- A working Tauri application
- Code signing certificate - you can acquire one of these on services listed in Microsoft’s docs. There are likely additional authorities for non-EV certificates than included in that list, please compare them yourself and choose one at your own risk.
- Please make sure to get a code signing certificate, SSL certificates do not work!
Getting Started
There are a few things we have to do to get Windows prepared for code signing. This includes converting our certificate to a specific format, installing this certificate, and decoding the required information from the certificate.
-
Convert your
.certo.pfx-
You will need the following:
- certificate file (mine is
cert.cer) - private key file (mine is
private-key.key)
- certificate file (mine is
-
Open up a command prompt and change to your current directory using
cd Documents/Certs -
Convert your
.certo a.pfxusingopenssl pkcs12 -export -in cert.cer -inkey private-key.key -out certificate.pfx -
You should be prompted to enter an export password DON’T FORGET IT!
-
-
Import your
.pfxfile into the keystore.-
We now need to import our
.pfxfile. -
Assign your export password to a variable using
$WINDOWS_PFX_PASSWORD = 'MYPASSWORD' -
Now Import the certificate using
Import-PfxCertificate -FilePath certificate.pfx -CertStoreLocation Cert:\CurrentUser\My -Password (ConvertTo-SecureString -String $WINDOWS_PFX_PASSWORD -Force -AsPlainText)
-
-
Prepare Variables
-
Start ➡️
certmgr.mscto open Personal Certificate Management, then open Personal/Certificates. -
Find the certificate we just imported and double-click on it, then click on the Details tab.
-
The Signature hash algorithm will be our
digestAlgorithm. (Hint: this is likelysha256) -
Scroll down to Thumbprint. There should be a value like
A1B1A2B2A3B3A4B4A5B5A6B6A7B7A8B8A9B9A0B0. This is ourcertificateThumbprint. -
We also need a timestamp URL; this is a time server used to verify the time of the certificate signing. I’m using
http://timestamp.comodoca.com, but whoever you got your certificate from likely has one as well.
-
Prepare tauri.conf.json file
-
Now that we have our
certificateThumbprint,digestAlgorithm, ×tampUrlwe will open up thetauri.conf.json. -
In the
tauri.conf.jsonyou will look for thetauri->bundle->windowssection. There are three variables for the information we have captured. Fill it out like below.
"windows": {
"certificateThumbprint": "A1B1A2B2A3B3A4B4A5B5A6B6A7B7A8B8A9B9A0B0",
"digestAlgorithm": "sha256",
"timestampUrl": "http://timestamp.comodoca.com"
}
-
Save and run
tauri build -
In the console output, you should see the following output.
info: signing app
info: running signtool "C:\\Program Files (x86)\\Windows Kits\\10\\bin\\10.0.19041.0\\x64\\signtool.exe"
info: "Done Adding Additional Store\r\nSuccessfully signed: APPLICATION FILE PATH HERE
Which shows you have successfully signed the .exe.
And that’s it! You have successfully set up your Tauri application for Windows signing.
Sign your application with GitHub Actions.
We can also create a workflow to sign the application with GitHub actions.
GitHub Secrets
We need to add a few GitHub secrets for the proper configuration of the GitHub Action. These can be named however you would like.
- You can view the encrypted secrets guide on how to add GitHub secrets.
The secrets we used are as follows
| GitHub Secrets | Value for Variable |
|---|---|
| WINDOWS_CERTIFICATE | Base64 encoded version of your .pfx certificate, can be done using this command certutil -encode certificate.pfx base64cert.txt |
| WINDOWS_CERTIFICATE_PASSWORD | Certificate export password used on creation of certificate .pfx |
Workflow Modifications
-
We need to add a step in the workflow to import the certificate into the Windows environment. This workflow accomplishes the following
- Assign GitHub secrets to environment variables
- Create a new
certificatedirectory - Import
WINDOWS_CERTIFICATEinto tempCert.txt - Use
certutilto decode the tempCert.txt from base64 into a.pfxfile. - Remove tempCert.txt
- Import the
.pfxfile into the Cert store of Windows & convert theWINDOWS_CERTIFICATE_PASSWORDto a secure string to be used in the import command.
-
We will be using the
tauri-actionpublish template.
name: 'publish'
on:
push:
branches:
- release
jobs:
publish-tauri:
strategy:
fail-fast: false
matrix:
platform: [macos-latest, ubuntu-latest, windows-latest]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v2
- name: setup node
uses: actions/setup-node@v1
with:
node-version: 12
- name: install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: install webkit2gtk (ubuntu only)
if: matrix.platform == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y webkit2gtk-4.0
- name: install app dependencies and build it
run: yarn && yarn build
- uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tagName: app-v__VERSION__ # the action automatically replaces \_\_VERSION\_\_ with the app version
releaseName: 'App v__VERSION__'
releaseBody: 'See the assets to download this version and install.'
releaseDraft: true
prerelease: false
- Right above
-name: install app dependencies and build ityou will want to add the following step
- name: import windows certificate
if: matrix.platform == 'windows-latest'
env:
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}
run: |
New-Item -ItemType directory -Path certificate
Set-Content -Path certificate/tempCert.txt -Value $env:WINDOWS_CERTIFICATE
certutil -decode certificate/tempCert.txt certificate/certificate.pfx
Remove-Item -path certificate -include tempCert.txt
Import-PfxCertificate -FilePath certificate/certificate.pfx -CertStoreLocation Cert:\CurrentUser\My -Password (ConvertTo-SecureString -String $env:WINDOWS_CERTIFICATE_PASSWORD -Force -AsPlainText)
-
Save and push to your repo.
-
Your workflow can now import your windows certificate and import it into the GitHub runner, allowing for automated code signing!
Azure Key Vault
You can sign the Windows executables by providing an Azure Key Vault certificate and credentials.
Note
This guide uses relic due to its support to secret-based authentication, though you can configure alternative tools if you prefer. To download relic, check its releases page or run go install github.com/sassoftware/relic/v8@latest.
- Key Vault
In the Azure Portal navigate to the Key vaults service to create a new key vault by clicking the “Create” button. Remember the “Key vault name” as you will need that information to configure the certificate URL.
- Certificate
After creating a key vault, select it and go to the “Objects > Certificates” page to create a new certificate and click the “Generate/Import” button. Remember the “Certificate name” as you will need that information to configure the certificate URL.
- Tauri Configuration
relic uses a configuration file to determine which signing key it should use. For Azure Key Vault you also need the certificate URL. Create a relic.conf file in the src-tauri folder and configure relic to use your certificate:
src-tauri/relic.conf
tokens:
azure:
type: azure
keys:
azure:
token: azure
id: https://\<KEY_VAULT_NAME\>.vault.azure.net/certificates/\<CERTIFICATE_NAME\>
Note that you must replace <KEY_VAULT_NAME> and <CERTIFICATE_NAME> with the appropriate names from the previous steps.
To configure Tauri to use your Azure Key Vault configuration for signing change the bundle > windows > signCommand config value:
tauri.conf.json
{
"bundle": {
"windows": {
"signCommand": "relic sign --file %1 --key azure --config relic.conf"
}
}
}
- Credentials
relic must authenticate with Azure in order to load the certificate. In the Azure portal landing page, go to the “Microsoft Entra ID” service and head to the “Manage > App registrations” page. Click “New registration” to create a new app. After creating the app, you are redirected to the application details page where you can see the “Application (client) ID” and “Directory (tenant) ID” values. Set these IDs to the AZURE_CLIENT_ID and AZURE_TENANT_ID environment variables respectively.
In the “Manage > Certificates & secrets” page click the “New client secret” button and set the text in the “Value” column as the AZURE_CLIENT_SECRET environment variable.
After setting up all the credentials, head back to your key vault’s page and navigate to the “Access control (IAM)” page. You must assign the “Key Vault Certificate User” and “Key Vault Crypto User” roles to your newly created application.
After setting up all these variables, running tauri build will produce signed Windows installers!
Custom Sign Command
In the Azure Key Vault documentation above we used a powerful Tauri Windows signing configuration to force the Tauri CLI to use a special shell command to sign Windows installer executables. The bundle > windows > signCommand configuration option can be used to use any codesign tool that can sign Windows executables.
Tip
When cross compiling Windows installers from Linux and macOS machines, you must use a custom sign command as the default implementation only works on Windows machines.
Azure Artifact Signing
You can sign the Windows executables by providing an Azure Artifact Signing (previously called Azure Code Signing/Azure Trusted Signing) certificate and credentials. If you don’t have an Azure Artifact signing Account yet you can follow this tutorial.
Prerequisites
If you want to sign with Github Actions everything should be installed.
- Artifact Signing Account and permissions configured
- .NET (.NET 8 recommended)
- Azure CLI
- Signtool (Windows 11 SDK 10.0.26100.0 or later recommended)
Getting Started
You need to install artifact-signing-cli and configure your environment variables.
-
Install artifact-signing-cli
cargo install artifact-signing-cli
-
Configure environment variables
-
artifact-signing-cli needs the following environment variables to be set, don’t forget to add these as Github Actions secrets:
AZURE_CLIENT_ID: The client ID of your App RegistrationAZURE_CLIENT_SECRET: The client secret of App RegistrationAZURE_TENANT_ID: The tenant ID of your Azure directory, you can also get this from your App Registration
-
-
Modify your
tauri.conf.jsonfile-
You can modify your
tauri.conf.jsonor you can create a specific config file for Windows. Replace the URL and the certificate name with your own values.- -e: The endpoint of your Azure Artifact Signing account
- -a: The name of your Azure Artifact Signing Account
- -c: The name of your Certificate profile inside your Azure Artifact Signing Account
- -d: The description of the signed content (optional). When signing a .msi installer, this description will appear as the installer’s name in the UAC prompt or will be a random string of characters if unset.
tauri.conf.json
{ "bundle": { "windows": { "signCommand": "artifact-signing-cli -e https://wus2.codesigning.azure.net -a MyAccount -c MyProfile -d MyApp %1" } } } -
Snapcraft
Prerequisites
1. Install snap
-
Debian
sudo apt install snapd -
Arch
sudo pacman -S --needed git base-devel git clone https://aur.archlinux.org/snapd.git cd snapd makepkg -si sudo systemctl enable --now snapd.socket sudo systemctl start snapd.socket sudo systemctl enable --now snapd.apparmor.service -
Fedora
sudo dnf install snapd # Enable classic snap support sudo ln -s /var/lib/snapd/snap /snapReboot your system afterwards.
2. Install a base snap
sudo snap install core22
3. Install snapcraft
sudo snap install snapcraft --classic
Configuration
- Create an UbuntuOne account.
- Go to the Snapcraft website and register an App name.
- Create a snapcraft.yaml file in your projects root.
- Adjust the names in the snapcraft.yaml file.
name: appname
base: core22
version: '0.1.0'
summary: Your summary # 79 char long summary
description: |
Your description
grade: stable
confinement: strict
layout:
/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/webkit2gtk-4.1:
bind: $SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/webkit2gtk-4.1
apps:
appname:
command: usr/bin/appname
desktop: usr/share/applications/appname.desktop
extensions: [gnome]
#plugs:
# - network
# Add whatever plugs you need here, see https://snapcraft.io/docs/snapcraft-interfaces for more info.
# The gnome extension already includes [ desktop, desktop-legacy, gsettings, opengl, wayland, x11, mount-observe, calendar-service ]
# - single-instance-plug # add this if you're using the single-instance plugin
#slots:
# Add the slots you need to expose to other snaps
# - single-instance-plug # add this if you're using the single-instance plugin
# Add these lines only if you're using the single-instance plugin
# Check https://v2.tauri.app/plugin/single-instance/ for details
#slots:
# single-instance:
# interface: dbus
# bus: session
# name: org.net_mydomain_MyApp.SingleInstance # Remember to change net_mydomain_MyApp to your app ID with "_" instead of "." and "-"
#
#plugs:
# single-instance-plug:
# interface: dbus
# bus: session
# name: org.net_mydomain_MyApp.SingleInstance # Remember to change net_mydomain_MyApp to your app ID with "_" instead of "." and "-"
package-repositories:
- type: apt
components: [main]
suites: [noble]
key-id: 78E1918602959B9C59103100F1831DDAFC42E99D
url: http://ppa.launchpad.net/snappy-dev/snapcraft-daily/ubuntu
parts:
build-app:
plugin: dump
build-snaps:
- node/20/stable
- rustup/latest/stable
build-packages:
- libwebkit2gtk-4.1-dev
- build-essential
- curl
- wget
- file
- libxdo-dev
- libssl-dev
- libayatana-appindicator3-dev
- librsvg2-dev
- dpkg
stage-packages:
- libwebkit2gtk-4.1-0
- libayatana-appindicator3-1
source: .
override-build: |
set -eu
npm install
npm run tauri build -- --bundles deb
dpkg -x src-tauri/target/release/bundle/deb/*.deb $SNAPCRAFT_PART_INSTALL/
sed -i -e "s|Icon=appname|Icon=/usr/share/icons/hicolor/32x32/apps/appname.png|g" $SNAPCRAFT_PART_INSTALL/usr/share/applications/appname.desktop
Explanation
- The
namevariable defines the name of your app and is required to be set to the name that you have registered earlier. - The
basevariable defines which core you are using. - The
versionvariable defines the version, and should be updated with each change to the source repository. - The
appssection allows you to expose the desktop and binary files to allow the user to run your app. - The
package-repositoriessection allows you to add a package repository to help you satisfy your dependencies. build-packages/build-snapsdefines the build dependencies for your snap.stage-packages/stage-snapsdefines the runtime dependencies for your snap.- The
override-buildsection runs a series of commands after the sources were pulled.
Building
sudo snapcraft
Testing
snap run your-app
Releasing Manually
snapcraft login # Login with your UbuntuOne credentials
snapcraft upload --release=stable mysnap_latest_amd64.snap
Building automatically
- On your apps developer page click on the
buildstab. - Click
login with github. - Enter in your repository’s details.
Windows Installer
Tauri applications for Windows are either distributed as Microsoft Installers (.msi files) using the WiX Toolset v3 or as setup executables (-setup.exe files) using NSIS.
Please note that .msi installers can only be created on Windows as WiX can only run on Windows systems. Cross-compilation for NSIS installers is shown below.
This guide provides information about available customization options for the installer.
Building
To build and bundle your app into a Windows installer you can use the Tauri CLI and run the tauri build command in a Windows computer:
-
npm
npm run tauri build -
yarn
yarn tauri build -
pnpm
pnpm tauri build -
deno
deno task tauri build -
bun
bun tauri build -
cargo
cargo tauri build
VBSCRIPT requirement for MSI packages
Building MSI packages ("targets": "msi" or "targets": "all" in tauri.conf.json) requires the VBSCRIPT optional feature to be enabled on Windows. This feature is enabled by default on most Windows installations, but if you encounter errors like failed to run light.exe, you may need to enable it manually through Settings → Apps → Optional features → More Windows features. See the Prerequisites guide for detailed instructions.
Build Windows apps on Linux and macOS
Cross compiling Windows apps on Linux and macOS hosts is possible with caveats when using NSIS. It is not as straight forward as compiling on Windows directly and is not tested as much. Therefore it should only be used as a last resort if local VMs or CI solutions like GitHub Actions don’t work for you.
Note
Signing cross compiled Windows installers requires an external signing tool. See the signing documentation for more information.
Since Tauri officially only supports the MSVC Windows target, the setup is a bit more involved.
Install NSIS
-
Linux
Some Linux distributions have NSIS available in their repositories, for example on Ubuntu you can install NSIS by running this command:
Ubuntu
sudo apt install nsisBut on many other distributions you have to compile NSIS yourself or download Stubs and Plugins manually that weren’t included in the distro’s binary package. Fedora for example only provides the binary but not the Stubs and Plugins:
Fedora
sudo dnf in mingw64-nsis wget https://github.com/tauri-apps/binary-releases/releases/download/nsis-3/nsis-3.zip unzip nsis-3.zip sudo cp nsis-3.08/Stubs/* /usr/share/nsis/Stubs/ sudo cp -r nsis-3.08/Plugins/** /usr/share/nsis/Plugins/ -
macOS
On macOS you will need [Homebrew] to install NSIS:
macOS
brew install nsis
Install LLVM and the LLD Linker
Since the default Microsoft linker only works on Windows we will also need to install a new linker. To compile the Windows Resource file which is used for setting the app icon among other things we will also need the llvm-rc binary which is part of the LLVM project.
-
Linux
Ubuntu
sudo apt install lld llvmOn Linux you also need to install the
clangpackage if you added dependencies that compile C/C++ dependencies as part of their build scripts. Default Tauri apps should not require this. -
macOS
macOS
brew install llvmOn macOS you also have to add
/opt/homebrew/opt/llvm/binto your$PATHas suggested in the install output.
Install the Windows Rust target
Assuming you’re building for 64-bit Windows systems:
rustup target add x86_64-pc-windows-msvc
Install cargo-xwin
Instead of setting the Windows SDKs up manually we will use [cargo-xwin] as Tauri’s “runner”:
cargo install --locked cargo-xwin
By default cargo-xwin will download the Windows SDKs into a project-local folder. If you have multiple projects and want to share those files you can set the XWIN_CACHE_DIR environment variable with a path to the preferred location.
Building the App
Now it should be as simple as adding the runner and target to the tauri build command:
-
npm
npm run tauri build -- --runner cargo-xwin --target x86_64-pc-windows-msvc -
yarn
yarn tauri build --runner cargo-xwin --target x86_64-pc-windows-msvc -
pnpm
pnpm tauri build --runner cargo-xwin --target x86_64-pc-windows-msvc -
deno
deno task tauri build --runner cargo-xwin --target x86_64-pc-windows-msvc -
bun
bun tauri build --runner cargo-xwin --target x86_64-pc-windows-msvc -
cargo
cargo tauri build --runner cargo-xwin --target x86_64-pc-windows-msvc
The build output will then be in target/x86_64-pc-windows-msvc/release/bundle/nsis/.
Building for 32-bit or ARM
The Tauri CLI compiles your executable using your machine’s architecture by default. Assuming that you’re developing on a 64-bit machine, the CLI will produce 64-bit applications.
If you need to support 32-bit machines, you can compile your application with a different Rust target using the --target flag:
-
npm
npm run tauri build -- --target i686-pc-windows-msvc -
yarn
yarn tauri build --target i686-pc-windows-msvc -
pnpm
pnpm tauri build --target i686-pc-windows-msvc -
deno
deno task tauri build --target i686-pc-windows-msvc -
bun
bun tauri build --target i686-pc-windows-msvc -
cargo
cargo tauri build --target i686-pc-windows-msvc
By default, Rust only installs toolchains for your machine’s target, so you need to install the 32-bit Windows toolchain first: rustup target add i686-pc-windows-msvc.
If you need to build for ARM64 you first need to install additional build tools. To do this, open Visual Studio Installer, click on “Modify”, and in the “Individual Components” tab install the “C++ ARM64 build tools”. At the time of writing, the exact name in VS2022 is MSVC v143 - VS 2022 C++ ARM64 build tools (Latest). Now you can add the rust target with rustup target add aarch64-pc-windows-msvc and then use the above-mentioned method to compile your app:
-
npm
npm run tauri build -- --target aarch64-pc-windows-msvc -
yarn
yarn tauri build --target aarch64-pc-windows-msvc -
pnpm
pnpm tauri build --target aarch64-pc-windows-msvc -
deno
deno task tauri build --target aarch64-pc-windows-msvc -
bun
bun tauri build --target aarch64-pc-windows-msvc -
cargo
cargo tauri build --target aarch64-pc-windows-msvc
Note
Note that the NSIS installer itself will still be x86 running on the ARM machine via emulation. The app itself will be a native ARM64 binary.
Supporting Windows 7
By default, the Microsoft Installer (.msi) does not work on Windows 7 because it needs to download the WebView2 bootstrapper if not installed (which might fail if TLS 1.2 is not enabled in the operating system). Tauri includes an option to embed the WebView2 bootstrapper (see the Embedding the WebView2 Bootstrapper section below). The NSIS based installer (-setup.exe) also supports the downloadBootstrapper mode on Windows 7.
Additionally, to use the Notification API in Windows 7, you need to enable the windows7-compat Cargo feature:
Cargo.toml
[dependencies]
tauri-plugin-notification = { version = "2.0.0", features = [ "windows7-compat" ] }
FIPS Compliance
If your system requires the MSI bundle to be FIPS compliant you can set the TAURI_BUNDLER_WIX_FIPS_COMPLIANT environment variable to true before running tauri build. In PowerShell you can set it for the current terminal session like this:
$env:TAURI_BUNDLER_WIX_FIPS_COMPLIANT="true"
WebView2 Installation Options
The installers by default download the WebView2 bootstrapper and executes it if the runtime is not installed. Alternatively, you can embed the bootstrapper, embed the offline installer, or use a fixed WebView2 runtime version. See the following table for a comparison between these methods:
| Installation Method | Requires Internet Connection? | Additional Installer Size | Notes |
|---|---|---|---|
downloadBootstrapper |
Yes | 0MB | Default Results in a smaller installer size, but is not recommended for Windows 7 deployment via .msi files. |
embedBootstrapper |
Yes | ~1.8MB | Better support on Windows 7 for .msi installers. |
offlineInstaller |
No | ~127MB | Embeds WebView2 installer. Recommended for offline environments. |
fixedVersion |
No | ~180MB | Embeds a fixed WebView2 version. |
skip |
No | 0MB | ⚠️ Not recommended Does not install the WebView2 as part of the Windows Installer. |
Note
On Windows 10 (April 2018 release or later) and Windows 11, the WebView2 runtime is distributed as part of the operating system.
Downloaded Bootstrapper
This is the default setting for building the Windows Installer. It downloads the bootstrapper and runs it. Requires an internet connection but results in a smaller installer size. This is not recommended if you’re going to be distributing to Windows 7 via .msi installers.
tauri.conf.json
{
"bundle": {
"windows": {
"webviewInstallMode": {
"type": "downloadBootstrapper"
}
}
}
}
Embedded Bootstrapper
To embed the WebView2 Bootstrapper, set the webviewInstallMode to embedBootstrapper. This increases the installer size by around 1.8MB, but increases compatibility with Windows 7 systems.
tauri.conf.json
{
"bundle": {
"windows": {
"webviewInstallMode": {
"type": "embedBootstrapper"
}
}
}
}
Offline Installer
To embed the WebView2 Bootstrapper, set the webviewInstallMode to offlineInstaller. This increases the installer size by around 127MB, but allows your application to be installed even if an internet connection is not available.
tauri.conf.json
{
"bundle": {
"windows": {
"webviewInstallMode": {
"type": "offlineInstaller"
}
}
}
}
Fixed Version
Using the runtime provided by the system is great for security as the webview vulnerability patches are managed by Windows. If you want to control the WebView2 distribution on each of your applications (either to manage the release patches yourself or distribute applications on environments where an internet connection might not be available) Tauri can bundle the runtime files for you.
Caution
Distributing a fixed WebView2 Runtime version increases the Windows Installer by around 180MB.
- Download the WebView2 fixed version runtime from Microsoft’s website. In this example, the downloaded filename is
Microsoft.WebView2.FixedVersionRuntime.128.0.2739.42.x64.cab - Extract the file to the core folder:
Expand .\Microsoft.WebView2.FixedVersionRuntime.128.0.2739.42.x64.cab -F:* ./src-tauri
- Configure the WebView2 runtime path in
tauri.conf.json:
tauri.conf.json
{
"bundle": {
"windows": {
"webviewInstallMode": {
"type": "fixedRuntime",
"path": "./Microsoft.WebView2.FixedVersionRuntime.98.0.1108.50.x64/"
}
}
}
}
- Run
tauri buildto produce the Windows Installer with the fixed WebView2 runtime.
Skipping Installation
You can remove the WebView2 Runtime download check from the installer by setting webviewInstallMode to skip. Your application WILL NOT work if the user does not have the runtime installed.
Your application WILL NOT work if the user does not have the runtime installed and won’t attempt to install it.
tauri.conf.json
{
"bundle": {
"windows": {
"webviewInstallMode": {
"type": "skip"
}
}
}
}
Minimum Webview2 version
If your app requires features only available in newer Webview2 versions (such as custom URI schemes), you can instruct the Windows installer to verify the current Webview2 version and run the Webview2 bootstrapper if it does not match the target version.
tauri.conf.json
{
"bundle": {
"windows": {
"minimumWebview2Version": "110.0.1531.0"
}
}
}
Customizing the WiX Installer
See the WiX configuration for the complete list of customization options.
Installer Template
The .msi Windows Installer package is built using the WiX Toolset v3. Currently, apart from pre-defined configurations, you can change it by using a custom WiX source code (an XML file with a .wxs file extension) or through WiX fragments.
Replacing the Installer Code with a Custom WiX File
The Windows Installer XML defined by Tauri is configured to work for the common use case of simple webview-based applications (you can find it here). It uses handlebars so the Tauri CLI can brand your installer according to your tauri.conf.json definition. If you need a completely different installer, a custom template file can be configured on tauri.bundle.windows.wix.template.
Extending the Installer with WiX Fragments
A WiX fragment is a container where you can configure almost everything offered by WiX. In this example, we will define a fragment that writes two registry entries:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<!-- these registry entries should be installed
to the target user's machine -->
<DirectoryRef Id="TARGETDIR">
<!-- groups together the registry entries to be installed -->
<!-- Note the unique `Id` we provide here -->
<Component Id="MyFragmentRegistryEntries" Guid="*">
<!-- the registry key will be under
HKEY_CURRENT_USER\Software\MyCompany\MyApplicationName -->
<!-- Tauri uses the second portion of the
bundle identifier as the `MyCompany` name
(e.g. `tauri-apps` in `com.tauri-apps.test`) -->
<RegistryKey
Root="HKCU"
Key="Software\MyCompany\MyApplicationName"
Action="createAndRemoveOnUninstall"
>
<!-- values to persist on the registry -->
<RegistryValue
Type="integer"
Name="SomeIntegerValue"
Value="1"
KeyPath="yes"
/>
<RegistryValue Type="string" Value="Default Value" />
</RegistryKey>
</Component>
</DirectoryRef>
</Fragment>
</Wix>
Save the fragment file with the .wxs extension in the src-tauri/windows/fragments folder and reference it on tauri.conf.json:
tauri.conf.json
{
"bundle": {
"windows": {
"wix": {
"fragmentPaths": ["./windows/fragments/registry.wxs"],
"componentRefs": ["MyFragmentRegistryEntries"]
}
}
}
}
Note that ComponentGroup, Component, FeatureGroup, Feature and Merge element ids must be referenced on the wix object of tauri.conf.json on the componentGroupRefs, componentRefs, featureGroupRefs, featureRefs and mergeRefs respectively to be included in the installer.
Internationalization
The WiX Installer is built using the en-US language by default. Internationalization (i18n) can be configured using the tauri.bundle.windows.wix.language property, defining the languages Tauri should build an installer against. You can find the language names to use in the Language-Culture column on Microsoft’s website.
Compiling a WiX Installer for a Single Language
To create a single installer targeting a specific language, set the language value to a string:
tauri.conf.json
{
"bundle": {
"windows": {
"wix": {
"language": "fr-FR"
}
}
}
}
Compiling a WiX Installer for Each Language in a List
To compile an installer targeting a list of languages, use an array. A specific installer for each language will be created, with the language key as a suffix:
tauri.conf.json
{
"bundle": {
"windows": {
"wix": {
"language": ["en-US", "pt-BR", "fr-FR"]
}
}
}
}
Configuring the WiX Installer Strings for Each Language
A configuration object can be defined for each language to configure localization strings:
tauri.conf.json
{
"bundle": {
"windows": {
"wix": {
"language": {
"en-US": null,
"pt-BR": {
"localePath": "./wix/locales/pt-BR.wxl"
}
}
}
}
}
}
The localePath property defines the path to a language file, a XML configuring the language culture:
<WixLocalization
Culture="en-US"
xmlns="http://schemas.microsoft.com/wix/2006/localization"
>
<String Id="LaunchApp"> Launch MyApplicationName </String>
<String Id="DowngradeErrorMessage">
A newer version of MyApplicationName is already installed.
</String>
<String Id="PathEnvVarFeature">
Add the install location of the MyApplicationName executable to
the PATH system environment variable. This allows the
MyApplicationName executable to be called from any location.
</String>
<String Id="InstallAppFeature">
Installs MyApplicationName.
</String>
</WixLocalization>
Note
The WixLocalization element’s Culture field must match the configured language.
Currently, Tauri references the following locale strings: LaunchApp, DowngradeErrorMessage, PathEnvVarFeature and InstallAppFeature. You can define your own strings and reference them on your custom template or fragments with "!(loc.TheStringId)". See the WiX localization documentation for more information.
Customizing the NSIS Installer
See the NSIS configuration for the complete list of customization options.
Installer Template
The NSIS Installer’s .nsi script defined by Tauri is configured to work for the common use case of simple webview-based applications (you can find it here). It uses handlebars so the Tauri CLI can brand your installer according to your tauri.conf.json definition. If you need a completely different installer, a custom template file can be configured on tauri.bundle.windows.nsis.template.
Extending the Installer
If you only need to extend some installation steps you might be able to use installer hooks instead of replacing the entire installer template.
Supported hooks are:
NSIS_HOOK_PREINSTALL: Runs before copying files, setting registry key values and creating shortcuts.NSIS_HOOK_POSTINSTALL: Runs after the installer has finished copying all files, setting the registry keys and created shortcuts.NSIS_HOOK_PREUNINSTALL: Runs before removing any files, registry keys and shortcuts.NSIS_HOOK_POSTUNINSTALL: Runs after files, registry keys and shortcuts have been removed.
For example, create a hooks.nsh file in the src-tauri/windows folder and define the hooks you need:
!macro NSIS_HOOK_PREINSTALL
MessageBox MB_OK "PreInstall"
!macroend
!macro NSIS_HOOK_POSTINSTALL
MessageBox MB_OK "PostInstall"
!macroend
!macro NSIS_HOOK_PREUNINSTALL
MessageBox MB_OK "PreUnInstall"
!macroend
!macro NSIS_HOOK_POSTUNINSTALL
MessageBox MB_OK "PostUninstall"
!macroend
Then you must configure Tauri to use that hook file:
tauri.conf.json
{
"bundle": {
"windows": {
"nsis": {
"installerHooks": "./windows/hooks.nsh"
}
}
}
}
Installing Dependencies with Hooks
You can use installer hooks to automatically install system dependencies that your application requires. This is particularly useful for runtime dependencies like Visual C++ Redistributables, DirectX, OpenSSL or other system libraries that may not be present on all Windows systems.
MSI Installer Example (Visual C++ Redistributable):
!macro NSIS_HOOK_POSTINSTALL
; Check if Visual C++ 2019 Redistributable is installed (via Windows Registry)
ReadRegDWord $0 HKLM "SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64" "Installed"
${If} $0 == 1
DetailPrint "Visual C++ Redistributable already installed"
Goto vcredist_done
${EndIf}
; Install from bundled MSI if not installed
${If} ${FileExists} "$INSTDIR\resources\vc_redist.x64.msi"
DetailPrint "Installing Visual C++ Redistributable..."
; Copy to TEMP folder and then execute installer
CopyFiles "$INSTDIR\resources\vc_redist.x64.msi" "$TEMP\vc_redist.x64.msi"
ExecWait 'msiexec /i "$TEMP\vc_redist.x64.msi" /passive /norestart' $0
; Check wether installation process exited successfully (code 0) or not
${If} $0 == 0
DetailPrint "Visual C++ Redistributable installed successfully"
${Else}
MessageBox MB_ICONEXCLAMATION "Visual C++ installation failed. Some features may not work."
${EndIf}
; Clean up setup files from TEMP and your installed app
Delete "$TEMP\vc_redist.x64.msi"
Delete "$INSTDIR\resources\vc_redist.x64.msi"
${EndIf}
vcredist_done:
!macroend
Key considerations:
- A good practice is to always check if the dependency is already installed using registry keys or file existence or via Windows where command.
- Use
/passive,/quiet, or/silentflags to avoid interrupting the installation flow. Check out msiexec options for.msifiles, or the setup manual for app-specific flags - Include
/norestartto prevent automatic system reboots during installation for setups that restarts user devices - Clean up temporary files and bundled installers to avoid bloating the application
- Consider that dependencies might be shared with other applications when uninstalling
- Provide meaningful error messages if installation fails
Ensure to bundle the dependency installers in your src-tauri/resources folder and add to tauri.conf.json so they get bundled, and can be accessed during installation from $INSTDIR\resources\:
tauri.conf.json
{
"bundle": {
"resources": [
"resources/my-dependency.exe",
"resources/another-one.msi
]
}
}
Install Modes
By default the installer will install your application for the current user only. The advantage of this option is that the installer does not require Administrator privileges to run, but the app is installed in the %LOCALAPPDATA% folder instead of C:/Program Files.
If you prefer your app installation to be available system-wide (which requires Administrator privileges) you can set installMode to perMachine:
tauri.conf.json
{
"bundle": {
"windows": {
"nsis": {
"installMode": "perMachine"
}
}
}
}
Alternatively you can let the user choose whether the app should be installed for the current user only or system-wide by setting the installMode to both. Note that the installer will require Administrator privileges to execute.
See NSISInstallerMode for more information.
Internationalization
The NSIS Installer is a multi-language installer, which means you always have a single installer which contains all the selected translations.
You can specify which languages to include using the tauri.bundle.windows.nsis.languages property. A list of languages supported by NSIS is available in the NSIS GitHub project. There are a few Tauri-specific translations required, so if you see untranslated texts feel free to open a feature request in Tauri’s main repo. You can also provide custom translation files.
By default the operating system default language is used to determine the installer language. You can also configure the installer to display a language selector before the installer contents are rendered:
tauri.conf.json
{
"bundle": {
"windows": {
"nsis": {
"displayLanguageSelector": true
}
}
}
}
Learn
Tutorials intended to provide end-to-end learning experiences to guide you through specific Tauri topics and help you apply knowledge from the guides and reference documentation
The Learning category is intended to provide end-to-end learning experiences on a Tauri related topic.
These tutorials will guide you through a specific topic and help you apply knowledge from the guides and reference documentation.
For security related topics, you can learn about the permissions system. You will get practical insight into how to use it, extend it, and write your own permissions.
Capabilities for Different Windows and Platforms
To learn how to write your own splash screen, use a node.js sidecar, or set up mobile features, check out:
More Resources
This section contains learning resources created by the Community that are not hosted on this website.
Have something to share?Open a pull request to show us your amazing resource.
Books
HTML, CSS, JavaScript, and Rust for Beginners: A Guide to Application Development with Tauri
by James Alexander Rose
Paperback on Amazon: Buy Here
Free PDF version: Download (PDF 4MB)
Guides & Tutorials
Auto-Updates with Tauri v2Setup auto-updates with Tauri and CrabNebula Cloud.
Publish to Apple’s App StoreDetails all the steps needed to publish your Mac app to the app store. Includes a sample bash script.
Video Guides
Create Tauri App with ReactChris Biscardi shows how easy it is to wire up a Rust crate with a JS module and communicate between them.
Tauri & ReactJS - Creating Modern Desktop AppsCreating a modern desktop application with Tauri.
File Associations on Mobile
Tauri supports file associations on Android and iOS, allowing your app to be registered as a handler for specific file types. When a user opens a file that matches your declared associations, the operating system launches your app and delivers the file URL.
On Android, file associations are implemented using intent filters that the Tauri build system generates automatically from your configuration.
On iOS, file associations use CFBundleDocumentTypes and optionally UTExportedTypeDeclarations for custom file types.
Configuration
File associations are declared in tauri.conf.json under bundle.fileAssociations. The Tauri CLI uses this configuration to generate the appropriate platform-specific metadata (Android intent filters in AndroidManifest.xml, iOS document types in Info.plist).
Each entry in the array represents a file type your app can handle:
src-tauri/tauri.conf.json
{
"bundle": {
"fileAssociations": [
{
"ext": ["png"],
"mimeType": "image/png"
},
{
"ext": ["jpg", "jpeg"],
"mimeType": "image/jpeg"
}
]
}
}
Configuration Options
ext— list of file extensions to associate (without leading dot).mimeType— the MIME type for the file (e.g.image/png). Required on Android for intent filter matching. Tauri infers common MIME types from extensions when not specified.role— the app’s role with respect to the file type. Maps toCFBundleTypeRoleon Apple platforms. Values:Editor(default),Viewer,Shell,QLGenerator,None.rank— the ranking among apps that handle this file type. Maps toLSHandlerRankon Apple platforms. Values:Default(default),Owner,Alternate,None.name— display name for the file type. Defaults to the first extension.exportedType— defines a custom file type owned by your app. Required on Apple platforms when associating with non-standard file extensions.androidIntentActionFilters— which Android intent actions to register. Values:Send,SendMultiple,View. All three are used by default.
Custom File Types
For non-standard file extensions, you should define an exportedType so Apple platforms can identify the file type. The identifier should be a reverse-DNS string unique to your app, and conformsTo lists the parent types:
src-tauri/tauri.conf.json
{
"bundle": {
"fileAssociations": [
{
"ext": ["mydata"],
"mimeType": "application/octet-stream",
"exportedType": {
"identifier": "com.example.myapp.mydata",
"conformsTo": ["public.data"]
}
}
]
}
}
Common conformsTo values include public.data, public.image, public.json, and public.plain-text.
Handling Opened Files
When a file is opened with your app, Tauri emits a RunEvent::Opened event containing the file URLs. This event is available on macOS, iOS, and Android.
You need to handle two cases:
- App is already running — the event is delivered at runtime.
- App is launched by the file open — the event fires during startup, so you should store the URLs and make them available to your frontend.
Rust
Store incoming URLs in managed state, expose them with a command the frontend can call on startup, and emit a Tauri event whenever RunEvent::Opened fires so the frontend can react while the app is already running:
src-tauri/src/lib.rs
use std::sync::Mutex;
use tauri::Manager;
struct OpenedUrls(Mutex<Vec<tauri::Url>>);
#[tauri::command]
fn opened_urls(app: tauri::AppHandle) -> Vec<tauri::Url> {
app.state::<OpenedUrls>().0.lock().unwrap().clone()
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.manage(OpenedUrls(Mutex::new(vec![])))
.invoke_handler(tauri::generate_handler![opened_urls])
.build(tauri::generate_context!())
.expect("error while running tauri application")
.run(|app, event| {
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "android"))]
if let tauri::RunEvent::Opened { urls } = event {
use tauri::Emitter;
app.state::<OpenedUrls>()
.0
.lock()
.unwrap()
.extend(urls.clone());
app.emit("opened", urls).unwrap();
}
});
}
JavaScript
The frontend below is wired to that Rust code in two places:
invoke('opened_urls')calls theopened_urlscommand, so the webview can read URLs that were stored before the UI finished loading (cold start from a file open).listen('opened', …)subscribes to the same event name passed toapp.emit("opened", urls)in Rust, so file open events that are triggered while the app is already running are delivered immediately.
import { listen } from '@tauri-apps/api/event';
import { invoke } from '@tauri-apps/api/core';
// Cold start: URLs may already be in Rust state before the frontend loads
const initialUrls = await invoke('opened_urls');
if (initialUrls.length > 0) {
handleFiles(initialUrls);
}
// Warm: Rust emits the "opened" event when RunEvent::Opened fires
await listen('opened', (event) => {
handleFiles(event.payload);
});
Multi-Window on Mobile
Tauri supports multiple windows on Android and iOS, allowing your app to display content side-by-side on tablets or in separate scenes on iPad.
On Android, multi-window is implemented using Activity Embedding, which lets the system display two activities side by side on large screens.
On iOS, multi-window uses the UIScene API, which allows iPad users to open multiple instances of your app in separate windows.
On phones, the system usually does not lay out two windows side by side. On Android, creating another window still launches a separate activity, but on handset-sized displays it is typically pushed onto the activity back stack—so Back returns to the previous activity instead of closing a split. On iOS (especially iPhone), opening or creating another window often replaces the current UI with the new scene’s content rather than keeping both visible at once; true concurrent windows remain an iPad (and Stage Manager) experience.
Note
Multi-window requires Android 12L (API 32)+ and iOS 13+. You can use the [app.supportsMultipleWindows] API to check availability at runtime.
Shared Setup
Both platforms require a capability permission to create new windows from the frontend.
Capabilities
Add the core:webview:allow-create-webview-window permission to your capability file so your frontend can create new windows.
If you are creating multiple windows, use a wildcard or list every window label in the windows array:
src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "Capability for the main window",
"windows": ["main"],
+"permissions": ["core:default", "core:webview:allow-create-webview-window"]
}
Android
Android multi-window uses Activity Embedding to split activities side by side on large screens (tablets, foldables). You need to create an Android Activity for each window type, configure split rules, and register an initializer.
-
Add Dependencies
Add the required AndroidX libraries to your
build.gradle.kts:src-tauri/gen/android/app/build.gradle.kts
dependencies { // ... existing dependencies +implementation("androidx.window:window:1.5.0") +implementation("androidx.startup:startup-runtime:1.2.0") } -
Create a New Activity
Create a Kotlin class for each additional window type. Each activity must extend
TauriActivity:src-tauri/gen/android/app/src/main/java/com/example/app/DetailActivity.kt
package com.example.app import android.os.Bundle import android.os.PersistableBundle class DetailActivity: TauriActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) } } -
Update AndroidManifest.xml
Register the new activity and enable activity embedding by adding the
toolsnamespace and the embedding property:src-tauri/gen/android/app/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" +xmlns:tools="http://schemas.android.com/tools"> <application ...> <property +android:name="android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED" +android:value="true" /> <!-- Existing MainActivity --> <activity android:name=".MainActivity" android:exported="true" ...> ... </activity> <!-- New activity for the detail window --> <activity android:name=".DetailActivity" android:exported="true" /> +<!-- Register the split initializer --> <provider android:name="androidx.startup.InitializationProvider" +android:authorities="${applicationId}.androidx-startup" +android:exported="false" +tools:node="merge"> <meta-data android:name="${applicationId}.SplitInitializer" +android:value="androidx.startup" /> </provider> </application> </manifest> -
Create the Split Initializer
The initializer loads the split pair rules at app startup:
src-tauri/gen/android/app/src/main/java/com/example/app/SplitInitializer.kt
package com.example.app import android.content.Context import androidx.startup.Initializer import androidx.window.core.ExperimentalWindowApi import androidx.window.embedding.RuleController @OptIn(ExperimentalWindowApi::class) class SplitInitializer : Initializer<RuleController> { override fun create(context: Context): RuleController { return RuleController.getInstance(context).apply { setRules(RuleController.parseRules(context, R.xml.main_split_config)) } } override fun dependencies(): List<Class<out Initializer<*>>> { return emptyList() } } -
Define Split Rules
Create an XML resource that tells the system how to pair activities and split the screen:
src-tauri/gen/android/app/src/main/res/xml/main_split_config.xml
<resources xmlns:window="http://schemas.android.com/apk/res-auto"> <SplitPairRule window:splitRatio="0.33" window:splitLayoutDirection="locale" window:splitMinWidthDp="840" window:splitMaxAspectRatioInPortrait="alwaysAllow" window:finishPrimaryWithSecondary="never" window:finishSecondaryWithPrimary="never" window:clearTop="false"> <SplitPairFilter window:primaryActivityName=".MainActivity" window:secondaryActivityName=".DetailActivity"/> </SplitPairRule> </resources>Key attributes:
splitRatio— how the screen is divided (0.33 gives the primary activity one-third)splitMinWidthDp— minimum screen width to activate the split (840dp targets tablets)splitMaxAspectRatioInPortrait— set toalwaysAllowto enable split in portrait modeprimaryActivityName/secondaryActivityName— which activity pair triggers the split
iOS
On iOS, multi-window uses the UIScene API. iPad users can open new windows by long-pressing the app icon and selecting “New window”, or your app can create them programmatically.
-
Enable Scene Support
Create an
Info.ios.plistfile in yoursrc-tauridirectory to declare scene support:src-tauri/Info.ios.plist
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>UIApplicationSceneManifest</key> <dict> <key>UIApplicationSupportsMultipleScenes</key> <true/> <key>UISceneConfigurations</key> <dict/> </dict> </dict> </plist> -
Handle Scene Requests
When a user requests a new window on iPad (for example by long-pressing the app icon), Tauri emits a
RunEvent::SceneRequestedevent. Handle it to create a new window:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { #[cfg(target_os = "ios")] let mut counter = 0; tauri::Builder::default() .setup(|app| { tauri::WebviewWindowBuilder::new( app, "main", tauri::WebviewUrl::default() ).build()?; Ok(()) }) .build(tauri::generate_context!()) .expect("error while running tauri application") .run(move |app, event| { #[cfg(target_os = "ios")] if let tauri::RunEvent::SceneRequested { .. } = event { counter += 1; tauri::WebviewWindowBuilder::new( app, format!("main-{counter}"), tauri::WebviewUrl::default(), ) .build() .unwrap(); } #[cfg(not(target_os = "ios"))] let _ = (app, event); }); }Note
Since scene-requested windows use dynamic labels like
main-1,main-2, etc., make sure your capabilities file includes a wildcard pattern to cover them — e.g."windows": ["main", "main-*"].
Creating Windows
You can create additional windows from both Rust and the frontend JavaScript API. The WebviewWindowBuilder (Rust) and WebviewWindow (JavaScript) accept platform-specific options:
Android options:
activityName— the name of the Android Activity class to create for this window.createdByActivityName— the name of the Activity that is creating this window. This determines which activity stack the new activity belongs to, which is important for the split rules to work correctly. When not set, it is automatically inherited from the manager (e.g. when building from aWindoworWebviewhandle).
iOS options:
requestedBySceneIdentifier— sets the identifier of the UIScene that is requesting the creation of this new scene, establishing a relationship between the two scenes. By default the system uses the foreground scene. When not set, it is automatically inherited from the manager.
-
JavaScript
import { WebviewWindow } from '@tauri-apps/api/webviewWindow'; function openDetail(id) { const webview = new WebviewWindow(`detail-${id}`, { url: `detail/${id}`, activityName: 'DetailActivity', }); webview.once('tauri://created', () => { console.log('window created'); }); webview.once('tauri://error', (e) => { console.error(e); }); } -
Rust
use tauri::Manager; let main_window = app.get_webview_window("main").unwrap(); // use the main_window instance so the relationships are determined automatically let builder = tauri::WebviewWindowBuilder::new(main_window, "detail", tauri::WebviewUrl::App("detail/1".into())); #[cfg(target_os = "android")] let builder = builder.activity_name("DetailActivity"); let window = builder.build()?;
Tip
If you are using a frontend router, use a browser-history based router (e.g. createBrowserRouter in React Router) instead of a hash router so each window can navigate to a distinct URL path.
Window Instance APIs
Once a window has been created, you can retrieve its platform-specific identifier:
-
JavaScript
const activityName = await window.activityName(); const sceneId = await window.sceneIdentifier(); -
Rust
#[cfg(target_os = "android")] let activity = window.activity_name()?; #[cfg(target_os = "ios")] let scene_id = window.scene_identifier()?;
These getters are useful for referencing a window’s identity when creating related windows. For example, you can read a window’s activityName to pass as createdByActivityName on a new window, or read sceneIdentifier to pass as requestedBySceneIdentifier.
Capabilities for Different Windows and Platforms
This guide will help you customize the capabilities of your Tauri app.
Content of this guide
- Create multiple windows in a Tauri app
- Use different capabilities for different windows
- Use platform-specific capabilities
Prerequisites
This exercise is meant to be read after completing Using Plugin Permissions.
Guide
-
Create Multiple Windows in a Tauri Application
Here we create an app with two windows labelled
firstandsecond. There are multiple ways to create windows in your Tauri application.Create Windows with the Tauri Configuration File
In the Tauri configuration file, usually named
tauri.conf.json:Show solution
"productName": "multiwindow", ... "app": { "windows": [ { "label": "first", "title": "First", "width": 800, "height": 600 }, { "label": "second", "title": "Second", "width": 800, "height": 600 } ], }, ... }Create Windows Programmatically
In the Rust code to create a Tauri app:
Show solution
tauri::Builder::default() .invoke_handler(tauri::generate_handler![greet]) .setup(|app| { let webview_url = tauri::WebviewUrl::App("index.html".into()); // First window tauri::WebviewWindowBuilder::new(app, "first", webview_url.clone()) .title("First") .build()?; // Second window tauri::WebviewWindowBuilder::new(app, "second", webview_url) .title("Second") .build()?; Ok(()) }) .run(context) .expect("error while running tauri application"); -
Apply Different Capabilities to Different Windows
The windows of a Tauri app can use different features or plugins of the Tauri backend. For better security it is recommended to only give the necessary capabilities to each window. We simulate a scenario where the
firstwindows uses filesystem and dialog functionalities andsecondonly needs dialog functionalities.Separate capability files per category
It is recommended to separate the capability files per category of actions they enable.
Show solution
JSON files in the
src-tauri/capabilitieswill be taken into account for the capability system. Here we separate capabilities related to the filesystem and dialog window intofilesystem.jsonanddialog.json.filetree of the Tauri project:
/src /src-tauri /capabilities filesystem.json dialog.json tauri.conf.json package.json README.mdGive filesystem capabilities to the
firstwindowWe give the
firstwindow the capability to have read access to the content of the$HOMEdirectory.Show solution
Use the
windowsfield in a capability file with one or multiple window labels.filesystem.json
{ "identifier": "fs-read-home", "description": "Allow access file access to home directory", "local": true, "windows": ["first"], "permissions": [ "fs:allow-home-read", ] }Give dialog capabilities to the
firstandsecondwindowWe give to
firstandsecondwindows the capability to create a “Yes/No” dialogShow solution
Use the
windowsfield in a capability file with one or multiple window labels.dialog.json
{ "identifier": "dialog", "description": "Allow to open a dialog", "local": true, "windows": ["first", "second"], "permissions": ["dialog:allow-ask"] } -
Make Capabilities Platform Dependent
We now want to customize the capabilities to be active only on certain platforms. We make our filesystem capabilities only active on
linuxandwindows.Show solution
Use the
platformsfield in a capability file to make it platform-specific.filesystem.json
{ "identifier": "fs-read-home", "description": "Allow access file access to home directory", "local": true, "windows": ["first"], "permissions": [ "fs:allow-home-read", ], "platforms": ["linux", "windows"] }The currently available platforms are
linux,windows,macos,android, andios.
Conclusion and Resources
We have learned how to create multiple windows in a Tauri app and give them specific capabilities. Furthermore these capabilities can also be targeted to certain platforms.
An example application that used window capabilities can be found in the api example of the Tauri Github repository. The fields that can be used in a capability file are listed in the Capability reference.
Using Plugin Permissions
The goal of this exercise is to get a better understanding on how plugin permissions can be enabled or disabled, where they are described and how to use default permissions of plugins.
At the end you will have the ability to find and use permissions of arbitrary plugins and understand how to custom tailor existing permissions. You will have an example Tauri application where a plugin and plugin specific permissions are used.
-
Create Tauri Application
Create your Tauri application. In our example we will facilitate
create-tauri-app:-
Bash
sh <(curl https://create.tauri.app/sh) -
PowerShell
irm https://create.tauri.app/ps | iex -
Fish
sh (curl -sSL https://create.tauri.app/sh | psub) -
npm
npm create tauri-app@latest -
Yarn
yarn create tauri-app -
pnpm
pnpm create tauri-app -
deno
deno run -A npm:create-tauri-app -
bun
bun create tauri-app -
Cargo
cargo install create-tauri-app --locked cargo create-tauri-app
We will proceed in this step-by-step explanation with
pnpmbut you can choose another package manager and replace it in the commands accordingly.Show solution
pnpm create tauri-app✔ Project name · plugin-permission-demo ✔ Choose which language to use for your frontend · TypeScript / JavaScript - (pnpm, yarn, npm, bun) ✔ Choose your package manager · pnpm ✔ Choose your UI template · Vanilla ✔ Choose your UI flavor · TypeScript Template created! To get started run: cd plugin-permission-demo pnpm install pnpm tauri dev -
-
Add the
file-systemPlugin to Your ApplicationTo search for existing plugins you can use multiple resources.
The most straight forward way would be to check out if your plugin is already in the Plugins section of the documentation and therefore part of Tauri’s maintained plugin set. The Filesystem plugin is part of the Tauri plugin workspace and you can add it to your project by following the instructions.
If the plugin is part of the community effort you can most likely find it on crates.io when searching for
tauri-plugin-<your plugin name>.Show solution
If it is an existing plugin from our workspace you can use the automated way:
pnpm tauri add fsIf you have found it on crates.io you need to manually add it as a dependency and modify the Tauri builder to initialize the plugin:
cargo add tauri-plugin-fsModify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] fn run() { tauri::Builder::default() +.plugin(tauri_plugin_fs::init()) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Understand the Default Permissions of the
fsPluginEach plugin has a
defaultpermission set, which contains all permissions and scopes to use the plugin out of the box with a reasonable minimal feature set.In the case of official maintained plugins you can find a rendered description in the documentation (eg. fs default).
In case you are figuring this out for a community plugin you need to check out the source code of the plugin. This should be defined in
your-plugin/permissions/default.toml.Show solution
"$schema" = "schemas/schema.json" [default] description = """ # Tauri `fs` default permissions This configuration file defines the default permissions granted to the filesystem. ### Granted Permissions This default permission set enables all read-related commands and allows access to the `$APP` folder and sub directories created in it. The location of the `$APP` folder depends on the operating system, where the application is run. In general the `$APP` folder needs to be manually created by the application at runtime, before accessing files or folders in it is possible. ### Denied Permissions This default permission set prevents access to critical components of the Tauri application by default. On Windows the webview data folder access is denied. """ permissions = ["read-all", "scope-app-recursive", "deny-default"] -
Find the Right Permissions
This step is all about finding the permissions you need to for your commands to be exposed to the frontend with the minimal access to your system.
The
fsplugin has autogenerated permissions which will disable or enable individual commands and allow or disable global scopes.These can be found in the documentation or in the source code of the plugin (
fs/permissions/autogenerated).Let us assume we want to enable writing to a text file
test.txtlocated in the users$HOMEfolder.For this we would search in the autogenerated permissions for a permission to enable writing to text files like
allow-write-text-fileand then for a scope which would allow us to access the$HOME/test.txtfile.We need to add these to our
capabilitiessection in oursrc-tauri/tauri.conf.jsonor in a file in thesrc-tauri/capabilities/folder. By default there is already a capability insrc-tauri/capabilities/default.jsonwe can modify.Show solution
src-tauri/capabilities/default.json
{ "$schema": "../gen/schemas/desktop-schema.json", "identifier": "default", "description": "Capability for the main window", "windows": [ "main" ], "permissions": [ "path:default", "event:default", "window:default", "app:default", "image:default", "resources:default", "menu:default", "tray:default", "shell:allow-open", -"fs:default", +"fs:allow-write-text-file", ] }Since there are only autogenerated scopes in the
fsplugin to access the full$HOMEfolder, we need to configure our own scope. This scope should be only enabled for thewrite-text-filecommand and should only expose ourtest.txtfile.Show solution
src-tauri/capabilities/default.json
{ "$schema": "../gen/schemas/desktop-schema.json", "identifier": "default", "description": "Capability for the main window", "windows": [ "main" ], "permissions": [ "path:default", "event:default", "window:default", "app:default", "image:default", "resources:default", "menu:default", "tray:default", "shell:allow-open", -"fs:allow-write-text-file", + { +"identifier": "fs:allow-write-text-file", +"allow": [{ "path": "$HOME/test.txt" }] + }, ] } -
Test Permissions in Practice
After we have added the necessary permission we want to confirm that our application can access the file and write it’s content.
Show solution
We can use this snippet in our application to write to the file:
src/main.ts
import { writeTextFile, BaseDirectory } from '@tauri-apps/plugin-fs'; let greetInputEl: HTMLInputElement | null; async function write(message: string) { await writeTextFile('test.txt', message, { baseDir: BaseDirectory.Home }); } window.addEventListener("DOMContentLoaded", () => { greetInputEl = document.querySelector("#greet-input"); document.querySelector("#greet-form")?.addEventListener("submit", (e) => { e.preventDefault(); if (!greetInputEl ) return; write(greetInputEl.value == "" ? "No input provided": greetInputEl.value); }); });Replacing the
src/main.tswith this snippet means we do not need to modify the defaultindex.html, when using the plain Vanilla+Typescript app. Entering any input into the input field of the running app will be written to the file on submit.Let’s test now in practice:
pnpm run tauri devAfter writing into the input and clicking “Submit”, we can check via our terminal emulator or by manually opening the file in your home folder.
cat $HOME/test.txtYou should be presented with your input and finished learning about using permissions from plugins in Tauri applications. 🥳
If you encountered this error:
[Error] Unhandled Promise Rejection: fs.write_text_file not allowed. Permissions associated with this command: fs:allow-app-write, fs:allow-app-write-recursive, fs:allow-appcache-write, fs:allow-appcache-write-recursive, fs:allow-appconf... (anonymous function) (main.ts:5)Then you very likely did not properly follow the previous instructions.
Writing Plugin Permissions
The goal of this exercise is to get a better understanding on how plugin permissions can be created when writing your own plugin.
At the end you will have the ability to create simple permissions for your plugins. You will have an example Tauri plugin where permissions are partially autogenerated and hand crafted.
-
Create a Tauri Plugin
In our example we will facilitate the Tauri
clito bootstrap a Tauri plugin source code structure. Make sure you have installed all Prerequisites and verify you have the Tauri CLI in the correct version by runningcargo tauri info.The output should indicate the
tauri-cliversion is2.x. We will proceed in this step-by-step explanation withpnpmbut you can choose another package manager and replace it in the commands accordingly.Once you have a recent version installed you can go ahead and create the plugin using the Tauri CLI.
Show solution
mkdir -p tauri-learning cd tauri-learning cargo tauri plugin new test cd tauri-plugin-test pnpm install pnpm build cargo build -
Create a New Command
To showcase something practical and simple let us assume our command writes user input to a file in our temporary folder while adding some custom header to the file.
Let’s name our command
write_custom_file, implement it insrc/commands.rsand add it to our plugin builder to be exposed to the frontend.Tauri’s core utils will autogenerate
allowanddenypermissions for this command, so we do not need to care about this.Show solution
The command implementation:
src/commands.rs
use tauri::{AppHandle, command, Runtime}; use crate::models::*; use crate::Result; use crate::TestExt; #[command] pub(crate) async fn ping<R: Runtime>( app: AppHandle<R>, payload: PingRequest, ) -> Result<PingResponse> { app.test1().ping(payload) } +#[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()) +}Auto-Generate inbuilt permissions for your new command:
src/build.rs
const COMMANDS: &[&str] = &["ping", "write_custom_file"];These inbuilt permissions will be automatically generated by the Tauri build system and will be visible in the
permissions/autogenerated/commandsfolder. By default anenable-<command>anddeny-<command>permission will be created. -
Expose the New Command
The previous step was to write the actual command implementation. Next we want to expose it to the frontend so it can be consumed.
Show solution
Configure the Tauri builder to generate the invoke handler to pass frontend IPC requests to the newly implemented command:
src/lib.rs
pub fn init<R: Runtime>() -> TauriPlugin<R> { Builder::new("test") .invoke_handler(tauri::generate_handler![ commands::ping, commands::write_custom_file, ]) .setup(|app, api| { #[cfg(mobile)] let test = mobile::init(app, api)?; #[cfg(desktop)] let test = desktop::init(app, api)?; app.manage(test); // manage state so it is accessible by the commands app.manage(MyState::default()); Ok(()) }) .build() }Expose the new command in the frontend module.
This step is essential for the example application to successfully import the frontend module. This is for convenience and has no security impact, as the command handler is already generated and the command can be manually invoked from the frontend.
guest-js/index.ts
import { invoke } from '@tauri-apps/api/core' export async function ping(value: string): Promise<string | null> { return await invoke<{value?: string}>('plugin:test|ping', { payload: { value, }, }).then((r) => (r.value ? r.value : null)); } +export async function writeCustomFile(user_input: string): Promise<string> { +return await invoke('plugin:test|write_custom_file',{userInput: user_input}); +}Tip
The invoke parameter needs to be CamelCase. In this example it is
userInputinstead ofuser_input.Make sure your package is built:
pnpm build -
Define Default Plugin Permissions
As our plugin should expose the
write_custom_filecommand by default we should add this to ourdefault.tomlpermission.Show solution
Add this to our default permission set to allow the new command we just exposed.
permissions/default.toml
"$schema" = "schemas/schema.json" [default] description = "Default permissions for the plugin" permissions = ["allow-ping", "allow-write-custom-file"] -
Invoke Test Command from Example Application
The created plugin directory structure contains an
examples/tauri-appfolder, which has a ready to use Tauri application to test out the plugin.Since we added a new command we need to slightly modify the frontend to invoke our new command instead.
Show solution
src/App.svelte
<script> import Greet from './lib/Greet.svelte' import { ping, writeCustomFile } from 'tauri-plugin-test-api' let response = '' function updateResponse(returnValue) { response += `[${new Date().toLocaleTimeString()}]` + (typeof returnValue === 'string' ? returnValue : JSON.stringify(returnValue)) + '<br>' } -function _ping() { -ping("Pong!").then(updateResponse).catch(updateResponse) - } +function _writeCustomFile() { +writeCustomFile("HELLO FROM TAURI PLUGIN").then(updateResponse).catch(updateResponse) + } </script> <main class="container"> <h1>Welcome to Tauri!</h1> <div class="row"> <a href="https://vitejs.dev" target="_blank"> <img src="/vite.svg" class="logo vite" alt="Vite Logo" /> </a> <a href="https://tauri.app" target="_blank"> <img src="/tauri.svg" class="logo tauri" alt="Tauri Logo" /> </a> <a href="https://svelte.dev" target="_blank"> <img src="/svelte.svg" class="logo svelte" alt="Svelte Logo" /> </a> </div> <p> Click on the Tauri, Vite, and Svelte logos to learn more. </p> <div class="row"> <Greet /> </div> <div> <button on:click="{_ping}">Ping</button> <div>{@html response}</div> </div> <div> <button on:click="{_writeCustomFile}">Write</button> <div>{@html response}</div> </div> </main> <style> .logo.vite:hover { filter: drop-shadow(0 0 2em #747bff); } .logo.svelte:hover { filter: drop-shadow(0 0 2em #ff3e00); } </style>Running this and pressing the “Write” button you should be greeted with this:
successAnd you should find a
test.txtfile in your temporary folder containing a message from our new implemented plugin command. 🥳
Node.js as a sidecar
In this guide we are going to package a Node.js application to a self contained binary to be used as a sidecar in a Tauri application without requiring the end user to have a Node.js installation. This example tutorial is applicable for desktop operating systems only.
We recommend reading the general sidecar guide first for a deeper understanding of how Tauri sidecars work.
Goals
- Package a Node.js application as a binary.
- Integrate this binary as a Tauri sidecar.
Implementation Details
- For this we use the pkg tool, but any other tool that can compile JavaScript or Typescript into a binary application will work.
- You can also embed the Node runtime itself into your Tauri application and ship bundled JavaScript as a resource, but this will ship the JavaScript content as readable-ish files and the runtime is usually larger than a
pkgpackaged application.
In this example we will create a Node.js application that reads input from the command line process.argv and writes output to stdout using console.log.
You can leverage alternative inter-process communication systems such as a localhost server, stdin/stdout or local sockets. Note that each has their own advantages, drawbacks and security concerns.
Prerequisites
An existing Tauri application set up with the shell plugin, that compiles and runs for you locally.
Create a lab app
If you are not an advanced user it’s highly recommended that you use the options and frameworks provided here. It’s just a lab, you can delete the project when you’re done.
-
Bash
sh <(curl https://create.tauri.app/sh) -
PowerShell
irm https://create.tauri.app/ps | iex -
Fish
sh (curl -sSL https://create.tauri.app/sh | psub) -
npm
npm create tauri-app@latest -
Yarn
yarn create tauri-app -
pnpm
pnpm create tauri-app -
deno
deno run -A npm:create-tauri-app -
bun
bun create tauri-app -
Cargo
cargo install create-tauri-app --locked cargo create-tauri-app
- Project name:
node-sidecar-lab - Choose which language to use for your frontend:
Typescript / Javascript - Choose your package manager:
pnpm - Choose your UI template:
Vanilla - Choose your UI flavor:
Typescript
Note
Please follow the shell plugin guide first to set up and initialize the plugin correctly. Without the plugin being initialized and configured the example won’t work.
Guide
-
Initialize Sidecar Project
Let’s create a new Node.js project to contain our sidecar implementation. Create a new directory in your Tauri application root folder (in this example we will call it
sidecar-app) and run theinitcommand of your preferred Node.js package manager inside the directory:-
npm
npm init -
yarn
yarn init -
pnpm
pnpm init
We will compile our Node.js application to a self container binary using pkg among other options. Let’s install it as a development dependency into the new
sidecar-app:-
npm
npm add @yao-pkg/pkg --save-dev -
yarn
yarn add @yao-pkg/pkg --dev -
pnpm
pnpm add @yao-pkg/pkg --save-dev
-
-
Write Sidecar Logic
Now we can start writing JavaScript code that will be executed by our Tauri application.
In this example we will process a command from the command line argmuents and write output to stdout, which means our process will be short lived and only handle a single command at a time. If your application must be long lived, consider using alternative inter-process communication systems.
Let’s create a
index.jsfile in oursidecar-appdirectory and write a basic Node.js app:sidecar-app/index.js
const command = process.argv[2]; switch (command) { case 'hello': const message = process.argv[3]; console.log(`Hello ${message}!`); break; default: console.error(`unknown command ${command}`); process.exit(1); } -
Package the Sidecar
To package our Node.js application into a self contained binary, create a script in
package.json:sidecar-app/package.json
{ "scripts": { "build": "pkg index.ts --output my-sidecar" } }-
npm
npm run build -
yarn
yarn build -
pnpm
pnpm build
This will create the
sidecar-app/my-sidecarbinary on Linux and macOS, and asidecar-app/my-sidecar.exeexecutable on Windows.For sidecar applications, we need to ensure that the binary is named in the correct pattern, for more information read Embedding External Binaries To rename this file to the expected Tauri sidecar filename and also move to our Tauri project, we can use the following Node.js script as a starting example:
sidecar-app/rename.js
import { execSync } from 'child_process'; import fs from 'fs'; const ext = process.platform === 'win32' ? '.exe' : ''; const targetTriple = execSync('rustc --print host-tuple').toString().trim(); if (!targetTriple) { console.error('Failed to determine platform target triple'); } // TODO: create `src-tauri/binaries` dir fs.renameSync( `my-sidecar${ext}`, `../src-tauri/binaries/my-sidecar-${targetTriple}${ext}` );Note
The
--print host-tupleflag was added in Rust 1.84.0. If you’re using an older version, you’ll need to parse the output ofrustc -Vvinstead:const rustInfo = execSync('rustc -vV'); const targetTriple = /host: (\S+)/g.exec(rustInfo)[1];And run
node rename.jsfrom thesidecar-appdirectory.At this step the
/src-tauri/binariesdirectory should contain the renamed sidecar binary. -
-
Setup plugin-shell permission
After installing the shell plugin make sure you configure the required capabilities.
Note that we use
"args": truebut you can optionally provide an array["hello"], read more.src-tauri/capabilities/default.json
{ "permissions": [ "core:default", "opener:default", { "identifier": "shell:allow-execute", "allow": [ { "args": true, "name": "binaries/my-sidecar", "sidecar": true } ] } ] } -
Configure the Sidecar in the Tauri Application
Now that we have our Node.js application ready, we can connect it to our Tauri application by configuring the
bundle > externalBinarray:src-tauri/tauri.conf.json
{ "bundle": { "externalBin": ["binaries/my-sidecar"] } }The Tauri CLI will handle the bundling of the sidecar binary as long as it exists as
src-tauri/binaries/my-sidecar-<target-triple>. -
Execute the Sidecar
We can run the sidecar binary either from Rust code or directly from JavaScript.
-
JavaScript
Let’s execute the
hellocommand in the Node.js sidecar directly:import { Command } from '@tauri-apps/plugin-shell'; const message = 'Tauri'; const command = Command.sidecar('binaries/my-sidecar', ['hello', message]); const output = await command.execute(); // once everything is configured it should log "Hello Tauri" in the browser console. console.log(output.stdout) -
Rust
Let’s pipe a
helloTauri command to the Node.js sidecar:use tauri_plugin_shell::ShellExt; #[tauri::command] async fn hello(app: tauri::AppHandle, cmd: String, message: String) -> String { let sidecar_command = app .shell() .sidecar("my-sidecar") .unwrap() .arg(cmd) .arg(message); let output = sidecar_command.output().await.unwrap(); String::from_utf8(output.stdout).unwrap() }Register it in
invoke_handlerand call it in the frontend with:import { invoke } from "@tauri-apps/api/core"; const message = "Tauri" console.log(await invoke("hello", { cmd: 'hello', message }))
-
-
Running
Lets test it
-
npm
npm run tauri dev -
yarn
yarn tauri dev -
pnpm
pnpm tauri dev -
deno
deno task tauri dev -
bun
bun tauri dev -
cargo
cargo tauri dev
Open the DevTools with F12 (or
Cmd+Option+Ion macOS) and you should see the output of the sidecar command.If you find any issues, please open an issue on GitHub.
-
Splashscreen
In this lab we’ll be implementing a basic splashscreen functionality in a Tauri app. Doing so is quite straight forward, a splashscreen is effectively just a matter of creating a new window that displays some contents during the period your app is doing some heavy setup related tasks and then closing it when setting up is done.
Prerequisites
Create a lab app
If you are not an advanced user it’s highly recommended that you use the options and frameworks provided here. It’s just a lab, you can delete the project when you’re done.
-
Bash
sh <(curl https://create.tauri.app/sh) -
PowerShell
irm https://create.tauri.app/ps | iex -
Fish
sh (curl -sSL https://create.tauri.app/sh | psub) -
npm
npm create tauri-app@latest -
Yarn
yarn create tauri-app -
pnpm
pnpm create tauri-app -
deno
deno run -A npm:create-tauri-app -
bun
bun create tauri-app -
Cargo
cargo install create-tauri-app --locked cargo create-tauri-app
- Project name:
splashscreen-lab - Choose which language to use for your frontend:
Typescript / Javascript - Choose your package manager:
pnpm - Choose your UI template:
Vanilla - Choose your UI flavor:
Typescript
Steps
-
Install dependencies and run the project
Before you start developing any project it’s important to build and run the initial template, just to validate your setup is working as intended.
Show solution
# Make sure you're in the right directory cd splashscreen-lab # Install dependencies pnpm install # Build and run the app pnpm tauri dev -
Register new windows in
tauri.conf.jsonThe easiest way of adding new windows is by adding them directly to
tauri.conf.json. You can also create them dynamically at startup, but for the sake of simplicity lets just register them instead. Make sure you have a window with the labelmainthat’s being created as a hidden window and a window with the labelsplashscreenthat’s created as being shown directly. You can leave all other options as their defaults, or tweak them based on preference.Show solution
src-tauri/tauri.conf.json
{ "windows": [ { "label": "main", "visible": false }, { "label": "splashscreen", "url": "/splashscreen" } ] } -
Create a new page to host your splashscreen
Before you begin you’ll need to have some content to show. How you develop new pages depend on your chosen framework, most have the concept of a “router” that handles page navigation which should work just like normal in Tauri, in which case you just create a new splashscreen page. Or as we’re going to be doing here, create a new
splashscreen.htmlfile to host the contents.What’s important here is that you can navigate to a
/splashscreenURL and be shown the contents you want for your splashscreen. Try running the app again after this step!Show solution
/splashscreen.html
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="stylesheet" href="/src/styles.css" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Tauri App</title> </head> <body> <div class="container"> <h1>Tauri used Splash!</h1> <div class="row"> <h5>It was super effective!</h5> </div> </div> </body> </html> -
Start some setup tasks
Since splashscreens are generally intended to be used for the sake of hiding heavy setup related tasks, lets fake giving the app something heavy to do, some in the frontend and some in the backend.
To fake heavy setup in the frontend we’re going to be using a simple
setTimeoutfunction.The easiest way to fake heavy operations in the backend is by using the Tokio crate, which is the Rust crate that Tauri uses in the backend to provide an asynchronous runtime. While Tauri provides the runtime there are various utilities that Tauri doesn’t re-export from it, so we’ll need to add the crate to our project in order to access them. This is a perfectly normal practice within the Rust ecosystem.
Don’t use
std::thread::sleepin async functions, they run cooperatively in a concurrent environment not in parallel, meaning that if you sleep the thread instead of the Tokio task you’ll be locking all tasks scheduled to run on that thread from being executed, causing your app to freeze.Show solution
# Run this command where the `Cargo.toml` file is cd src-tauri # Add the Tokio crate cargo add tokio -F time # Optionally go back to the top folder to keep developing # `tauri dev` can figure out where to run automatically cd ..src/main.ts
// These contents can be copy-pasted below the existing code, don't replace the entire file!! // Utility function to implement a sleep function in TypeScript function sleep(seconds: number): Promise<void> { return new Promise(resolve => setTimeout(resolve, seconds * 1000)); } // Setup function async function setup() { // Fake perform some really heavy setup task console.log('Performing really heavy frontend setup task...') await sleep(3); console.log('Frontend setup task complete!') // Set the frontend task as being completed invoke('set_complete', {task: 'frontend'}) } // Effectively a JavaScript main function window.addEventListener("DOMContentLoaded", () => { setup() });/src-tauri/src/lib.rs
// Import functionalities we'll be using use std::sync::Mutex; use tauri::async_runtime::spawn; use tauri::{AppHandle, Manager, State}; use tokio::time::{sleep, Duration}; // Create a struct we'll use to track the completion of // setup related tasks struct SetupState { frontend_task: bool, backend_task: bool, } // Our main entrypoint in a version 2 mobile compatible app #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { // Don't write code before Tauri starts, write it in the // setup hook instead! tauri::Builder::default() // Register a `State` to be managed by Tauri // We need write access to it so we wrap it in a `Mutex` .manage(Mutex::new(SetupState { frontend_task: false, backend_task: false, })) // Add a command we can use to check .invoke_handler(tauri::generate_handler![greet, set_complete]) // Use the setup hook to execute setup related tasks // Runs before the main loop, so no windows are yet created .setup(|app| { // Spawn setup as a non-blocking task so the windows can be // created and ran while it executes spawn(setup(app.handle().clone())); // The hook expects an Ok result Ok(()) }) // Run the app .run(tauri::generate_context!()) .expect("error while running tauri application"); } #[tauri::command] fn greet(name: String) -> String { format!("Hello {name} from Rust!") } // A custom task for setting the state of a setup task #[tauri::command] async fn set_complete( app: AppHandle, state: State<'_, Mutex<SetupState>>, task: String, ) -> Result<(), ()> { // Lock the state without write access let mut state_lock = state.lock().unwrap(); match task.as_str() { "frontend" => state_lock.frontend_task = true, "backend" => state_lock.backend_task = true, _ => panic!("invalid task completed!"), } // Check if both tasks are completed if state_lock.backend_task && state_lock.frontend_task { // Setup is complete, we can close the splashscreen // and unhide the main window! let splash_window = app.get_webview_window("splashscreen").unwrap(); let main_window = app.get_webview_window("main").unwrap(); splash_window.close().unwrap(); main_window.show().unwrap(); } Ok(()) } // An async function that does some heavy setup task async fn setup(app: AppHandle) -> Result<(), ()> { // Fake performing some heavy action for 3 seconds println!("Performing really heavy backend setup task..."); sleep(Duration::from_secs(3)).await; println!("Backend setup task completed!"); // Set the backend task as being completed // Commands can be ran as regular functions as long as you take // care of the input arguments yourself set_complete( app.clone(), app.state::<Mutex<SetupState>>(), "backend".to_string(), ) .await?; Ok(()) } -
Run the application
You should now see a splashscreen window pop up, both the frontend and backend will perform their respective heavy 3 second setup tasks, after which the splashscreen disappears and the main window is shown!
Discuss
Should you have a splashscreen?
In general having a splashscreen is an admittance of defeat that you couldn’t make your app load fast enough to not need one. In fact it tends to be better to just go straight to a main window that then shows some little spinner somewhere in a corner informing the user there’s still setup tasks happening in the background.
However, with that said, it can be a stylistic choice that you want to have a splashscreen, or you might have some very particular requirement that makes it impossible to start the app until some tasks are performed. It’s definitely not wrong to have a splashscreen, it just tends to not be necessary and can make users feel like the app isn’t very well optimized.
System Tray
Tauri allows you to create and customize a system tray for your application. This can enhance the user experience by providing quick access to common actions.
Configuration
First of all, update your Cargo.toml to include the necessary feature for the system tray.
src-tauri/Cargo.toml
tauri = { version = "2.0.0", features = [ "tray-icon" ] }
Usage
The tray API is available in both JavaScript and Rust.
Create a Tray Icon
-
JavaScript
Use the
TrayIcon.newstatic function to create a new tray icon:import { TrayIcon } from '@tauri-apps/api/tray'; const options = { // here you can add a tray menu, title, tooltip, event handler, etc }; const tray = await TrayIcon.new(options);See
TrayIconOptionsfor more information on the customization options. -
Rust
use tauri::tray::TrayIconBuilder; tauri::Builder::default() .setup(|app| { let tray = TrayIconBuilder::new().build(app)?; Ok(()) })See
TrayIconBuilderfor more information on customization options.
Change the Tray Icon
When creating the tray you can use the application icon as the tray icon:
-
JavaScript
import { TrayIcon } from '@tauri-apps/api/tray'; import { defaultWindowIcon } from '@tauri-apps/api/app'; const options = { icon: await defaultWindowIcon(), }; const tray = await TrayIcon.new(options); -
Rust
let tray = TrayIconBuilder::new() .icon(app.default_window_icon().unwrap().clone()) .build(app)?;
Add a Menu
To attach a menu that is displayed when the tray is clicked, you can use the menu option.
Note
By default the menu is displayed on both left and right clicks.
To prevent the menu from popping up on left click, call the show_menu_on_left_click(false) Rust function or set the menuOnLeftClick JavaScript option to false.
-
JavaScript
import { TrayIcon } from '@tauri-apps/api/tray'; import { Menu } from '@tauri-apps/api/menu'; const menu = await Menu.new({ items: [ { id: 'quit', text: 'Quit', }, ], }); const options = { menu, menuOnLeftClick: true, }; const tray = await TrayIcon.new(options); -
Rust
use tauri::{ menu::{Menu, MenuItem}, tray::TrayIconBuilder, }; let quit_i = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>)?; let menu = Menu::with_items(app, &[&quit_i])?; let tray = TrayIconBuilder::new() .menu(&menu) .show_menu_on_left_click(true) .build(app)?;
Listen to Menu Events
-
JavaScript
On JavaScript you can attach a menu click event listener directly to the menu item:
-
Using a shared menu click handler
import { Menu } from '@tauri-apps/api/menu'; function onTrayMenuClick(itemId) { // itemId === 'quit' } const menu = await Menu.new({ items: [ { id: 'quit', text: 'Quit', action: onTrayMenuClick, }, ], }); -
Using a dedicated menu click handler
import { Menu } from '@tauri-apps/api/menu'; const menu = await Menu.new({ items: [ { id: 'quit', text: 'Quit', action: () => { console.log('quit pressed'); }, }, ], });
-
-
Rust
Use the
TrayIconBuilder::on_menu_eventmethod to attach a tray menu click event listener:use tauri::tray::TrayIconBuilder; TrayIconBuilder::new() .on_menu_event(|app, event| match event.id.as_ref() { "quit" => { println!("quit menu item was clicked"); app.exit(0); } _ => { println!("menu item {:?} not handled", event.id); } })
Listen to Tray Events
The tray icon emits events for the following mouse events:
- click: triggered when the cursor receives a single left, right or middle click, including information on whether the mouse press was released or not
- Double click: triggered when the cursor receives a double left, right or middle click
- Enter: triggered when the cursor enters the tray icon area
- Move: triggered when the cursor moves around the tray icon area
- Leave: triggered when the cursor leaves the tray icon area
Note
Linux: Unsupported. The event is not emitted even though the icon is shown and will still show a context menu on right click.
-
JavaScript
import { TrayIcon } from '@tauri-apps/api/tray'; const options = { action: (event) => { switch (event.type) { case 'Click': console.log( `mouse ${event.button} button pressed, state: ${event.buttonState}` ); break; case 'DoubleClick': console.log(`mouse ${event.button} button pressed`); break; case 'Enter': console.log( `mouse hovered tray at ${event.rect.position.x}, ${event.rect.position.y}` ); break; case 'Move': console.log( `mouse moved on tray at ${event.rect.position.x}, ${event.rect.position.y}` ); break; case 'Leave': console.log( `mouse left tray at ${event.rect.position.x}, ${event.rect.position.y}` ); break; } }, }; const tray = await TrayIcon.new(options);See
TrayIconEventfor more information on the event payload. -
Rust
use tauri::{ Manager, tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent} }; TrayIconBuilder::new() .on_tray_icon_event(|tray, event| match event { TrayIconEvent::Click { button: MouseButton::Left, button_state: MouseButtonState::Up, .. } => { println!("left click pressed and released"); // in this example, let's show and focus the main window when the tray is clicked let app = tray.app_handle(); if let Some(window) = app.get_webview_window("main") { let _ = window.unminimize(); let _ = window.show(); let _ = window.set_focus(); } } _ => { println!("unhandled event {event:?}"); } })See
TrayIconEventfor more information on the event type.
For detailed information about creating menus, including menu items, submenus, and dynamic updates, see the Window Menu documentation.
Window Customization
Tauri provides lots of options for customizing the look and feel of your app’s window. You can create custom titlebars, have transparent windows, enforce size constraints, and more.
Configuration
There are three ways to change the window configuration:
Usage
Creating a Custom Titlebar
A common use of these window features is creating a custom titlebar. This short tutorial will guide you through that process.
Note
For macOS, using a custom titlebar will also lose some features provided by the system, such as moving or aligning the window. Another approach to customizing the titlebar but keeping native functions could be making the titlebar transparent and setting the window background color. See the usage (macOS) Transparent Titlebar with Custom Window Background Color.
tauri.conf.json
Set decorations to false in your tauri.conf.json:
tauri.conf.json
"tauri": {
"windows": [
{
"decorations": false
}
]
}
Permissions
Add window permissions in capability file.
By default, all plugin commands are blocked and cannot be accessed. You must define a list of permissions in your capabilities configuration.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
+"core:window:default",
+"core:window:allow-close",
+"core:window:allow-minimize",
+"core:window:allow-toggle-maximize",
+"core:window:allow-start-dragging"
]
}
| Permission | Description |
|---|---|
core:window:default |
Default permissions for the plugin. This includes core:window:allow-internal-toggle-maximize. |
core:window:allow-close |
Enables the close command without any pre-configured scope. |
core:window:allow-minimize |
Enables the minimize command without any pre-configured scope. |
core:window:allow-start-dragging |
Enables the start_dragging command without any pre-configured scope. |
core:window:allow-toggle-maximize |
Enables the toggle_maximize command without any pre-configured scope. |
core:window:allow-internal-toggle-maximize |
Enables the internal_toggle_maximize command without any pre-configured scope. |
CSS
Add this CSS sample to keep it at the top of the screen and style the buttons:
.titlebar {
height: 30px;
background: #329ea3;
user-select: none;
display: grid;
grid-template-columns: auto max-content;
position: fixed;
top: 0;
left: 0;
right: 0;
}
.titlebar > .controls {
display: flex;
}
.titlebar button {
appearance: none;
padding: 0;
margin: 0;
border: none;
display: inline-flex;
justify-content: center;
align-items: center;
width: 30px;
background-color: transparent;
}
.titlebar button:hover {
background: #5bbec3;
}
HTML
Put this at the top of your <body> tag:
<div class="titlebar">
<div data-tauri-drag-region></div>
<div class="controls">
<button id="titlebar-minimize" title="minimize">
<!-- https://api.iconify.design/mdi:window-minimize.svg -->
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
>
<path fill="currentColor" d="M19 13H5v-2h14z" />
</svg>
</button>
<button id="titlebar-maximize" title="maximize">
<!-- https://api.iconify.design/mdi:window-maximize.svg -->
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
>
<path fill="currentColor" d="M4 4h16v16H4zm2 4v10h12V8z" />
</svg>
</button>
<button id="titlebar-close" title="close">
<!-- https://api.iconify.design/mdi:close.svg -->
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="M13.46 12L19 17.54V19h-1.46L12 13.46L6.46 19H5v-1.46L10.54 12L5 6.46V5h1.46L12 10.54L17.54 5H19v1.46z"
/>
</svg>
</button>
</div>
</div>
Note that you may need to move the rest of your content down so that the titlebar doesn’t cover it.
Tip
On Windows, if you just want a title bar that doesn’t need custom interactions, you can use
*[data-tauri-drag-region] {
app-region: drag;
}
to make the title bar work with touch and pen inputs
JavaScript
Use this code snippet to make the buttons work:
import { getCurrentWindow } from '@tauri-apps/api/window';
// when using `"withGlobalTauri": true`, you may use
// const { getCurrentWindow } = window.__TAURI__.window;
const appWindow = getCurrentWindow();
document
.getElementById('titlebar-minimize')
?.addEventListener('click', () => appWindow.minimize());
document
.getElementById('titlebar-maximize')
?.addEventListener('click', () => appWindow.toggleMaximize());
document
.getElementById('titlebar-close')
?.addEventListener('click', () => appWindow.close());
Note that if you are using a Rust-based frontend, you can copy the code above into a <script> element in your index.html file.
Note
data-tauri-drag-region will only work on the element to which it is directly applied. If you want the drag behavior to apply to child elements as well, you’ll need to add it to each child individually.
This behavior is preserved so that interactive elements like buttons and inputs can function properly.
Manual Implementation of data-tauri-drag-region
For use cases where you customize the drag behavior, you can manually add an event listener with window.startDragging instead of using data-tauri-drag-region.
HTML
From the code in the previous section, we remove data-tauri-drag-region and add an id:
<div data-tauri-drag-region class="titlebar">
<div id="titlebar" class="titlebar">
<!-- ... -->
</div>
</div>
Javascript
Add an event listener to the titlebar element:
// ...
document.getElementById('titlebar')?.addEventListener('mousedown', (e) => {
if (e.buttons === 1) {
// Primary (left) button
e.detail === 2
? appWindow.toggleMaximize() // Maximize on double click
: appWindow.startDragging(); // Else start dragging
}
});
(macOS) Transparent Titlebar with Custom Window Background Color
We are going to create the main window and change its background color from the Rust side.
Remove the main window from the tauri.conf.json file:
tauri.conf.json
"tauri": {
"windows": [
- {
-"title": "Transparent Titlebar Window",
-"width": 800,
-"height": 600
- }
],
}
Add cocoa crate to dependencies so that we can use it to call the macOS native API:
src-tauri/Cargo.toml
[target."cfg(target_os = \"macos\")".dependencies]
objc2-app-kit = { version = "0.3.2", features = ["NSColor", "NSWindow", "objc2-core-foundation"] }
Create the main window and change its background color:
src-tauri/src/lib.rs
use tauri::{TitleBarStyle, WebviewUrl, WebviewWindowBuilder};
pub fn run() {
tauri::Builder::default()
.setup(|app| {
let win_builder =
WebviewWindowBuilder::new(app, "main", WebviewUrl::default())
.title("Transparent Titlebar Window")
.inner_size(800.0, 600.0);
// set transparent title bar only when building for macOS
#[cfg(target_os = "macos")]
let win_builder = win_builder.title_bar_style(TitleBarStyle::Transparent);
let window = win_builder.build().unwrap();
// set background color only when building for macOS
#[cfg(target_os = "macos")]
{
use objc2_app_kit::{NSColor, NSWindow};
let ns_window_ptr = window.ns_window().unwrap() as *mut NSWindow;
let ns_window = unsafe { &*ns_window_ptr };
let bg_color = NSColor::colorWithRed_green_blue_alpha(
50.0 / 255.0,
158.0 / 255.0,
163.5 / 255.0,
1.0,
);
ns_window.setBackgroundColor(Some(&bg_color));
}
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Window Menu
Native application menus can be attached to both to a window or system tray. Available on desktop.
Creating a base-level menu
To create a base-level native window menu, and attach to a window. You can create various types of menu items including basic items, check items, and separators:
-
JavaScript
Use the
Menu.newstatic function to create a window menu:import { Menu } from '@tauri-apps/api/menu'; const menu = await Menu.new({ items: [ { id: 'quit', text: 'Quit', action: () => { console.log('quit pressed'); }, }, { id: 'check_item', text: 'Check Item', checked: true, }, { item: 'Separator', }, { id: 'disabled_item', text: 'Disabled Item', enabled: false, }, { id: 'status', text: 'Status: Processing...', }, ], }); // If a window was not created with an explicit menu or had one set explicitly, // this menu will be assigned to it. menu.setAsAppMenu().then(async (res) => { console.log('menu set success', res); // Update individual menu item text const statusItem = await menu.get('status'); if (statusItem) { await statusItem.setText('Status: Ready'); } }); -
Rust
use tauri::menu::MenuBuilder; fn main() { tauri::Builder::default() .setup(|app| { let menu = MenuBuilder::new(app) .text("open", "Open") .text("close", "Close") .check("check_item", "Check Item") .separator() .text("disabled_item", "Disabled Item") .text("status", "Status: Processing...") .build()?; app.set_menu(menu.clone())?; // Update individual menu item text menu .get("status") .unwrap() .as_menuitem_unchecked() .set_text("Status: Ready")?; Ok(()) }) .run(tauri::generate_context!()); }
Listening to events on custom menu items
Each custom menu item triggers an event when clicked. Use the on_menu_event API to handle them.
-
JavaScript
import { Menu } from '@tauri-apps/api/menu'; const menu = await Menu.new({ items: [ { id: 'Open', text: 'open', action: () => { console.log('open pressed'); }, }, { id: 'Close', text: 'close', action: () => { console.log('close pressed'); }, }, ], }); await menu.setAsAppMenu(); -
Rust
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] use tauri::menu::{MenuBuilder}; fn main() { tauri::Builder::default() .setup(|app| { let menu = MenuBuilder::new(app) .text("open", "Open") .text("close", "Close") .build()?; app.set_menu(menu)?; app.on_menu_event(move |app_handle: &tauri::AppHandle, event| { println!("menu event: {:?}", event.id()); match event.id().0.as_str() { "open" => { println!("open event"); } "close" => { println!("close event"); } _ => { println!("unexpected menu event"); } } }); Ok(()) }) }
Creating a multi-level menu
Multi-level menus allow you to group menu items under categories like “File,” “Edit,” etc. These will appear as part of the application window for Windows or Linux, or in the menu bar on MacOS.
Note: When using submenus on MacOS, all items must be grouped under a submenu. Top-level items will be ignored. Additionally, the first submenu will be placed under the application’s about menu by default, regardless of the text label. You should include a submenu as the first entry (say, an “About” submenu) to fill this space.
Note
Icon support for submenus is available since Tauri 2.8.0.
-
JavaScript
import { Menu, MenuItem, Submenu } from '@tauri-apps/api/menu'; // Will become the application submenu on MacOS const aboutSubmenu = await Submenu.new({ text: 'About', items: [ await MenuItem.new({ id: 'quit', text: 'Quit', action: () => { console.log('Quit pressed'); }, }), ], }); const fileSubmenu = await Submenu.new({ text: 'File', icon: 'folder', // Optional: Add an icon to the submenu items: [ await MenuItem.new({ id: 'new', text: 'New', action: () => { console.log('New clicked'); }, }), await MenuItem.new({ id: 'open', text: 'Open', action: () => { console.log('Open clicked'); }, }), await MenuItem.new({ id: 'save_as', text: 'Save As...', action: () => { console.log('Save As clicked'); }, }), ], }); const editSubmenu = await Submenu.new({ text: 'Edit', items: [ await MenuItem.new({ id: 'undo', text: 'Undo', action: () => { console.log('Undo clicked'); }, }), await MenuItem.new({ id: 'redo', text: 'Redo', action: () => { console.log('Redo clicked'); }, }), ], }); const menu = await Menu.new({ items: [aboutSubmenu, fileSubmenu, editSubmenu], }); menu.setAsAppMenu(); // You can also update the submenu icon dynamically fileSubmenu.setIcon('document'); // Or set a native icon (only one type applies per platform) fileSubmenu.setNativeIcon('NSFolder'); -
Rust
use tauri::{ image::Image, menu::{CheckMenuItemBuilder, IconMenuItemBuilder, MenuBuilder, SubmenuBuilder}, }; fn main() { tauri::Builder::default() .setup(|app| { let menu_image = Image::from_bytes(include_bytes!("../icons/menu.png")).unwrap(); let file_menu = SubmenuBuilder::new(app, "File") .submenu_icon(menu_image) // Optional: Add an icon to the submenu .text("open", "Open") .text("quit", "Quit") .build()?; let lang_str = "en"; let check_sub_item_1 = CheckMenuItemBuilder::new("English") .id("en") .checked(lang_str == "en") .build(app)?; let check_sub_item_2 = CheckMenuItemBuilder::new("Chinese") .id("zh") .checked(lang_str == "zh") .enabled(false) .build(app)?; // Load icon from path let icon_image = Image::from_bytes(include_bytes!("../icons/icon.png")).unwrap(); let icon_item = IconMenuItemBuilder::new("icon") .icon(icon_image) .build(app)?; let other_item = SubmenuBuilder::new(app, "language") .item(&check_sub_item_1) .item(&check_sub_item_2) .build()?; let menu = MenuBuilder::new(app) .items(&[&file_menu, &other_item, &icon_item]) .build()?; app.set_menu(menu)?; let menu_image_update = Image::from_bytes(include_bytes!("../icons/menu_update.png")).unwrap(); // You can also update the submenu icon dynamically file_menu.set_icon(Some(menu_image_update))?; // Or set a native icon (only one type applies per platform) file_menu.set_native_icon(Some(tauri::menu::NativeIcon::Folder))?; Ok(()) }) .run(tauri::generate_context!()); }Note that you need to enable
image-icoorimage-pngfeature to use this API:src-tauri/Cargo.toml
[dependencies] tauri = { version = "...", features = ["...", "image-png"] }
Creating predefined menu
To use built-in (native) menu items that has predefined behavior by the operating system or Tauri:
-
JavaScript
import { Menu, PredefinedMenuItem } from '@tauri-apps/api/menu'; const copy = await PredefinedMenuItem.new({ text: 'copy-text', item: 'Copy', }); const separator = await PredefinedMenuItem.new({ text: 'separator-text', item: 'Separator', }); const undo = await PredefinedMenuItem.new({ text: 'undo-text', item: 'Undo', }); const redo = await PredefinedMenuItem.new({ text: 'redo-text', item: 'Redo', }); const cut = await PredefinedMenuItem.new({ text: 'cut-text', item: 'Cut', }); const paste = await PredefinedMenuItem.new({ text: 'paste-text', item: 'Paste', }); const select_all = await PredefinedMenuItem.new({ text: 'select_all-text', item: 'SelectAll', }); const menu = await Menu.new({ items: [copy, separator, undo, redo, cut, paste, select_all], }); await menu.setAsAppMenu(); -
Rust
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] use tauri::menu::{MenuBuilder, PredefinedMenuItem}; fn main() { tauri::Builder::default() .setup(|app| { let menu = MenuBuilder::new(app) .copy() .separator() .undo() .redo() .cut() .paste() .select_all() .item(&PredefinedMenuItem::copy(app, Some("custom text"))?) .build()?; app.set_menu(menu)?; Ok(()) }) }For more preset capabilities, please refer to the documentation
PredefinedMenuItem.Tip
The menu builder has dedicated methods to add each predefined menu item so you can call
.copy()instead of.item(&PredefinedMenuItem::copy(app, None)?).
Change menu status
If you want to change the status of the menu, such as text, icon, or check status, you can set_menu again:
-
JavaScript
import { Menu, CheckMenuItem, IconMenuItem, MenuItem, } from '@tauri-apps/api/menu'; import { Image } from '@tauri-apps/api/image'; let currentLanguage = 'en'; const check_sub_item_en = await CheckMenuItem.new({ id: 'en', text: 'English', checked: currentLanguage === 'en', action: () => { currentLanguage = 'en'; check_sub_item_en.setChecked(currentLanguage === 'en'); check_sub_item_zh.setChecked(currentLanguage === 'cn'); console.log('English pressed'); }, }); const check_sub_item_zh = await CheckMenuItem.new({ id: 'zh', text: 'Chinese', checked: currentLanguage === 'zh', action: () => { currentLanguage = 'zh'; check_sub_item_en.setChecked(currentLanguage === 'en'); check_sub_item_zh.setChecked(currentLanguage === 'zh'); check_sub_item_zh.setAccelerator('Ctrl+L'); console.log('Chinese pressed'); }, }); // Load icon from path const icon = await Image.fromPath('../src/icon.png'); const icon2 = await Image.fromPath('../src/icon-2.png'); const icon_item = await IconMenuItem.new({ id: 'icon_item', text: 'Icon Item', icon: icon, action: () => { icon_item.setIcon(icon2); console.log('icon pressed'); }, }); const text_item = await MenuItem.new({ id: 'text_item', text: 'Text Item', action: () => { text_item.setText('Text Item Changed'); console.log('text pressed'); }, }); const menu = await Menu.new({ items: [ { id: 'change menu', text: 'change_menu', items: [text_item, check_sub_item_en, check_sub_item_zh, icon_item], }, ], }); await menu.setAsAppMenu(); -
Rust
// change-menu-status #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] use tauri::{ image::Image, menu::{CheckMenuItemBuilder, IconMenuItem, MenuBuilder, MenuItem, SubmenuBuilder}, }; fn main() { tauri::Builder::default() .setup(|app| { let check_sub_item_en = CheckMenuItemBuilder::with_id("en", "EN") .checked(true) .build(app)?; let check_sub_item_zh = CheckMenuItemBuilder::with_id("zh", "ZH") .checked(false) .build(app)?; let text_menu = MenuItem::with_id( app, "change_text", &"Change menu".to_string(), true, Some("Ctrl+Z"), ) .unwrap(); let icon_menu = IconMenuItem::with_id( app, "change_icon", &"Change icon menu", true, Some(Image::from_bytes(include_bytes!("../icons/icon.png")).unwrap()), Some("Ctrl+F"), ) .unwrap(); let menu_item = SubmenuBuilder::new(app, "Change menu") .item(&text_menu) .item(&icon_menu) .items(&[&check_sub_item_en, &check_sub_item_zh]) .build()?; let menu = MenuBuilder::new(app).items(&[&menu_item]).build()?; app.set_menu(menu)?; app.on_menu_event(move |_app_handle: &tauri::AppHandle, event| { match event.id().0.as_str() { "change_text" => { text_menu .set_text("changed menu text") .expect("Change text error"); text_menu .set_text("changed menu text") .expect("Change text error"); } "change_icon" => { icon_menu .set_text("changed menu-icon text") .expect("Change text error"); icon_menu .set_icon(Some( Image::from_bytes(include_bytes!("../icons/icon-2.png")).unwrap(), )) .expect("Change icon error"); } "en" | "zh" => { check_sub_item_en .set_checked(event.id().0.as_str() == "en") .expect("Change check error"); check_sub_item_zh .set_checked(event.id().0.as_str() == "zh") .expect("Change check error"); check_sub_item_zh.set_accelerator(Some("Ctrl+L")) .expect("Change accelerator error"); } _ => { println!("unexpected menu event"); } } }); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
Features & Recipes
Information on the extensibility of Tauri from built-in Tauri features and functionality to provided plugins and recipes built by the Tauri community
Tauri comes with extensibility in mind. On this page you’ll find:
- Official Features: Built-in Tauri features and functionality
- Community Resources: More plugins and recipes built by the Tauri community. You can also contribute your own on Awesome Tauri
- Support Table: A compatibility table showing which platforms are supported by each official plugin
Use the search and filter functionality to find features or community resources:
Official Features
Automatically launch your app at system startup.
Allows your mobile application to use the camera to scan QR codes, EAN-13 and other types of barcodes.
Prompt the user for biometric authentication on Android and iOS.
Read and write to the system clipboard.
Parse arguments from the command line interface.
Set your Tauri application as the default handler for an URL.
Native system dialogs for opening and saving files along with message dialogs.
Access the file system.
Get and track the device's current position, including information about altitude, heading, and speed (if available).
Register global shortcuts.
Haptic feedback and vibrations on Android and iOS
Access the HTTP client written in Rust.
Use a localhost server in production apps.
Configurable logging.
Read and write NFC tags on Android and iOS.
Send native notifications to the user.
Open files and URLs in external applications.
Read information about the operating system.
Persist runtime scope changes on the filesystem.
Move windows to common locations.
Access the current process.
Access the system shell to spawn child processes.
Ensure that a single instance of your Tauri app is running at a time.
Tauri Plugin providing an interface for the frontend to communicate with SQL databases through sqlx.
Persistent key value storage.
Encrypted, secure database.
In-app updates for Tauri applications.
File uploads through HTTP.
Open a WebSocket connection using a Rust client in JavaScript.
Persist window sizes and positions.
Community Plugins
sentry-tauriCapture JavaScript errors, Rust panics and native crash minidumps to Sentry.
tauri-awesome-rpcCustom invoke system that leverages WebSocket.
tauri-nspanelConvert a window to panel.
tauri-nspopover-pluginNative NSPopover view for use in the status bar in macOS.
tauri-plugin-android-battery-optimizationCheck and request battery optimization exemptions on Android.
tauri-plugin-android-fsAccess the file system on Android.
tauri-plugin-aptabasePrivacy-first and minimalist analytics for desktop and mobile apps.
tauri-plugin-authAuth plugin for iOS that uses ASWebAuthenticationSession for authentication, which allows keychain access
tauri-plugin-blecCross platform Bluetooth Low Energy client based on btleplug.
tauri-plugin-cacheAdvanced disk caching solution with memory layer, TTL management, compression support, and cross-platform compatibility for desktop and mobile.
tauri-plugin-clipboardClipboard plugin for reading/writing clipboard text/image/html/rtf/files, and monitoring clipboard update.
tauri-plugin-context-menuNative context menu.
tauri-plugin-desktop-underlayAttach a window to desktop, below icons and above wallpaper.
tauri-plugin-device-infoAccess comprehensive device information including battery, network, storage, display, and system details across desktop and mobile.
tauri-plugin-dragoutNative macOS drag-out (file promise) support.
tauri-plugin-drpcDiscord RPC support.
tauri-plugin-fs-proExtended with additional methods for files and directories.
tauri-plugin-graphqlType-safe IPC for Tauri using GraphQL.
tauri-plugin-iapPlugin that enables full In-App Purchases flow for Android, macOS, iOS and Windows.
tauri-plugin-iapIn-app-purchase plugin for iOS that allows fetching, purchasing, and restoring of products.
tauri-plugin-in-app-reviewIn-app app rating prompts using native platform APIs.
tauri-plugin-ios-photosiOS Photos album and asset management via native APIs.
tauri-plugin-jsGive your app Electron-like JS backends with type-safe RPC powered by kkrpc. Supports Bun, Node.js, and Deno.
tauri-plugin-keep-screen-onDisable screen timeout on Android and iOS.
tauri-plugin-macos-permissionsSupport for checking and requesting macOS system permissions.
tauri-plugin-mobile-sharetargetHandle mobile Share Intents with a FIFO queue
tauri-plugin-mqttMQTT client support.
tauri-plugin-networkTools for reading network information and scanning network.
tauri-plugin-nosleepBlock the power save functionality in the OS.
tauri-plugin-otaOTA plugin for applications that just want to continuously deliever new JavaScript code based on a manfiest.
tauri-plugin-piniaPersistent Pinia stores for Vue.
tauri-plugin-prevent-defaultDisable default browser shortcuts.
tauri-plugin-pythonUse python in your backend.
tauri-plugin-screenshotsGet screenshots of windows and monitors.
tauri-plugin-serialportCross-compatible serialport communication tool.
tauri-plugin-serialpluginCross-compatible serialport communication tool for tauri 2.
tauri-plugin-sharesheetShare content to other apps via the Android Sharesheet or iOS Share Pane.
tauri-plugin-sveltePersistent Svelte stores.
tauri-plugin-system-infoDetailed system information.
tauri-plugin-tcpTCP socket support.
tauri-plugin-themeDynamically change Tauri App theme.
tauri-plugin-thermal-printerAdd support to handle thermal printers.
tauri-plugin-tracingStructured logging with the tracing crate, featuring JS-to-Rust log bridging, file rotation, and flamegraph profiling.
tauri-plugin-udpUDP socket support.
tauri-plugin-velesdbNative vector database plugin. 70µs semantic search, ≥95% recall, hybrid BM25+vector, offline-first, full ecosystem integrations and more.
tauri-plugin-viewView and share files on mobile.
tauri-remote-uiMake you web app bundle available as web page for test and development.
taurpcTypesafe IPC wrapper for Tauri commands and events.
Community Integrations
AstrodonMake Tauri desktop apps with Deno.
axios-tauri-adapteraxios adapter for the @tauri-apps/api/http module.
axios-tauri-api-adapterMakes it easy to use Axios in Tauri, axios adapter for the @tauri-apps/api/http module.
Deno in TauriRun JS/TS code with Deno Core Engine, in Tauri apps.
faynosync-update-serverSelf-hosted Dynamic Update Server with statistics, supporting Tauri and other platforms. Flexible features for seamless app updates and insights.
kkrpcSeamless RPC communication between a Tauri app and node/deno/bun processes, just like Electron.
ngx-tauriSmall lib to wrap around functions from tauri modules, to integrate easier with Angular.
svelte-tauri-filedropFile drop handling component for Svelte.
Tauri SpectaCompletely typesafe Tauri commands.
tauri-htmx-extensionExtention for using htmx with Tauri apis.
tauri-macos-menubar-app-exampleExample macOS Menubar app project.
tauri-macos-spotlight-exampleExample macOS Spotlight app project.
tauri-mcp-serverMCP server and plugin for rapid development and debugging.
tauri-update-cloudflareOne-click deploy a Tauri Update Server to Cloudflare.
tauri-update-serverAutomatically interface the Tauri updater with git repository releases.
vite-plugin-tauriIntegrate Tauri in a Vite project to build cross-platform apps.
Support Table
Hover “*” to see notes. For more details visit the plugin page
| Plugin | Rust Version | android | ios | linux | macos | windows |
|---|---|---|---|---|---|---|
| autostart | 1.77.2 | |||||
| barcode-scanner | 1.77.2 | |||||
| biometric | 1.77.2 | |||||
| cli | 1.77.2 | |||||
| clipboard-manager | 1.77.2 | * | * | |||
| deep-link | 1.77.2 | * | * | * | ||
| dialog | 1.77.2 | * | * | |||
| fs | 1.77.2 | * | * | * | * | * |
| geolocation | 1.77.2 | |||||
| global-shortcut | 1.77.2 | |||||
| haptics | 1.77.2 | |||||
| http | 1.77.2 | |||||
| localhost | 1.77.2 | |||||
| log | 1.77.2 | |||||
| nfc | 1.77.2 | |||||
| notification | 1.77.2 | * | ||||
| opener | 1.77.2 | * | * | |||
| os | 1.77.2 | |||||
| persisted-scope | 1.77.2 | |||||
| positioner | 1.77.2 | |||||
| process | 1.77.2 | |||||
| shell | 1.77.2 | * | * | |||
| single-instance | 1.77.2 | |||||
| sql | 1.77.2 | |||||
| store | 1.77.2 | |||||
| stronghold | 1.77.2 | |||||
| updater | 1.77.2 | |||||
| upload | 1.77.2 | |||||
| websocket | 1.77.2 | |||||
| window-state | 1.77.2 | |||||
| system-tray | 1.77.2 | |||||
| window-customization | 1.77.2 |
Autostart
Automatically launch your app at system startup.
Automatically launch your application at system startup.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the autostart plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add autostart -
yarn
yarn run tauri add autostart -
pnpm
pnpm tauri add autostart -
deno
deno task tauri add autostart -
bun
bun tauri add autostart -
cargo
cargo tauri add autostart
-
-
Manual
npm run tauri add autostart -
npm
yarn run tauri add autostart -
yarn
pnpm tauri add autostart -
pnpm
deno task tauri add autostart -
deno
bun tauri add autostart -
bun
cargo tauri add autostart -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-autostart --target 'cfg(any(target_os = "macos", windows, target_os = "linux"))' -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .setup(|app| { + #[cfg(desktop)] +app.handle().plugin(tauri_plugin_autostart::init(tauri_plugin_autostart::MacosLauncher::LaunchAgent, Some(vec!["--flag1", "--flag2"]) /* arbitrary number of args to pass to your app */)); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
You can install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
npm
npm install @tauri-apps/plugin-autostart -
yarn
yarn add @tauri-apps/plugin-autostart -
pnpm
pnpm add @tauri-apps/plugin-autostart -
deno
deno add npm:@tauri-apps/plugin-autostart -
bun
bun add @tauri-apps/plugin-autostart
-
-
-
npm
npm install @tauri-apps/plugin-autostart -
yarn
yarn add @tauri-apps/plugin-autostart -
pnpm
pnpm add @tauri-apps/plugin-autostart -
deno
deno add npm:@tauri-apps/plugin-autostart -
bun
bun add @tauri-apps/plugin-autostart
Usage
The autostart plugin is available in both JavaScript and Rust.
-
JavaScript
import { enable, isEnabled, disable } from '@tauri-apps/plugin-autostart'; // when using `"withGlobalTauri": true`, you may use // const { enable, isEnabled, disable } = window.__TAURI__.autostart; // Enable autostart await enable(); // Check enable state console.log(`registered for autostart? ${await isEnabled()}`); // Disable autostart disable(); -
Rust
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .setup(|app| { #[cfg(desktop)] { use tauri_plugin_autostart::MacosLauncher; use tauri_plugin_autostart::ManagerExt; app.handle().plugin(tauri_plugin_autostart::init( MacosLauncher::LaunchAgent, Some(vec!["--flag1", "--flag2"]), )); // Get the autostart manager let autostart_manager = app.autolaunch(); // Enable autostart let _ = autostart_manager.enable(); // Check enable state println!("registered for autostart? {}", autostart_manager.is_enabled().unwrap()); // Disable autostart let _ = autostart_manager.disable(); } Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/default.json
{
"permissions": [
...,
"autostart:allow-enable",
"autostart:allow-disable",
"autostart:allow-is-enabled"
]
}
Default Permission
This permission set configures if your application can enable or disable auto starting the application on boot.
Granted Permissions
It allows all to check, enable and disable the automatic start on boot.
This default permission set includes the following:
allow-enableallow-disableallow-is-enabled
Permission Table
| Identifier | Description |
|---|---|
autostart:allow-disable |
Enables the disable command without any pre-configured scope. |
autostart:deny-disable |
Denies the disable command without any pre-configured scope. |
autostart:allow-enable |
Enables the enable command without any pre-configured scope. |
autostart:deny-enable |
Denies the enable command without any pre-configured scope. |
autostart:allow-is-enabled |
Enables the is_enabled command without any pre-configured scope. |
autostart:deny-is-enabled |
Denies the is_enabled command without any pre-configured scope. |
Barcode Scanner
Allows your mobile application to use the camera to scan QR codes, EAN-13 and other types of barcodes.
Allows your mobile application to use the camera to scan QR codes, EAN-13 and other kinds of barcodes.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the barcode-scanner plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add barcode-scanner -
yarn
yarn run tauri add barcode-scanner -
pnpm
pnpm tauri add barcode-scanner -
deno
deno task tauri add barcode-scanner -
bun
bun tauri add barcode-scanner -
cargo
cargo tauri add barcode-scanner
-
-
Manual
npm run tauri add barcode-scanner -
npm
yarn run tauri add barcode-scanner -
yarn
pnpm tauri add barcode-scanner -
pnpm
deno task tauri add barcode-scanner -
deno
bun tauri add barcode-scanner -
bun
cargo tauri add barcode-scanner -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-barcode-scanner --target 'cfg(any(target_os = "android", target_os = "ios"))' -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .setup(|app| { + #[cfg(mobile)] +app.handle().plugin(tauri_plugin_barcode_scanner::init()); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
npm
npm install @tauri-apps/plugin-barcode-scanner -
yarn
yarn add @tauri-apps/plugin-barcode-scanner -
pnpm
pnpm add @tauri-apps/plugin-barcode-scanner -
deno
deno add npm:@tauri-apps/plugin-barcode-scanner -
bun
bun add @tauri-apps/plugin-barcode-scanner
-
-
-
npm
npm install @tauri-apps/plugin-barcode-scanner -
yarn
yarn add @tauri-apps/plugin-barcode-scanner -
pnpm
pnpm add @tauri-apps/plugin-barcode-scanner -
deno
deno add npm:@tauri-apps/plugin-barcode-scanner -
bun
bun add @tauri-apps/plugin-barcode-scanner
Configuration
On iOS the barcode scanner plugin requires the NSCameraUsageDescription information property list value, which should describe why your app needs to use the camera.
In the src-tauri/Info.ios.plist file, add the following snippet:
src-tauri/Info.ios.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSCameraUsageDescription</key>
<string>Read QR codes</string>
</dict>
</plist>
Usage
The barcode scanner plugin is available in JavaScript.
import { scan, Format } from '@tauri-apps/plugin-barcode-scanner';
// when using `"withGlobalTauri": true`, you may use
// const { scan, Format } = window.__TAURI__.barcodeScanner;
// `windowed: true` actually sets the webview to transparent
// instead of opening a separate view for the camera
// make sure your user interface is ready to show what is underneath with a transparent element
scan({ windowed: true, formats: [Format.QRCode] });
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/mobile.json
{
"$schema": "../gen/schemas/mobile-schema.json",
"identifier": "mobile-capability",
"windows": ["main"],
"platforms": ["iOS", "android"],
"permissions": ["barcode-scanner:allow-scan", "barcode-scanner:allow-cancel"]
}
Default Permission
This permission set configures which barcode scanning features are by default exposed.
Granted Permissions
It allows all barcode related features.
This default permission set includes the following:
allow-cancelallow-check-permissionsallow-open-app-settingsallow-request-permissionsallow-scanallow-vibrate
Permission Table
| Identifier | Description |
|---|---|
barcode-scanner:allow-cancel |
Enables the cancel command without any pre-configured scope. |
barcode-scanner:deny-cancel |
Denies the cancel command without any pre-configured scope. |
barcode-scanner:allow-check-permissions |
Enables the check_permissions command without any pre-configured scope. |
barcode-scanner:deny-check-permissions |
Denies the check_permissions command without any pre-configured scope. |
barcode-scanner:allow-open-app-settings |
Enables the open_app_settings command without any pre-configured scope. |
barcode-scanner:deny-open-app-settings |
Denies the open_app_settings command without any pre-configured scope. |
barcode-scanner:allow-request-permissions |
Enables the request_permissions command without any pre-configured scope. |
barcode-scanner:deny-request-permissions |
Denies the request_permissions command without any pre-configured scope. |
barcode-scanner:allow-scan |
Enables the scan command without any pre-configured scope. |
barcode-scanner:deny-scan |
Denies the scan command without any pre-configured scope. |
barcode-scanner:allow-vibrate |
Enables the vibrate command without any pre-configured scope. |
barcode-scanner:deny-vibrate |
Denies the vibrate command without any pre-configured scope. |
Biometric
Prompt the user for biometric authentication on Android and iOS.
Prompt the user for biometric authentication on Android and iOS.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the biometric plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add biometric -
yarn
yarn run tauri add biometric -
pnpm
pnpm tauri add biometric -
deno
deno task tauri add biometric -
bun
bun tauri add biometric -
cargo
cargo tauri add biometric
-
-
Manual
npm run tauri add biometric -
npm
yarn run tauri add biometric -
yarn
pnpm tauri add biometric -
pnpm
deno task tauri add biometric -
deno
bun tauri add biometric -
bun
cargo tauri add biometric -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-biometric --target 'cfg(any(target_os = "android", target_os = "ios"))' -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .setup(|app| { + #[cfg(mobile)] +app.handle().plugin(tauri_plugin_biometric::Builder::new().build()); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
npm
npm install @tauri-apps/plugin-biometric -
yarn
yarn add @tauri-apps/plugin-biometric -
pnpm
pnpm add @tauri-apps/plugin-biometric -
deno
deno add npm:@tauri-apps/plugin-biometric -
bun
bun add @tauri-apps/plugin-biometric
-
-
-
npm
npm install @tauri-apps/plugin-biometric -
yarn
yarn add @tauri-apps/plugin-biometric -
pnpm
pnpm add @tauri-apps/plugin-biometric -
deno
deno add npm:@tauri-apps/plugin-biometric -
bun
bun add @tauri-apps/plugin-biometric
Configuration
On iOS the biometric plugin requires the NSFaceIDUsageDescription information property list value, which should describe why your app needs to use biometric authentication.
In the src-tauri/Info.ios.plist file, add the following snippet:
src-tauri/Info.ios.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSFaceIDUsageDescription</key>
<string>Authenticate with biometric</string>
</dict>
</plist>
Usage
This plugin enables you to verify the availability of Biometric Authentication on a device, prompt the user for biometric authentication, and check the result to determine if the authentication was successful or not.
Check Status
You can check the status of Biometric Authentication, including its availability and the types of biometric authentication methods supported.
-
JavaScript
import { checkStatus } from '@tauri-apps/plugin-biometric'; const status = await checkStatus(); if (status.isAvailable) { console.log('Yes! Biometric Authentication is available'); } else { console.log( 'No! Biometric Authentication is not available due to ' + status.error ); } -
Rust
use tauri_plugin_biometric::BiometricExt; fn check_biometric(app_handle: tauri::AppHandle) { let status = app_handle.biometric().status().unwrap(); if status.is_available { println!("Yes! Biometric Authentication is available"); } else { println!("No! Biometric Authentication is not available due to: {}", status.error.unwrap()); } }
Authenticate
To prompt the user for Biometric Authentication, utilize the authenticate() method.
-
JavaScript
import { authenticate } from '@tauri-apps/plugin-biometric'; const options = { // Set true if you want the user to be able to authenticate using phone password allowDeviceCredential: false, cancelTitle: "Feature won't work if Canceled", // iOS only feature fallbackTitle: 'Sorry, authentication failed', // Android only features title: 'Tauri feature', subtitle: 'Authenticate to access the locked Tauri function', confirmationRequired: true, }; try { +await authenticate('This feature is locked', options); console.log( 'Hooray! Successfully Authenticated! We can now perform the locked Tauri function!' ); } catch (err) { console.log('Oh no! Authentication failed because ' + err.message); } -
Rust
use tauri_plugin_biometric::{BiometricExt, AuthOptions}; fn bio_auth(app_handle: tauri::AppHandle) { let options = AuthOptions { // Set True if you want the user to be able to authenticate using phone password allow_device_credential:false, cancel_title: Some("Feature won't work if Canceled".to_string()), // iOS only feature fallback_title: Some("Sorry, authentication failed".to_string()), // Android only features title: Some("Tauri feature".to_string()), subtitle: Some("Authenticate to access the locked Tauri function".to_string()), confirmation_required: Some(true), }; // if the authentication was successful, the function returns Result::Ok() // otherwise returns Result::Error() +match app_handle.biometric().authenticate("This feature is locked".to_string(), options) { Ok(_) => { println!("Hooray! Successfully Authenticated! We can now perform the locked Tauri function!"); } Err(e) => { println!("Oh no! Authentication failed because : {e}"); } } }
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "Capability for the main window",
"windows": ["main"],
+"permissions": ["biometric:default"]
}
Default Permission
This permission set configures which biometric features are by default exposed.
Granted Permissions
It allows acccess to all biometric commands.
This default permission set includes the following:
allow-authenticateallow-status
Permission Table
| Identifier | Description |
|---|---|
biometric:allow-authenticate |
Enables the authenticate command without any pre-configured scope. |
biometric:deny-authenticate |
Denies the authenticate command without any pre-configured scope. |
biometric:allow-status |
Enables the status command without any pre-configured scope. |
biometric:deny-status |
Denies the status command without any pre-configured scope. |
Command Line Interface (CLI)
Parse arguments from the command line interface.
Tauri enables your app to have a CLI through clap, a robust command line argument parser. With a simple CLI definition in your tauri.conf.json file, you can define your interface and read its argument matches map on JavaScript and/or Rust.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
- Windows
- Due to an OS limitation, production apps are not able to write text back to the calling console by default. Please check out tauri#8305 for a workaround.
Setup
Install the CLI plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add cli -
yarn
yarn run tauri add cli -
pnpm
pnpm tauri add cli -
deno
deno task tauri add cli -
bun
bun tauri add cli -
cargo
cargo tauri add cli
-
-
Manual
npm run tauri add cli -
npm
yarn run tauri add cli -
yarn
pnpm tauri add cli -
pnpm
deno task tauri add cli -
deno
bun tauri add cli -
bun
cargo tauri add cli -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-cli --target 'cfg(any(target_os = "macos", windows, target_os = "linux"))'- Modify
lib.rsto initialize the plugin:
src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .setup(|app| { + #[cfg(desktop)] +app.handle().plugin(tauri_plugin_cli::init()); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); }- Install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
npm
npm install @tauri-apps/plugin-cli -
yarn
yarn add @tauri-apps/plugin-cli -
pnpm
pnpm add @tauri-apps/plugin-cli -
deno
deno add npm:@tauri-apps/plugin-cli -
bun
bun add @tauri-apps/plugin-cli
- Modify
-
-
npm
npm install @tauri-apps/plugin-cli -
yarn
yarn add @tauri-apps/plugin-cli -
pnpm
pnpm add @tauri-apps/plugin-cli -
deno
deno add npm:@tauri-apps/plugin-cli -
bun
bun add @tauri-apps/plugin-cli
Base Configuration
Under tauri.conf.json, you have the following structure to configure the interface:
src-tauri/tauri.conf.json
{
"plugins": {
"cli": {
"description": "Tauri CLI Plugin Example",
"args": [
{
"short": "v",
"name": "verbose",
"description": "Verbosity level"
}
],
"subcommands": {
"run": {
"description": "Run the application",
"args": [
{
"name": "debug",
"description": "Run application in debug mode"
},
{
"name": "release",
"description": "Run application in release mode"
}
]
}
}
}
}
}
Note
All JSON configurations here are just samples, many other fields have been omitted for the sake of clarity.
Adding Arguments
The args array represents the list of arguments accepted by its command or subcommand.
Positional Arguments
A positional argument is identified by its position in the list of arguments. With the following configuration:
src-tauri/tauri.conf.json
{
"args": [
{
"name": "source",
"index": 1,
"takesValue": true
},
{
"name": "destination",
"index": 2,
"takesValue": true
}
]
}
Users can run your app as ./app tauri.txt dest.txt and the arg matches map will define source as "tauri.txt" and destination as "dest.txt".
Named Arguments
A named argument is a (key, value) pair where the key identifies the value. With the following configuration:
tauri-src/tauri.conf.json
{
"args": [
{
"name": "type",
"short": "t",
"takesValue": true,
"multiple": true,
"possibleValues": ["foo", "bar"]
}
]
}
Users can run your app as ./app --type foo bar, ./app -t foo -t bar or ./app --type=foo,bar and the arg matches map will define type as ["foo", "bar"].
Flag Arguments
A flag argument is a standalone key whose presence or absence provides information to your application. With the following configuration:
tauri-src/tauri.conf.json
{
"args": [
{
"name": "verbose",
"short": "v"
}
]
}
Users can run your app as ./app -v -v -v, ./app --verbose --verbose --verbose or ./app -vvv and the arg matches map will define verbose as true, with occurrences = 3.
Subcommands
Some CLI applications have additional interfaces as subcommands. For instance, the git CLI has git branch, git commit and git push. You can define additional nested interfaces with the subcommands array:
tauri-src/tauri.conf.json
{
"cli": {
...
"subcommands": {
"branch": {
"args": []
},
"push": {
"args": []
}
}
}
}
Its configuration is the same as the root application configuration, with the description, longDescription, args, etc.
Usage
The CLI plugin is available in both JavaScript and Rust.
-
JavaScript
import { getMatches } from '@tauri-apps/plugin-cli'; // when using `"withGlobalTauri": true`, you may use // const { getMatches } = window.__TAURI__.cli; const matches = await getMatches(); if (matches.subcommand?.name === 'run') { // `./your-app run $ARGS` was executed const args = matches.subcommand.matches.args; if (args.debug?.value === true) { // `./your-app run --debug` was executed } if (args.release?.value === true) { // `./your-app run --release` was executed } } -
Rust
src-tauri/src/lib.rs
use tauri_plugin_cli::CliExt; #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .plugin(tauri_plugin_cli::init()) .setup(|app| { match app.cli().matches() { // `matches` here is a Struct with { args, subcommand }. // `args` is `HashMap<String, ArgData>` where `ArgData` is a struct with { value, occurrences }. // `subcommand` is `Option<Box<SubcommandMatches>>` where `SubcommandMatches` is a struct with { name, matches }. Ok(matches) => { println!("{:?}", matches) } Err(_) => {} } Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "Capability for the main window",
"windows": ["main"],
+"permissions": ["cli:default"]
}
Default Permission
Allows reading the CLI matches
This default permission set includes the following:
allow-cli-matches
Permission Table
| Identifier | Description |
|---|---|
cli:allow-cli-matches |
Enables the cli_matches command without any pre-configured scope. |
cli:deny-cli-matches |
Denies the cli_matches command without any pre-configured scope. |
Clipboard
Read and write to the system clipboard.
Read and write to the system clipboard using the clipboard plugin.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | Only plain-text content support | |
| ios | Only plain-text content support |
Setup
Install the clipboard plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add clipboard-manager -
yarn
yarn run tauri add clipboard-manager -
pnpm
pnpm tauri add clipboard-manager -
deno
deno task tauri add clipboard-manager -
bun
bun tauri add clipboard-manager -
cargo
cargo tauri add clipboard-manager
-
-
Manual
npm run tauri add clipboard-manager -
npm
yarn run tauri add clipboard-manager -
yarn
pnpm tauri add clipboard-manager -
pnpm
deno task tauri add clipboard-manager -
deno
bun tauri add clipboard-manager -
bun
cargo tauri add clipboard-manager -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-clipboard-manager -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() +.plugin(tauri_plugin_clipboard_manager::init()) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
If you’d like to manage the clipboard in JavaScript then install the npm package as well:
-
npm
npm install @tauri-apps/plugin-clipboard-manager -
yarn
yarn add @tauri-apps/plugin-clipboard-manager -
pnpm
pnpm add @tauri-apps/plugin-clipboard-manager -
deno
deno add npm:@tauri-apps/plugin-clipboard-manager -
bun
bun add @tauri-apps/plugin-clipboard-manager
-
-
-
npm
npm install @tauri-apps/plugin-clipboard-manager -
yarn
yarn add @tauri-apps/plugin-clipboard-manager -
pnpm
pnpm add @tauri-apps/plugin-clipboard-manager -
deno
deno add npm:@tauri-apps/plugin-clipboard-manager -
bun
bun add @tauri-apps/plugin-clipboard-manager
Usage
The clipboard plugin is available in both JavaScript and Rust.
-
JavaScript
import { writeText, readText } from '@tauri-apps/plugin-clipboard-manager'; // when using `"withGlobalTauri": true`, you may use // const { writeText, readText } = window.__TAURI__.clipboardManager; // Write content to clipboard await writeText('Tauri is awesome!'); // Read content from clipboard const content = await readText(); console.log(content); // Prints "Tauri is awesome!" to the console -
Rust
use tauri_plugin_clipboard_manager::ClipboardExt; app.clipboard().write_text("Tauri is awesome!".to_string()).unwrap(); // Read content from clipboard let content = app.clipboard().read_text(); println!("{:?}", content.unwrap()); // Prints "Tauri is awesome!" to the terminal
Default Permission
No features are enabled by default, as we believe the clipboard can be inherently dangerous and it is application specific if read and/or write access is needed.
Clipboard interaction needs to be explicitly enabled.
Permission Table
| Identifier | Description |
|---|---|
clipboard-manager:allow-clear |
Enables the clear command without any pre-configured scope. |
clipboard-manager:deny-clear |
Denies the clear command without any pre-configured scope. |
clipboard-manager:allow-read-image |
Enables the read_image command without any pre-configured scope. |
clipboard-manager:deny-read-image |
Denies the read_image command without any pre-configured scope. |
clipboard-manager:allow-read-text |
Enables the read_text command without any pre-configured scope. |
clipboard-manager:deny-read-text |
Denies the read_text command without any pre-configured scope. |
clipboard-manager:allow-write-html |
Enables the write_html command without any pre-configured scope. |
clipboard-manager:deny-write-html |
Denies the write_html command without any pre-configured scope. |
clipboard-manager:allow-write-image |
Enables the write_image command without any pre-configured scope. |
clipboard-manager:deny-write-image |
Denies the write_image command without any pre-configured scope. |
clipboard-manager:allow-write-text |
Enables the write_text command without any pre-configured scope. |
clipboard-manager:deny-write-text |
Denies the write_text command without any pre-configured scope. |
Deep Linking
Set your Tauri application as the default handler for an URL.
Set your Tauri application as the default handler for an URL.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | Deep links must be registered in config. Dynamic registration at runtime is not supported. | |
| android | Deep links must be registered in config. Dynamic registration at runtime is not supported. | |
| ios | Deep links must be registered in config. Dynamic registration at runtime is not supported. |
Setup
Install the deep-link plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add deep-link -
yarn
yarn run tauri add deep-link -
pnpm
pnpm tauri add deep-link -
deno
deno task tauri add deep-link -
bun
bun tauri add deep-link -
cargo
cargo tauri add deep-link
-
-
Manual
npm run tauri add deep-link -
npm
yarn run tauri add deep-link -
yarn
pnpm tauri add deep-link -
pnpm
deno task tauri add deep-link -
deno
bun tauri add deep-link -
bun
cargo tauri add deep-link -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-deep-link@2.0.0 -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() +.plugin(tauri_plugin_deep_link::init()) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
npm
npm install @tauri-apps/plugin-deep-link -
yarn
yarn add @tauri-apps/plugin-deep-link -
pnpm
pnpm add @tauri-apps/plugin-deep-link -
deno
deno add npm:@tauri-apps/plugin-deep-link -
bun
bun add @tauri-apps/plugin-deep-link
-
-
-
npm
npm install @tauri-apps/plugin-deep-link -
yarn
yarn add @tauri-apps/plugin-deep-link -
pnpm
pnpm add @tauri-apps/plugin-deep-link -
deno
deno add npm:@tauri-apps/plugin-deep-link -
bun
bun add @tauri-apps/plugin-deep-link
Setting up
Android
There are two ways to open your app from links on Android:
- App Links (http/https + host, verified) For app links, you need a server with a
.well-known/assetlinks.jsonendpoint that must return a text response in the given format:
.well-known/assetlinks.json
[
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "$APP_BUNDLE_ID",
"sha256_cert_fingerprints": [
$CERT_FINGERPRINT
]
}
}
]
Where $APP_BUNDLE_ID is the value defined on tauri.conf.json > identifier with - replaced with _ and $CERT_FINGERPRINT is a list of SHA256 fingerprints of your app’s signing certificates, see verify Android applinks for more information.
- Custom URI schemes (no host required, no verification) For URIs like
myapp://..., you can declare a custom scheme without hosting any files. Use theschemefield in the mobile configuration and omit thehost.
iOS
There are two ways to open your app from links on iOS:
- Universal Links (https + host, verified) For universal links, you need a server with a
.well-known/apple-app-site-associationendpoint that must return a JSON response in the given format:
.well-known/apple-app-site-association
{
"applinks": {
"details": [
{
"appIDs": ["$DEVELOPMENT_TEAM_ID.$APP_BUNDLE_ID"],
"components": [
{
"/": "/open/*",
"comment": "Matches any URL whose path starts with /open/"
}
]
}
]
}
}
Note
The response Content-Type header must be application/json.
The .well-known/apple-app-site-association endpoint must be served over HTTPS. To test localhost you can either use a self-signed TLS certificate and install it on the iOS simulator or use services like ngrok.
Where $DEVELOPMENT_TEAM_ID is the value defined on tauri.conf.json > bundle > iOS > developmentTeam or the TAURI_APPLE_DEVELOPMENT_TEAM environment variable and $APP_BUNDLE_ID is the value defined on tauri.conf.json > identifier.
To verify if your domain has been properly configured to expose the app associations, you can run the following command, replacing <host> with your actual host:
curl -v https://app-site-association.cdn-apple.com/a/v1/<host>
See applinks.details for more information.
- Custom URI schemes (no host, no verification) For URIs like
myapp://..., you can declare a custom scheme under mobile configuration with"appLink": false(or omit it). The plugin generates the appropriateCFBundleURLTypesentries in your app’s Info.plist. No.well-knownfiles or HTTPS host are needed.
Desktop
On Linux and Windows deep links are delivered as a command line argument to a new app process. The deep link plugin has integration with the single instance plugin if you prefer having a unique app instance receiving the events.
- First you must add the
deep-linkfeature to the single instance plugin:
src-tauri/Cargo.toml
[target."cfg(any(target_os = \"macos\", windows, target_os = \"linux\"))".dependencies]
tauri-plugin-single-instance = { version = "2.0.0", features = ["deep-link"] }
- Then configure the single instance plugin which should always be the first plugin you register:
src-tauri/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
let mut builder = tauri::Builder::default();
#[cfg(desktop)]
{
builder = builder.plugin(tauri_plugin_single_instance::init(|_app, argv, _cwd| {
println!("a new app instance was opened with {argv:?} and the deep link event was already triggered");
// when defining deep link schemes at runtime, you must also check `argv` here
}));
}
builder = builder.plugin(tauri_plugin_deep_link::init());
}
Caution
The user could trigger a fake deep link manually by including the URL as argument. Tauri matches the command line argument against the configured schemes to mitigate this, but you should still check if the URL matches the format you expect.
This means Tauri only handles deep links for schemes that were statically configured, and schemes registered at runtime must be manually checked using Env::args_os.
Configuration
Under tauri.conf.json > plugins > deep-link, configure mobile domains/schemes and desktop schemes you want to associate with your application.
Examples
Custom scheme on mobile (no server required):
tauri.conf.json
{
"plugins": {
"deep-link": {
"mobile": [
{
"scheme": ["ovi"],
"appLink": false
}
]
}
}
}
This registers the ovi://* scheme on Android and iOS.
App Link / Universal Link (verified https + host):
{
"plugins": {
"deep-link": {
"mobile": [
{
"scheme": ["https"],
"host": "your.website.com",
"pathPrefix": ["/open"],
"appLink": true
}
]
}
}
}
This registers https://your.website.com/open/* as an app/universal link.
Desktop custom schemes:
{
"plugins": {
"deep-link": {
"desktop": {
"schemes": ["something", "my-tauri-app"]
}
}
}
}
Usage
The deep-link plugin is available in both JavaScript and Rust.
Listening to Deep Links
-
JavaScript
When a deep link triggers your app while it’s running, the
onOpenUrlcallback is called. To detect whether your app was opened via a deep link, usegetCurrenton app start.import { getCurrent, onOpenUrl } from '@tauri-apps/plugin-deep-link'; // when using `"withGlobalTauri": true`, you may use // const { getCurrent, onOpenUrl } = window.__TAURI__.deepLink; const startUrls = await getCurrent(); if (startUrls) { // App was likely started via a deep link // Note that getCurrent's return value will also get updated every time onOpenUrl gets triggered. } await onOpenUrl((urls) => { console.log('deep link:', urls); }); -
Rust
When a deep link triggers your app while it’s running, the plugin’s
on_open_urlclosure is called. To detect whether your app was opened via a deep link, useget_currenton app start.src-tauri/src/lib.rs
use tauri_plugin_deep_link::DeepLinkExt; #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .plugin(tauri_plugin_deep_link::init()) .setup(|app| { // Note that get_current's return value will also get updated every time on_open_url gets triggered. let start_urls = app.deep_link().get_current()?; if let Some(urls) = start_urls { // app was likely started by a deep link println!("deep link URLs: {:?}", urls); } app.deep_link().on_open_url(|event| { println!("deep link URLs: {:?}", event.urls()); }); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
Note
The open URL event is triggered with a list of URLs that were requested to be compatible with the macOS API for deep links, but in most cases your app will only receive a single URL.
Registering Desktop Deep Links at Runtime
The configuration section describes how to define static deep link schemes for your application.
On Linux and Windows it is possible to also associate schemes with your application at runtime via the register Rust function.
In the following snippet, we will register the my-app scheme at runtime. After executing the app for the first time, the operating system will open my-app://* URLs with our application:
src-tauri/src/lib.rs
use tauri_plugin_deep_link::DeepLinkExt;
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_deep_link::init())
.setup(|app| {
#[cfg(desktop)]
app.deep_link().register("my-app")?;
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Note
Registering the deep links at runtime can be useful for developing on Linux and Windows as by default the deep link is only registered when your app is installed.
Installing an AppImage can be complicated as it requires an AppImage launcher.
Registering the deep links at runtime might be preferred, so Tauri also includes a helper function to force register all statically configured deep links at runtime. Calling this function also ensures the deep links is registered for development mode:
#[cfg(any(target_os = "linux", all(debug_assertions, windows)))]
{
use tauri_plugin_deep_link::DeepLinkExt;
app.deep_link().register_all()?;
}
Testing
There are some caveats to test deep links for your application.
Desktop
Deep links are only triggered for installed applications on desktop. On Linux and Windows you can circumvent this using the register_all Rust function, which registers all configured schemes to trigger the current executable:
src-tauri/src/lib.rs
use tauri_plugin_deep_link::DeepLinkExt;
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_deep_link::init())
.setup(|app| {
#[cfg(any(windows, target_os = "linux"))]
{
use tauri_plugin_deep_link::DeepLinkExt;
app.deep_link().register_all()?;
}
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Note
Installing an AppImage that supports deep links on Linux requires an AppImage launcher to integrate the AppImage with the operating system. Using the register_all function you can support deep links out of the box, without requiring your users to use external tools.
When the AppImage is moved to a different location in the file system, the deep link is invalidated since it leverages an absolute path to the executable, which makes registering the schemes at runtime even more important.
See the Registering Desktop Deep Links at Runtime section for more information.
Caution
Registering deep links at runtime is not possible on macOS, so deep links can only be tested on the bundled application, which must be installed in the /Applications directory.
Windows
To trigger a deep link on Windows you can either open <scheme>://url in the browser or run the following command in the terminal:
start <scheme>://url
Linux
To trigger a deep link on Linux you can either open <scheme>://url in the browser or run xdg-open in the terminal:
xdg-open <scheme>://url
iOS
To trigger an app link on iOS you can open the https://<host>/path URL in the browser. For simulators you can leverage the simctl CLI to directly open a link from the terminal:
xcrun simctl openurl booted https://<host>/path
Android
To trigger an app link on Android you can open the https://<host>/path URL in the browser. For emulators you can leverage the adb CLI to directly open a link from the terminal:
adb shell am start -a android.intent.action.VIEW -d https://<host>/path <bundle-identifier>
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/mobile-schema.json",
"identifier": "mobile-capability",
"windows": ["main"],
"platforms": ["iOS", "android"],
"permissions": [
// Usually you will need core:event:default to listen to the deep-link event
"core:event:default",
+"deep-link:default"
]
}
Default Permission
Allows reading the opened deep link via the get_current command
This default permission set includes the following:
allow-get-current
Permission Table
| Identifier | Description |
|---|---|
deep-link:allow-get-current |
Enables the get_current command without any pre-configured scope. |
deep-link:deny-get-current |
Denies the get_current command without any pre-configured scope. |
deep-link:allow-is-registered |
Enables the is_registered command without any pre-configured scope. |
deep-link:deny-is-registered |
Denies the is_registered command without any pre-configured scope. |
deep-link:allow-register |
Enables the register command without any pre-configured scope. |
deep-link:deny-register |
Denies the register command without any pre-configured scope. |
deep-link:allow-unregister |
Enables the unregister command without any pre-configured scope. |
deep-link:deny-unregister |
Denies the unregister command without any pre-configured scope. |
Dialog
Native system dialogs for opening and saving files along with message dialogs.
Native system dialogs for opening and saving files along with message dialogs.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | Does not support folder picker | |
| ios | Does not support folder picker |
Setup
Install the dialog plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add dialog -
yarn
yarn run tauri add dialog -
pnpm
pnpm tauri add dialog -
deno
deno task tauri add dialog -
bun
bun tauri add dialog -
cargo
cargo tauri add dialog
-
-
Manual
npm run tauri add dialog -
npm
yarn run tauri add dialog -
yarn
pnpm tauri add dialog -
pnpm
deno task tauri add dialog -
deno
bun tauri add dialog -
bun
cargo tauri add dialog -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-dialog -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() +.plugin(tauri_plugin_dialog::init()) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
If you’d like create dialogs in JavaScript, install the npm package as well:
-
npm
npm install @tauri-apps/plugin-dialog -
yarn
yarn add @tauri-apps/plugin-dialog -
pnpm
pnpm add @tauri-apps/plugin-dialog -
deno
deno add npm:@tauri-apps/plugin-dialog -
bun
bun add @tauri-apps/plugin-dialog
-
-
-
npm
npm install @tauri-apps/plugin-dialog -
yarn
yarn add @tauri-apps/plugin-dialog -
pnpm
pnpm add @tauri-apps/plugin-dialog -
deno
deno add npm:@tauri-apps/plugin-dialog -
bun
bun add @tauri-apps/plugin-dialog
Usage
The dialog plugin is available in both JavaScript and Rust. Here’s how you can use it:
in JavaScript:
- Create Yes/No Dialog
- Create Ok/Cancel Dialog
- Create Message Dialog
- Open a File Selector Dialog
- Save to File Dialog
in Rust:
Note
The file dialog APIs returns file system paths on Linux, Windows and macOS.
On iOS, a file://<path> URIs are returned.
On Android, content URIs are returned.
The filesystem plugin works with any path format out of the box.
JavaScript
See all Dialog Options at the JavaScript API reference.
Create Yes/No Dialog
Shows a question dialog with Yes and No buttons.
import { ask } from '@tauri-apps/plugin-dialog';
// when using `"withGlobalTauri": true`, you may use
// const { ask } = window.__TAURI__.dialog;
// Create a Yes/No dialog
const answer = await ask('This action cannot be reverted. Are you sure?', {
title: 'Tauri',
kind: 'warning',
});
console.log(answer);
// Prints boolean to the console
Create Ok/Cancel Dialog
Shows a question dialog with Ok and Cancel buttons.
import { confirm } from '@tauri-apps/plugin-dialog';
// when using `"withGlobalTauri": true`, you may use
// const { confirm } = window.__TAURI__.dialog;
// Creates a confirmation Ok/Cancel dialog
const confirmation = await confirm(
'This action cannot be reverted. Are you sure?',
{ title: 'Tauri', kind: 'warning' }
);
console.log(confirmation);
// Prints boolean to the console
Create Message Dialog
Shows a message dialog with an Ok button. Keep in mind that if the user closes the dialog it will return false.
import { message } from '@tauri-apps/plugin-dialog';
// when using `"withGlobalTauri": true`, you may use
// const { message } = window.__TAURI__.dialog;
// Shows message
await message('File not found', { title: 'Tauri', kind: 'error' });
Open a File Selector Dialog
Open a file/directory selection dialog.
The multiple option controls whether the dialog allows multiple selection or not, while the directory, whether is a directory selection or not.
import { open } from '@tauri-apps/plugin-dialog';
// when using `"withGlobalTauri": true`, you may use
// const { open } = window.__TAURI__.dialog;
// Open a dialog
const file = await open({
multiple: false,
directory: false,
});
console.log(file);
// Prints file path or URI
Save to File Dialog
Open a file/directory save dialog.
import { save } from '@tauri-apps/plugin-dialog';
// when using `"withGlobalTauri": true`, you may use
// const { save } = window.__TAURI__.dialog;
// Prompt to save a 'My Filter' with extension .png or .jpeg
const path = await save({
filters: [
{
name: 'My Filter',
extensions: ['png', 'jpeg'],
},
],
});
console.log(path);
// Prints the chosen path
Rust
Refer to the Rust API reference to see all available options.
Build an Ask Dialog
Shows a question dialog with Absolutely and Totally buttons.
use tauri_plugin_dialog::{DialogExt, MessageDialogButtons};
let answer = app.dialog()
.message("Tauri is Awesome")
.title("Tauri is Awesome")
.buttons(MessageDialogButtons::OkCancelCustom("Absolutely", "Totally"))
.blocking_show();
If you need a non blocking operation you can use show() instead:
use tauri_plugin_dialog::{DialogExt, MessageDialogButtons};
app.dialog()
.message("Tauri is Awesome")
.title("Tauri is Awesome")
.buttons(MessageDialogButtons::OkCancelCustom("Absolutely", "Totally"))
.show(|result| match result {
true => // do something,
false =>// do something,
});
Build a Message Dialog
Shows a message dialog with an Ok button. Keep in mind that if the user closes the dialog it will return false.
use tauri_plugin_dialog::{DialogExt, MessageDialogKind};
let ans = app.dialog()
.message("File not found")
.kind(MessageDialogKind::Error)
.title("Warning")
.blocking_show();
If you need a non blocking operation you can use show() instead:
use tauri_plugin_dialog::{DialogExt, MessageDialogButtons, MessageDialogKind};
app.dialog()
.message("Tauri is Awesome")
.kind(MessageDialogKind::Info)
.title("Information")
.buttons(MessageDialogButtons::OkCustom("Absolutely"))
.show(|result| match result {
true => // do something,
false => // do something,
});
Build a File Selector Dialog
Pick Files
use tauri_plugin_dialog::DialogExt;
let file_path = app.dialog().file().blocking_pick_file();
// return a file_path `Option`, or `None` if the user closes the dialog
If you need a non blocking operation you can use pick_file() instead:
use tauri_plugin_dialog::DialogExt;
app.dialog().file().pick_file(|file_path| {
// return a file_path `Option`, or `None` if the user closes the dialog
})
Save Files
use tauri_plugin_dialog::DialogExt;
let file_path = app
.dialog()
.file()
.add_filter("My Filter", &["png", "jpeg"])
.blocking_save_file();
// do something with the optional file path here
// the file path is `None` if the user closed the dialog
or, alternatively:
use tauri_plugin_dialog::DialogExt;
app.dialog()
.file()
.add_filter("My Filter", &["png", "jpeg"])
.pick_file(|file_path| {
// return a file_path `Option`, or `None` if the user closes the dialog
});
Default Permission
This permission set configures the types of dialogs available from the dialog plugin.
Granted Permissions
All dialog types are enabled.
This default permission set includes the following:
allow-messageallow-saveallow-open
Permission Table
| Identifier | Description |
|---|---|
dialog:allow-ask |
Enables the ask command without any pre-configured scope. (DEPRECATED: This is now an alias to allow-message and will be removed in v3) |
dialog:deny-ask |
Denies the ask command without any pre-configured scope. (DEPRECATED: This is now an alias to deny-message and will be removed in v3) |
dialog:allow-message |
Enables the message command without any pre-configured scope. |
dialog:deny-message |
Denies the message command without any pre-configured scope. |
dialog:allow-open |
Enables the open command without any pre-configured scope. |
dialog:deny-open |
Denies the open command without any pre-configured scope. |
dialog:allow-save |
Enables the save command without any pre-configured scope. |
dialog:deny-save |
Denies the save command without any pre-configured scope. |
dialog:allow-confirm |
Enables the confirm command without any pre-configured scope. (DEPRECATED: This is now an alias to allow-message and will be removed in v3) |
dialog:deny-confirm |
Denies the confirm command without any pre-configured scope. (DEPRECATED: This is now an alias to deny-message and will be removed in v3) |
File System
Access the file system.
Access the file system.
Use std::fs or tokio::fs on the Rust side
If you want to manipulate files/directories through Rust, use traditional Rust’s libs (std::fs, tokio::fs, etc).
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | Apps installed via MSI or NSIS in perMachine and both mode require admin permissions for write access in $RESOURCES folder |
|
| linux | No write access to $RESOURCES folder |
|
| macos | No write access to $RESOURCES folder |
|
| android | Access is restricted to Application folder by default | |
| ios | Access is restricted to Application folder by default |
Setup
Install the fs plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add fs -
yarn
yarn run tauri add fs -
pnpm
pnpm tauri add fs -
deno
deno task tauri add fs -
bun
bun tauri add fs -
cargo
cargo tauri add fs
-
-
Manual
npm run tauri add fs -
npm
yarn run tauri add fs -
yarn
pnpm tauri add fs -
pnpm
deno task tauri add fs -
deno
bun tauri add fs -
bun
cargo tauri add fs -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-fs -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() +.plugin(tauri_plugin_fs::init()) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
npm
npm install @tauri-apps/plugin-fs -
yarn
yarn add @tauri-apps/plugin-fs -
pnpm
pnpm add @tauri-apps/plugin-fs -
deno
deno add npm:@tauri-apps/plugin-fs -
bun
bun add @tauri-apps/plugin-fs
-
-
-
npm
npm install @tauri-apps/plugin-fs -
yarn
yarn add @tauri-apps/plugin-fs -
pnpm
pnpm add @tauri-apps/plugin-fs -
deno
deno add npm:@tauri-apps/plugin-fs -
bun
bun add @tauri-apps/plugin-fs
Configuration
Android
When using the audio, cache, documents, downloads, picture, public or video directories your app must have access to the external storage.
Include the following permissions to the manifest tag in the gen/android/app/src/main/AndroidManifest.xml file:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
iOS
Apple requires app developers to specify approved reasons for API usage to enhance user privacy.
You must create a PrivacyInfo.xcprivacy file in the src-tauri/gen/apple folder with the required NSPrivacyAccessedAPICategoryFileTimestamp key and the C617.1 recommended reason.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
</array>
</dict>
</plist>
Usage
The fs plugin is available in both JavaScript and Rust.
Different APIs
Although this plugin has a file manipulation API on the frontend, in the backend it offers only the methods to change permission of some resources (files, directories, etc).
In the Rust side you can use the traditional file manipulation libraries, std::fs, tokio::fs or others.
-
JavaScript
import { exists, BaseDirectory } from '@tauri-apps/plugin-fs'; // when using `"withGlobalTauri": true`, you may use // const { exists, BaseDirectory } = window.__TAURI__.fs; // Check if the `$APPDATA/avatar.png` file exists await exists('avatar.png', { baseDir: BaseDirectory.AppData }); -
Rust
src-tauri/src/lib.rs
use tauri_plugin_fs::FsExt; #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .plugin(tauri_plugin_fs::init()) .setup(|app| { // allowed the given directory let scope = app.fs_scope(); scope.allow_directory("/path/to/directory", false); dbg!(scope.allowed()); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
Security
This module prevents path traversal, not allowing parent directory accessors to be used (i.e. “/usr/path/to/../file” or “../path/to/file” paths are not allowed). Paths accessed with this API must be either relative to one of the base directories or created with the path API.
See @tauri-apps/plugin-fs - Security for more information.
Paths
The file system plugin offers two ways of manipulating paths: the base directory and the path API.
-
base directory
Every API has an options argument that lets you define a baseDir that acts as the working directory of the operation.
import { readFile } from '@tauri-apps/plugin-fs'; const contents = await readFile('avatars/tauri.png', { baseDir: BaseDirectory.Home, });In the above example the ~/avatars/tauri.png file is read since we are using the Home base directory.
-
path API
Alternatively you can use the path APIs to perform path manipulations.
import { readFile } from '@tauri-apps/plugin-fs'; import * as path from '@tauri-apps/api/path'; const home = await path.homeDir(); const contents = await readFile(await path.join(home, 'avatars/tauri.png'));
Files
Create
Creates a file and returns a handle to it. If the file already exists, it is truncated.
import { create, BaseDirectory } from '@tauri-apps/plugin-fs';
const file = await create('foo/bar.txt', { baseDir: BaseDirectory.AppData });
await file.write(new TextEncoder().encode('Hello world'));
await file.close();
Note
Always call file.close() when you are done manipulating the file.
Write
The plugin offers separate APIs for writing text and binary files for performance.
-
text files
import { writeTextFile, BaseDirectory } from '@tauri-apps/plugin-fs'; const contents = JSON.stringify({ notifications: true }); await writeTextFile('config.json', contents, { baseDir: BaseDirectory.AppConfig, }); -
binary files
import { writeFile, BaseDirectory } from '@tauri-apps/plugin-fs'; const contents = new Uint8Array(); // fill a byte array await writeFile('config', contents, { baseDir: BaseDirectory.AppConfig, });
Open
Opens a file and returns a handle to it. With this API you have more control over how the file should be opened (read-only mode, write-only mode, append instead of overwrite, only create if it does not exist, etc).
Note
Always call file.close() when you are done manipulating the file.
-
read-only
This is the default mode.
import { open, BaseDirectory } from '@tauri-apps/plugin-fs'; const file = await open('foo/bar.txt', { read: true, baseDir: BaseDirectory.AppData, }); const stat = await file.stat(); const buf = new Uint8Array(stat.size); await file.read(buf); const textContents = new TextDecoder().decode(buf); await file.close(); -
write-only
import { open, BaseDirectory } from '@tauri-apps/plugin-fs'; const file = await open('foo/bar.txt', { write: true, baseDir: BaseDirectory.AppData, }); await file.write(new TextEncoder().encode('Hello world')); await file.close();By default the file is truncated on any
file.write()call. See the following example to learn how to append to the existing contents instead. -
append
import { open, BaseDirectory } from '@tauri-apps/plugin-fs'; const file = await open('foo/bar.txt', { append: true, baseDir: BaseDirectory.AppData, }); await file.write(new TextEncoder().encode('world')); await file.close();Note that
{ append: true }has the same effect as{ write: true, append: true }. -
truncate
When the
truncateoption is set and the file already exists, it will be truncated to length 0.import { open, BaseDirectory } from '@tauri-apps/plugin-fs'; const file = await open('foo/bar.txt', { write: true, truncate: true, baseDir: BaseDirectory.AppData, }); await file.write(new TextEncoder().encode('world')); await file.close();This option requires
writeto betrue.You can use it along the
appendoption if you want to rewrite an existing file using multiplefile.write()calls. -
create
By default the
openAPI only opens existing files. To create the file if it does not exist, opening it if it does, setcreatetotrue:import { open, BaseDirectory } from '@tauri-apps/plugin-fs'; const file = await open('foo/bar.txt', { write: true, create: true, baseDir: BaseDirectory.AppData, }); await file.write(new TextEncoder().encode('world')); await file.close();In order for the file to be created,
writeorappendmust also be set totrue.To fail if the file already exists, see
createNew. -
createNew
createNewworks similarly tocreate, but will fail if the file already exists.import { open, BaseDirectory } from '@tauri-apps/plugin-fs'; const file = await open('foo/bar.txt', { write: true, createNew: true, baseDir: BaseDirectory.AppData, }); await file.write(new TextEncoder().encode('world')); await file.close();In order for the file to be created,
writemust also be set totrue.
Read
The plugin offers separate APIs for reading text and binary files for performance.
-
text files
import { readTextFile, BaseDirectory } from '@tauri-apps/plugin-fs'; const configToml = await readTextFile('config.toml', { baseDir: BaseDirectory.AppConfig, });If the file is large you can stream its lines with the
readTextFileLinesAPI:import { readTextFileLines, BaseDirectory } from '@tauri-apps/plugin-fs'; const lines = await readTextFileLines('app.logs', { baseDir: BaseDirectory.AppLog, }); for await (const line of lines) { console.log(line); } -
binary files
import { readFile, BaseDirectory } from '@tauri-apps/plugin-fs'; const icon = await readFile('icon.png', { baseDir: BaseDirectory.Resources, });
Remove
Call remove() to delete a file. If the file does not exist, an error is returned.
import { remove, BaseDirectory } from '@tauri-apps/plugin-fs';
await remove('user.db', { baseDir: BaseDirectory.AppLocalData });
Copy
The copyFile function takes the source and destination paths. Note that you must configure each base directory separately.
import { copyFile, BaseDirectory } from '@tauri-apps/plugin-fs';
await copyFile('user.db', 'user.db.bk', {
fromPathBaseDir: BaseDirectory.AppLocalData,
toPathBaseDir: BaseDirectory.Temp,
});
In the above example the <app-local-data>/user.db file is copied to $TMPDIR/user.db.bk.
Exists
Use the exists() function to check if a file exists:
import { exists, BaseDirectory } from '@tauri-apps/plugin-fs';
const tokenExists = await exists('token', {
baseDir: BaseDirectory.AppLocalData,
});
Metadata
File metadata can be retrieved with the stat and the lstat functions. stat follows symlinks (and returns an error if the actual file it points to is not allowed by the scope) and lstat does not follow symlinks, returning the information of the symlink itself.
import { stat, BaseDirectory } from '@tauri-apps/plugin-fs';
const metadata = await stat('app.db', {
baseDir: BaseDirectory.AppLocalData,
});
Rename
The rename function takes the source and destination paths. Note that you must configure each base directory separately.
import { rename, BaseDirectory } from '@tauri-apps/plugin-fs';
await rename('user.db.bk', 'user.db', {
fromPathBaseDir: BaseDirectory.AppLocalData,
toPathBaseDir: BaseDirectory.Temp,
});
In the above example the <app-local-data>/user.db.bk file is renamed to $TMPDIR/user.db.
Truncate
Truncates or extends the specified file to reach the specified file length (defaults to 0).
- truncate to 0 length
import { truncate } from '@tauri-apps/plugin-fs';
await truncate('my_file.txt', 0, { baseDir: BaseDirectory.AppLocalData });
- truncate to a specific length
import {
truncate,
readTextFile,
writeTextFile,
BaseDirectory,
} from '@tauri-apps/plugin-fs';
const filePath = 'file.txt';
await writeTextFile(filePath, 'Hello World', {
baseDir: BaseDirectory.AppLocalData,
});
await truncate(filePath, 7, {
baseDir: BaseDirectory.AppLocalData,
});
const data = await readTextFile(filePath, {
baseDir: BaseDirectory.AppLocalData,
});
console.log(data); // "Hello W"
Directories
Create
To create a directory, call the mkdir function:
import { mkdir, BaseDirectory } from '@tauri-apps/plugin-fs';
await mkdir('images', {
baseDir: BaseDirectory.AppLocalData,
});
Read
The readDir function recursively lists the entries of a directory:
import { readDir, BaseDirectory } from '@tauri-apps/plugin-fs';
const entries = await readDir('users', { baseDir: BaseDirectory.AppLocalData });
Remove
Call remove() to delete a directory. If the directory does not exist, an error is returned.
import { remove, BaseDirectory } from '@tauri-apps/plugin-fs';
await remove('images', { baseDir: BaseDirectory.AppLocalData });
If the directory is not empty, the recursive option must be set to true:
import { remove, BaseDirectory } from '@tauri-apps/plugin-fs';
await remove('images', {
baseDir: BaseDirectory.AppLocalData,
recursive: true,
});
Exists
Use the exists() function to check if a directory exists:
import { exists, BaseDirectory } from '@tauri-apps/plugin-fs';
const tokenExists = await exists('images', {
baseDir: BaseDirectory.AppLocalData,
});
Metadata
Directory metadata can be retrieved with the stat and the lstat functions. stat follows symlinks (and returns an error if the actual file it points to is not allowed by the scope) and lstat does not follow symlinks, returning the information of the symlink itself.
import { stat, BaseDirectory } from '@tauri-apps/plugin-fs';
const metadata = await stat('databases', {
baseDir: BaseDirectory.AppLocalData,
});
Watching changes
To watch a directory or file for changes, use the watch or watchImmediate functions.
-
watch
watchis debounced so it only emits events after a certain delay:import { watch, BaseDirectory } from '@tauri-apps/plugin-fs'; await watch( 'app.log', (event) => { console.log('app.log event', event); }, { baseDir: BaseDirectory.AppLog, delayMs: 500, } ); -
watchImmediate
watchImmediateimmediately notifies listeners of an event:import { watchImmediate, BaseDirectory } from '@tauri-apps/plugin-fs'; await watchImmediate( 'logs', (event) => { console.log('logs directory event', event); }, { baseDir: BaseDirectory.AppLog, recursive: true, } );
By default watch operations on a directory are not recursive. Set the recursive option to true to recursively watch for changes on all sub-directories.
Note
The watch functions require the watch feature flag:
src-tauri/Cargo.toml
[dependencies]
tauri-plugin-fs = { version = "2.0.0", features = ["watch"] }
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
+"fs:default",
+ {
+"identifier": "fs:allow-exists",
+"allow": [{ "path": "$APPDATA/*" }]
+ }
]
}
Default Permission
This set of permissions describes the what kind of file system access the fs plugin has enabled or denied by default.
Granted Permissions
This default permission set enables read access to the application specific directories (AppConfig, AppData, AppLocalData, AppCache, AppLog) and all files and sub directories created in it. The location of these directories depends on the operating system, where the application is run.
In general these directories need to be manually created by the application at runtime, before accessing files or folders in it is possible.
Therefore, it is also allowed to create all of these folders via the mkdir command.
Denied Permissions
This default permission set prevents access to critical components of the Tauri application by default. On Windows the webview data folder access is denied.
This default permission set includes the following:
create-app-specific-dirsread-app-specific-dirs-recursivedeny-default
Permission Table
| Identifier | Description |
|---|---|
fs:allow-app-read-recursive |
This allows full recursive read access to the complete application folders, files and subdirectories. |
fs:allow-app-write-recursive |
This allows full recursive write access to the complete application folders, files and subdirectories. |
fs:allow-app-read |
This allows non-recursive read access to the application folders. |
fs:allow-app-write |
This allows non-recursive write access to the application folders. |
fs:allow-app-meta-recursive |
This allows full recursive read access to metadata of the application folders, including file listing and statistics. |
fs:allow-app-meta |
This allows non-recursive read access to metadata of the application folders, including file listing and statistics. |
fs:scope-app-recursive |
This scope permits recursive access to the complete application folders, including sub directories and files. |
fs:scope-app |
This scope permits access to all files and list content of top level directories in the application folders. |
fs:scope-app-index |
This scope permits to list all files and folders in the application directories. |
fs:allow-appcache-read-recursive |
This allows full recursive read access to the complete $APPCACHE folder, files and subdirectories. |
fs:allow-appcache-write-recursive |
This allows full recursive write access to the complete $APPCACHE folder, files and subdirectories. |
fs:allow-appcache-read |
This allows non-recursive read access to the $APPCACHE folder. |
fs:allow-appcache-write |
This allows non-recursive write access to the $APPCACHE folder. |
fs:allow-appcache-meta-recursive |
This allows full recursive read access to metadata of the $APPCACHE folder, including file listing and statistics. |
fs:allow-appcache-meta |
This allows non-recursive read access to metadata of the $APPCACHE folder, including file listing and statistics. |
fs:scope-appcache-recursive |
This scope permits recursive access to the complete $APPCACHE folder, including sub directories and files. |
fs:scope-appcache |
This scope permits access to all files and list content of top level directories in the $APPCACHE folder. |
fs:scope-appcache-index |
This scope permits to list all files and folders in the $APPCACHEfolder. |
fs:allow-appconfig-read-recursive |
This allows full recursive read access to the complete $APPCONFIG folder, files and subdirectories. |
fs:allow-appconfig-write-recursive |
This allows full recursive write access to the complete $APPCONFIG folder, files and subdirectories. |
fs:allow-appconfig-read |
This allows non-recursive read access to the $APPCONFIG folder. |
fs:allow-appconfig-write |
This allows non-recursive write access to the $APPCONFIG folder. |
fs:allow-appconfig-meta-recursive |
This allows full recursive read access to metadata of the $APPCONFIG folder, including file listing and statistics. |
fs:allow-appconfig-meta |
This allows non-recursive read access to metadata of the $APPCONFIG folder, including file listing and statistics. |
fs:scope-appconfig-recursive |
This scope permits recursive access to the complete $APPCONFIG folder, including sub directories and files. |
fs:scope-appconfig |
This scope permits access to all files and list content of top level directories in the $APPCONFIG folder. |
fs:scope-appconfig-index |
This scope permits to list all files and folders in the $APPCONFIGfolder. |
fs:allow-appdata-read-recursive |
This allows full recursive read access to the complete $APPDATA folder, files and subdirectories. |
fs:allow-appdata-write-recursive |
This allows full recursive write access to the complete $APPDATA folder, files and subdirectories. |
fs:allow-appdata-read |
This allows non-recursive read access to the $APPDATA folder. |
fs:allow-appdata-write |
This allows non-recursive write access to the $APPDATA folder. |
fs:allow-appdata-meta-recursive |
This allows full recursive read access to metadata of the $APPDATA folder, including file listing and statistics. |
fs:allow-appdata-meta |
This allows non-recursive read access to metadata of the $APPDATA folder, including file listing and statistics. |
fs:scope-appdata-recursive |
This scope permits recursive access to the complete $APPDATA folder, including sub directories and files. |
fs:scope-appdata |
This scope permits access to all files and list content of top level directories in the $APPDATA folder. |
fs:scope-appdata-index |
This scope permits to list all files and folders in the $APPDATAfolder. |
fs:allow-applocaldata-read-recursive |
This allows full recursive read access to the complete $APPLOCALDATA folder, files and subdirectories. |
fs:allow-applocaldata-write-recursive |
This allows full recursive write access to the complete $APPLOCALDATA folder, files and subdirectories. |
fs:allow-applocaldata-read |
This allows non-recursive read access to the $APPLOCALDATA folder. |
fs:allow-applocaldata-write |
This allows non-recursive write access to the $APPLOCALDATA folder. |
fs:allow-applocaldata-meta-recursive |
This allows full recursive read access to metadata of the $APPLOCALDATA folder, including file listing and statistics. |
fs:allow-applocaldata-meta |
This allows non-recursive read access to metadata of the $APPLOCALDATA folder, including file listing and statistics. |
fs:scope-applocaldata-recursive |
This scope permits recursive access to the complete $APPLOCALDATA folder, including sub directories and files. |
fs:scope-applocaldata |
This scope permits access to all files and list content of top level directories in the $APPLOCALDATA folder. |
fs:scope-applocaldata-index |
This scope permits to list all files and folders in the $APPLOCALDATAfolder. |
fs:allow-applog-read-recursive |
This allows full recursive read access to the complete $APPLOG folder, files and subdirectories. |
fs:allow-applog-write-recursive |
This allows full recursive write access to the complete $APPLOG folder, files and subdirectories. |
fs:allow-applog-read |
This allows non-recursive read access to the $APPLOG folder. |
fs:allow-applog-write |
This allows non-recursive write access to the $APPLOG folder. |
fs:allow-applog-meta-recursive |
This allows full recursive read access to metadata of the $APPLOG folder, including file listing and statistics. |
fs:allow-applog-meta |
This allows non-recursive read access to metadata of the $APPLOG folder, including file listing and statistics. |
fs:scope-applog-recursive |
This scope permits recursive access to the complete $APPLOG folder, including sub directories and files. |
fs:scope-applog |
This scope permits access to all files and list content of top level directories in the $APPLOG folder. |
fs:scope-applog-index |
This scope permits to list all files and folders in the $APPLOGfolder. |
fs:allow-audio-read-recursive |
This allows full recursive read access to the complete $AUDIO folder, files and subdirectories. |
fs:allow-audio-write-recursive |
This allows full recursive write access to the complete $AUDIO folder, files and subdirectories. |
fs:allow-audio-read |
This allows non-recursive read access to the $AUDIO folder. |
fs:allow-audio-write |
This allows non-recursive write access to the $AUDIO folder. |
fs:allow-audio-meta-recursive |
This allows full recursive read access to metadata of the $AUDIO folder, including file listing and statistics. |
fs:allow-audio-meta |
This allows non-recursive read access to metadata of the $AUDIO folder, including file listing and statistics. |
fs:scope-audio-recursive |
This scope permits recursive access to the complete $AUDIO folder, including sub directories and files. |
fs:scope-audio |
This scope permits access to all files and list content of top level directories in the $AUDIO folder. |
fs:scope-audio-index |
This scope permits to list all files and folders in the $AUDIOfolder. |
fs:allow-cache-read-recursive |
This allows full recursive read access to the complete $CACHE folder, files and subdirectories. |
fs:allow-cache-write-recursive |
This allows full recursive write access to the complete $CACHE folder, files and subdirectories. |
fs:allow-cache-read |
This allows non-recursive read access to the $CACHE folder. |
fs:allow-cache-write |
This allows non-recursive write access to the $CACHE folder. |
fs:allow-cache-meta-recursive |
This allows full recursive read access to metadata of the $CACHE folder, including file listing and statistics. |
fs:allow-cache-meta |
This allows non-recursive read access to metadata of the $CACHE folder, including file listing and statistics. |
fs:scope-cache-recursive |
This scope permits recursive access to the complete $CACHE folder, including sub directories and files. |
fs:scope-cache |
This scope permits access to all files and list content of top level directories in the $CACHE folder. |
fs:scope-cache-index |
This scope permits to list all files and folders in the $CACHEfolder. |
fs:allow-config-read-recursive |
This allows full recursive read access to the complete $CONFIG folder, files and subdirectories. |
fs:allow-config-write-recursive |
This allows full recursive write access to the complete $CONFIG folder, files and subdirectories. |
fs:allow-config-read |
This allows non-recursive read access to the $CONFIG folder. |
fs:allow-config-write |
This allows non-recursive write access to the $CONFIG folder. |
fs:allow-config-meta-recursive |
This allows full recursive read access to metadata of the $CONFIG folder, including file listing and statistics. |
fs:allow-config-meta |
This allows non-recursive read access to metadata of the $CONFIG folder, including file listing and statistics. |
fs:scope-config-recursive |
This scope permits recursive access to the complete $CONFIG folder, including sub directories and files. |
fs:scope-config |
This scope permits access to all files and list content of top level directories in the $CONFIG folder. |
fs:scope-config-index |
This scope permits to list all files and folders in the $CONFIGfolder. |
fs:allow-data-read-recursive |
This allows full recursive read access to the complete $DATA folder, files and subdirectories. |
fs:allow-data-write-recursive |
This allows full recursive write access to the complete $DATA folder, files and subdirectories. |
fs:allow-data-read |
This allows non-recursive read access to the $DATA folder. |
fs:allow-data-write |
This allows non-recursive write access to the $DATA folder. |
fs:allow-data-meta-recursive |
This allows full recursive read access to metadata of the $DATA folder, including file listing and statistics. |
fs:allow-data-meta |
This allows non-recursive read access to metadata of the $DATA folder, including file listing and statistics. |
fs:scope-data-recursive |
This scope permits recursive access to the complete $DATA folder, including sub directories and files. |
fs:scope-data |
This scope permits access to all files and list content of top level directories in the $DATA folder. |
fs:scope-data-index |
This scope permits to list all files and folders in the $DATAfolder. |
fs:allow-desktop-read-recursive |
This allows full recursive read access to the complete $DESKTOP folder, files and subdirectories. |
fs:allow-desktop-write-recursive |
This allows full recursive write access to the complete $DESKTOP folder, files and subdirectories. |
fs:allow-desktop-read |
This allows non-recursive read access to the $DESKTOP folder. |
fs:allow-desktop-write |
This allows non-recursive write access to the $DESKTOP folder. |
fs:allow-desktop-meta-recursive |
This allows full recursive read access to metadata of the $DESKTOP folder, including file listing and statistics. |
fs:allow-desktop-meta |
This allows non-recursive read access to metadata of the $DESKTOP folder, including file listing and statistics. |
fs:scope-desktop-recursive |
This scope permits recursive access to the complete $DESKTOP folder, including sub directories and files. |
fs:scope-desktop |
This scope permits access to all files and list content of top level directories in the $DESKTOP folder. |
fs:scope-desktop-index |
This scope permits to list all files and folders in the $DESKTOPfolder. |
fs:allow-document-read-recursive |
This allows full recursive read access to the complete $DOCUMENT folder, files and subdirectories. |
fs:allow-document-write-recursive |
This allows full recursive write access to the complete $DOCUMENT folder, files and subdirectories. |
fs:allow-document-read |
This allows non-recursive read access to the $DOCUMENT folder. |
fs:allow-document-write |
This allows non-recursive write access to the $DOCUMENT folder. |
fs:allow-document-meta-recursive |
This allows full recursive read access to metadata of the $DOCUMENT folder, including file listing and statistics. |
fs:allow-document-meta |
This allows non-recursive read access to metadata of the $DOCUMENT folder, including file listing and statistics. |
fs:scope-document-recursive |
This scope permits recursive access to the complete $DOCUMENT folder, including sub directories and files. |
fs:scope-document |
This scope permits access to all files and list content of top level directories in the $DOCUMENT folder. |
fs:scope-document-index |
This scope permits to list all files and folders in the $DOCUMENTfolder. |
fs:allow-download-read-recursive |
This allows full recursive read access to the complete $DOWNLOAD folder, files and subdirectories. |
fs:allow-download-write-recursive |
This allows full recursive write access to the complete $DOWNLOAD folder, files and subdirectories. |
fs:allow-download-read |
This allows non-recursive read access to the $DOWNLOAD folder. |
fs:allow-download-write |
This allows non-recursive write access to the $DOWNLOAD folder. |
fs:allow-download-meta-recursive |
This allows full recursive read access to metadata of the $DOWNLOAD folder, including file listing and statistics. |
fs:allow-download-meta |
This allows non-recursive read access to metadata of the $DOWNLOAD folder, including file listing and statistics. |
fs:scope-download-recursive |
This scope permits recursive access to the complete $DOWNLOAD folder, including sub directories and files. |
fs:scope-download |
This scope permits access to all files and list content of top level directories in the $DOWNLOAD folder. |
fs:scope-download-index |
This scope permits to list all files and folders in the $DOWNLOADfolder. |
fs:allow-exe-read-recursive |
This allows full recursive read access to the complete $EXE folder, files and subdirectories. |
fs:allow-exe-write-recursive |
This allows full recursive write access to the complete $EXE folder, files and subdirectories. |
fs:allow-exe-read |
This allows non-recursive read access to the $EXE folder. |
fs:allow-exe-write |
This allows non-recursive write access to the $EXE folder. |
fs:allow-exe-meta-recursive |
This allows full recursive read access to metadata of the $EXE folder, including file listing and statistics. |
fs:allow-exe-meta |
This allows non-recursive read access to metadata of the $EXE folder, including file listing and statistics. |
fs:scope-exe-recursive |
This scope permits recursive access to the complete $EXE folder, including sub directories and files. |
fs:scope-exe |
This scope permits access to all files and list content of top level directories in the $EXE folder. |
fs:scope-exe-index |
This scope permits to list all files and folders in the $EXEfolder. |
fs:allow-font-read-recursive |
This allows full recursive read access to the complete $FONT folder, files and subdirectories. |
fs:allow-font-write-recursive |
This allows full recursive write access to the complete $FONT folder, files and subdirectories. |
fs:allow-font-read |
This allows non-recursive read access to the $FONT folder. |
fs:allow-font-write |
This allows non-recursive write access to the $FONT folder. |
fs:allow-font-meta-recursive |
This allows full recursive read access to metadata of the $FONT folder, including file listing and statistics. |
fs:allow-font-meta |
This allows non-recursive read access to metadata of the $FONT folder, including file listing and statistics. |
fs:scope-font-recursive |
This scope permits recursive access to the complete $FONT folder, including sub directories and files. |
fs:scope-font |
This scope permits access to all files and list content of top level directories in the $FONT folder. |
fs:scope-font-index |
This scope permits to list all files and folders in the $FONTfolder. |
fs:allow-home-read-recursive |
This allows full recursive read access to the complete $HOME folder, files and subdirectories. |
fs:allow-home-write-recursive |
This allows full recursive write access to the complete $HOME folder, files and subdirectories. |
fs:allow-home-read |
This allows non-recursive read access to the $HOME folder. |
fs:allow-home-write |
This allows non-recursive write access to the $HOME folder. |
fs:allow-home-meta-recursive |
This allows full recursive read access to metadata of the $HOME folder, including file listing and statistics. |
fs:allow-home-meta |
This allows non-recursive read access to metadata of the $HOME folder, including file listing and statistics. |
fs:scope-home-recursive |
This scope permits recursive access to the complete $HOME folder, including sub directories and files. |
fs:scope-home |
This scope permits access to all files and list content of top level directories in the $HOME folder. |
fs:scope-home-index |
This scope permits to list all files and folders in the $HOMEfolder. |
fs:allow-localdata-read-recursive |
This allows full recursive read access to the complete $LOCALDATA folder, files and subdirectories. |
fs:allow-localdata-write-recursive |
This allows full recursive write access to the complete $LOCALDATA folder, files and subdirectories. |
fs:allow-localdata-read |
This allows non-recursive read access to the $LOCALDATA folder. |
fs:allow-localdata-write |
This allows non-recursive write access to the $LOCALDATA folder. |
fs:allow-localdata-meta-recursive |
This allows full recursive read access to metadata of the $LOCALDATA folder, including file listing and statistics. |
fs:allow-localdata-meta |
This allows non-recursive read access to metadata of the $LOCALDATA folder, including file listing and statistics. |
fs:scope-localdata-recursive |
This scope permits recursive access to the complete $LOCALDATA folder, including sub directories and files. |
fs:scope-localdata |
This scope permits access to all files and list content of top level directories in the $LOCALDATA folder. |
fs:scope-localdata-index |
This scope permits to list all files and folders in the $LOCALDATAfolder. |
fs:allow-log-read-recursive |
This allows full recursive read access to the complete $LOG folder, files and subdirectories. |
fs:allow-log-write-recursive |
This allows full recursive write access to the complete $LOG folder, files and subdirectories. |
fs:allow-log-read |
This allows non-recursive read access to the $LOG folder. |
fs:allow-log-write |
This allows non-recursive write access to the $LOG folder. |
fs:allow-log-meta-recursive |
This allows full recursive read access to metadata of the $LOG folder, including file listing and statistics. |
fs:allow-log-meta |
This allows non-recursive read access to metadata of the $LOG folder, including file listing and statistics. |
fs:scope-log-recursive |
This scope permits recursive access to the complete $LOG folder, including sub directories and files. |
fs:scope-log |
This scope permits access to all files and list content of top level directories in the $LOG folder. |
fs:scope-log-index |
This scope permits to list all files and folders in the $LOGfolder. |
fs:allow-picture-read-recursive |
This allows full recursive read access to the complete $PICTURE folder, files and subdirectories. |
fs:allow-picture-write-recursive |
This allows full recursive write access to the complete $PICTURE folder, files and subdirectories. |
fs:allow-picture-read |
This allows non-recursive read access to the $PICTURE folder. |
fs:allow-picture-write |
This allows non-recursive write access to the $PICTURE folder. |
fs:allow-picture-meta-recursive |
This allows full recursive read access to metadata of the $PICTURE folder, including file listing and statistics. |
fs:allow-picture-meta |
This allows non-recursive read access to metadata of the $PICTURE folder, including file listing and statistics. |
fs:scope-picture-recursive |
This scope permits recursive access to the complete $PICTURE folder, including sub directories and files. |
fs:scope-picture |
This scope permits access to all files and list content of top level directories in the $PICTURE folder. |
fs:scope-picture-index |
This scope permits to list all files and folders in the $PICTUREfolder. |
fs:allow-public-read-recursive |
This allows full recursive read access to the complete $PUBLIC folder, files and subdirectories. |
fs:allow-public-write-recursive |
This allows full recursive write access to the complete $PUBLIC folder, files and subdirectories. |
fs:allow-public-read |
This allows non-recursive read access to the $PUBLIC folder. |
fs:allow-public-write |
This allows non-recursive write access to the $PUBLIC folder. |
fs:allow-public-meta-recursive |
This allows full recursive read access to metadata of the $PUBLIC folder, including file listing and statistics. |
fs:allow-public-meta |
This allows non-recursive read access to metadata of the $PUBLIC folder, including file listing and statistics. |
fs:scope-public-recursive |
This scope permits recursive access to the complete $PUBLIC folder, including sub directories and files. |
fs:scope-public |
This scope permits access to all files and list content of top level directories in the $PUBLIC folder. |
fs:scope-public-index |
This scope permits to list all files and folders in the $PUBLICfolder. |
fs:allow-resource-read-recursive |
This allows full recursive read access to the complete $RESOURCE folder, files and subdirectories. |
fs:allow-resource-write-recursive |
This allows full recursive write access to the complete $RESOURCE folder, files and subdirectories. |
fs:allow-resource-read |
This allows non-recursive read access to the $RESOURCE folder. |
fs:allow-resource-write |
This allows non-recursive write access to the $RESOURCE folder. |
fs:allow-resource-meta-recursive |
This allows full recursive read access to metadata of the $RESOURCE folder, including file listing and statistics. |
fs:allow-resource-meta |
This allows non-recursive read access to metadata of the $RESOURCE folder, including file listing and statistics. |
fs:scope-resource-recursive |
This scope permits recursive access to the complete $RESOURCE folder, including sub directories and files. |
fs:scope-resource |
This scope permits access to all files and list content of top level directories in the $RESOURCE folder. |
fs:scope-resource-index |
This scope permits to list all files and folders in the $RESOURCEfolder. |
fs:allow-runtime-read-recursive |
This allows full recursive read access to the complete $RUNTIME folder, files and subdirectories. |
fs:allow-runtime-write-recursive |
This allows full recursive write access to the complete $RUNTIME folder, files and subdirectories. |
fs:allow-runtime-read |
This allows non-recursive read access to the $RUNTIME folder. |
fs:allow-runtime-write |
This allows non-recursive write access to the $RUNTIME folder. |
fs:allow-runtime-meta-recursive |
This allows full recursive read access to metadata of the $RUNTIME folder, including file listing and statistics. |
fs:allow-runtime-meta |
This allows non-recursive read access to metadata of the $RUNTIME folder, including file listing and statistics. |
fs:scope-runtime-recursive |
This scope permits recursive access to the complete $RUNTIME folder, including sub directories and files. |
fs:scope-runtime |
This scope permits access to all files and list content of top level directories in the $RUNTIME folder. |
fs:scope-runtime-index |
This scope permits to list all files and folders in the $RUNTIMEfolder. |
fs:allow-temp-read-recursive |
This allows full recursive read access to the complete $TEMP folder, files and subdirectories. |
fs:allow-temp-write-recursive |
This allows full recursive write access to the complete $TEMP folder, files and subdirectories. |
fs:allow-temp-read |
This allows non-recursive read access to the $TEMP folder. |
fs:allow-temp-write |
This allows non-recursive write access to the $TEMP folder. |
fs:allow-temp-meta-recursive |
This allows full recursive read access to metadata of the $TEMP folder, including file listing and statistics. |
fs:allow-temp-meta |
This allows non-recursive read access to metadata of the $TEMP folder, including file listing and statistics. |
fs:scope-temp-recursive |
This scope permits recursive access to the complete $TEMP folder, including sub directories and files. |
fs:scope-temp |
This scope permits access to all files and list content of top level directories in the $TEMP folder. |
fs:scope-temp-index |
This scope permits to list all files and folders in the $TEMPfolder. |
fs:allow-template-read-recursive |
This allows full recursive read access to the complete $TEMPLATE folder, files and subdirectories. |
fs:allow-template-write-recursive |
This allows full recursive write access to the complete $TEMPLATE folder, files and subdirectories. |
fs:allow-template-read |
This allows non-recursive read access to the $TEMPLATE folder. |
fs:allow-template-write |
This allows non-recursive write access to the $TEMPLATE folder. |
fs:allow-template-meta-recursive |
This allows full recursive read access to metadata of the $TEMPLATE folder, including file listing and statistics. |
fs:allow-template-meta |
This allows non-recursive read access to metadata of the $TEMPLATE folder, including file listing and statistics. |
fs:scope-template-recursive |
This scope permits recursive access to the complete $TEMPLATE folder, including sub directories and files. |
fs:scope-template |
This scope permits access to all files and list content of top level directories in the $TEMPLATE folder. |
fs:scope-template-index |
This scope permits to list all files and folders in the $TEMPLATEfolder. |
fs:allow-video-read-recursive |
This allows full recursive read access to the complete $VIDEO folder, files and subdirectories. |
fs:allow-video-write-recursive |
This allows full recursive write access to the complete $VIDEO folder, files and subdirectories. |
fs:allow-video-read |
This allows non-recursive read access to the $VIDEO folder. |
fs:allow-video-write |
This allows non-recursive write access to the $VIDEO folder. |
fs:allow-video-meta-recursive |
This allows full recursive read access to metadata of the $VIDEO folder, including file listing and statistics. |
fs:allow-video-meta |
This allows non-recursive read access to metadata of the $VIDEO folder, including file listing and statistics. |
fs:scope-video-recursive |
This scope permits recursive access to the complete $VIDEO folder, including sub directories and files. |
fs:scope-video |
This scope permits access to all files and list content of top level directories in the $VIDEO folder. |
fs:scope-video-index |
This scope permits to list all files and folders in the $VIDEOfolder. |
fs:allow-copy-file |
Enables the copy_file command without any pre-configured scope. |
fs:deny-copy-file |
Denies the copy_file command without any pre-configured scope. |
fs:allow-create |
Enables the create command without any pre-configured scope. |
fs:deny-create |
Denies the create command without any pre-configured scope. |
fs:allow-exists |
Enables the exists command without any pre-configured scope. |
fs:deny-exists |
Denies the exists command without any pre-configured scope. |
fs:allow-fstat |
Enables the fstat command without any pre-configured scope. |
fs:deny-fstat |
Denies the fstat command without any pre-configured scope. |
fs:allow-ftruncate |
Enables the ftruncate command without any pre-configured scope. |
fs:deny-ftruncate |
Denies the ftruncate command without any pre-configured scope. |
fs:allow-lstat |
Enables the lstat command without any pre-configured scope. |
fs:deny-lstat |
Denies the lstat command without any pre-configured scope. |
fs:allow-mkdir |
Enables the mkdir command without any pre-configured scope. |
fs:deny-mkdir |
Denies the mkdir command without any pre-configured scope. |
fs:allow-open |
Enables the open command without any pre-configured scope. |
fs:deny-open |
Denies the open command without any pre-configured scope. |
fs:allow-read |
Enables the read command without any pre-configured scope. |
fs:deny-read |
Denies the read command without any pre-configured scope. |
fs:allow-read-dir |
Enables the read_dir command without any pre-configured scope. |
fs:deny-read-dir |
Denies the read_dir command without any pre-configured scope. |
fs:allow-read-file |
Enables the read_file command without any pre-configured scope. |
fs:deny-read-file |
Denies the read_file command without any pre-configured scope. |
fs:allow-read-text-file |
Enables the read_text_file command without any pre-configured scope. |
fs:deny-read-text-file |
Denies the read_text_file command without any pre-configured scope. |
fs:allow-read-text-file-lines |
Enables the read_text_file_lines command without any pre-configured scope. |
fs:deny-read-text-file-lines |
Denies the read_text_file_lines command without any pre-configured scope. |
fs:allow-read-text-file-lines-next |
Enables the read_text_file_lines_next command without any pre-configured scope. |
fs:deny-read-text-file-lines-next |
Denies the read_text_file_lines_next command without any pre-configured scope. |
fs:allow-remove |
Enables the remove command without any pre-configured scope. |
fs:deny-remove |
Denies the remove command without any pre-configured scope. |
fs:allow-rename |
Enables the rename command without any pre-configured scope. |
fs:deny-rename |
Denies the rename command without any pre-configured scope. |
fs:allow-seek |
Enables the seek command without any pre-configured scope. |
fs:deny-seek |
Denies the seek command without any pre-configured scope. |
fs:allow-size |
Enables the size command without any pre-configured scope. |
fs:deny-size |
Denies the size command without any pre-configured scope. |
fs:allow-start-accessing-security-scoped-resource |
Enables the start_accessing_security_scoped_resource command without any pre-configured scope. |
fs:deny-start-accessing-security-scoped-resource |
Denies the start_accessing_security_scoped_resource command without any pre-configured scope. |
fs:allow-stat |
Enables the stat command without any pre-configured scope. |
fs:deny-stat |
Denies the stat command without any pre-configured scope. |
fs:allow-stop-accessing-security-scoped-resource |
Enables the stop_accessing_security_scoped_resource command without any pre-configured scope. |
fs:deny-stop-accessing-security-scoped-resource |
Denies the stop_accessing_security_scoped_resource command without any pre-configured scope. |
fs:allow-truncate |
Enables the truncate command without any pre-configured scope. |
fs:deny-truncate |
Denies the truncate command without any pre-configured scope. |
fs:allow-unwatch |
Enables the unwatch command without any pre-configured scope. |
fs:deny-unwatch |
Denies the unwatch command without any pre-configured scope. |
fs:allow-watch |
Enables the watch command without any pre-configured scope. |
fs:deny-watch |
Denies the watch command without any pre-configured scope. |
fs:allow-write |
Enables the write command without any pre-configured scope. |
fs:deny-write |
Denies the write command without any pre-configured scope. |
fs:allow-write-file |
Enables the write_file command without any pre-configured scope. |
fs:deny-write-file |
Denies the write_file command without any pre-configured scope. |
fs:allow-write-text-file |
Enables the write_text_file command without any pre-configured scope. |
fs:deny-write-text-file |
Denies the write_text_file command without any pre-configured scope. |
fs:create-app-specific-dirs |
This permissions allows to create the application specific directories. |
fs:deny-default |
This denies access to dangerous Tauri relevant files and folders by default. |
fs:deny-webview-data-linux |
This denies read access to the $APPLOCALDATA folder on linux as the webview data and configuration values are stored here. Allowing access can lead to sensitive information disclosure and should be well considered. |
fs:deny-webview-data-windows |
This denies read access to the $APPLOCALDATA/EBWebView folder on windows as the webview data and configuration values are stored here. Allowing access can lead to sensitive information disclosure and should be well considered. |
fs:read-all |
This enables all read related commands without any pre-configured accessible paths. |
fs:read-app-specific-dirs-recursive |
This permission allows recursive read functionality on the application specific base directories. |
fs:read-dirs |
This enables directory read and file metadata related commands without any pre-configured accessible paths. |
fs:read-files |
This enables file read related commands without any pre-configured accessible paths. |
fs:read-meta |
This enables all index or metadata related commands without any pre-configured accessible paths. |
fs:scope |
An empty permission you can use to modify the global scope.## Example``` |
| { | |
| "identifier": "read-documents", | |
| "windows": ["main"], | |
| "permissions": [ | |
| "fs:allow-read", | |
| { | |
| "identifier": "fs:scope", | |
| "allow": [ | |
| "$APPDATA/documents/**/*" | |
| ], | |
| "deny": [ | |
| "$APPDATA/documents/secret.txt" | |
| ] | |
| } | |
| ] | |
| } |
| `fs:write-all` | This enables all write related commands without any pre-configured accessible paths. |
| `fs:write-files` | This enables all file write related commands without any pre-configured accessible paths. |
### Scopes
This plugin permissions includes scopes for defining which paths are allowed or explicitly rejected. For more information on scopes, see the [Command Scopes](/security/scope/).
Each `allow` or `deny` scope must include an array listing all paths that should be allowed or denied. The scope entries are in the `{ path: string }` format.
Note
`deny` take precedence over `allow` so if a path is denied by a scope, it will be blocked at runtime even if it is allowed by another scope.
Scope entries can use `$<path>` variables to reference common system paths such as the home directory, the app resources directory and the config directory. The following table lists all common paths you can reference:
| Path | Variable |
| ----------------------------------------------------------------------------------------------- | ------------- |
| [appConfigDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#appconfigdir) | $APPCONFIG |
| [appDataDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#appdatadir) | $APPDATA |
| [appLocalDataDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#appLocaldatadir) | $APPLOCALDATA |
| [appcacheDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#appcachedir) | $APPCACHE |
| [applogDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#applogdir) | $APPLOG |
| [audioDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#audiodir) | $AUDIO |
| [cacheDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#cachedir) | $CACHE |
| [configDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#configdir) | $CONFIG |
| [dataDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#datadir) | $DATA |
| [localDataDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#localdatadir) | $LOCALDATA |
| [desktopDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#desktopdir) | $DESKTOP |
| [documentDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#documentdir) | $DOCUMENT |
| [downloadDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#downloaddir) | $DOWNLOAD |
| [executableDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#executabledir) | $EXE |
| [fontDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#fontdir) | $FONT |
| [homeDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#homedir) | $HOME |
| [pictureDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#picturedir) | $PICTURE |
| [publicDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#publicdir) | $PUBLIC |
| [runtimeDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#runtimedir) | $RUNTIME |
| [templateDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#templatedir) | $TEMPLATE |
| [videoDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#videodir) | $VIDEO |
| [resourceDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#resourcedir) | $RESOURCE |
| [tempDir](https://v2.tauri.app/reference/javascript/api/namespacepath/#tempdir) | $TEMP |
#### Examples
* global scope
To apply a scope to any `fs` command, use the `fs:scope` permission:
src-tauri/capabilities/default.json
```json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
{
"identifier": "fs:scope",
"allow": [{ "path": "$APPDATA" }, { "path": "$APPDATA/**/*" }]
}
]
}
To apply a scope to a specific fs command, use the the object form of permissions { "identifier": string, "allow"?: [], "deny"?: [] }:
src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
{
"identifier": "fs:allow-rename",
"allow": [{ "path": "$HOME/**/*" }]
},
{
"identifier": "fs:allow-rename",
"deny": [{ "path": "$HOME/.config/**/*" }]
},
{
"identifier": "fs:allow-exists",
"allow": [{ "path": "$APPDATA/*" }]
}
]
}
In the above example you can use the exists API using any $APPDATA sub path (does not include sub-directories) and the rename
Tip
If you are trying to access dotfiles (e.g. .gitignore) or dotfolders (e.g. .ssh) on Unix based systems, then you need to specify either the full path /home/user/.ssh/example or the glob after the dotfolder path component /home/user/.ssh/*.
If that does not work in your use case then you can configure the plugin to treat any component as a valid path literal.
src-tauri/tauri.conf.json
"plugins": {
"fs": {
"requireLiteralLeadingDot": false
}
}
The same option exists for app.security.assetProtocol.scope when you use the object form (not the array-only form). For real-world cases involving dot-directories, see tauri#13788.
Geolocation
Get and track the device's current position, including information about altitude, heading, and speed (if available).
Get and track the device’s current position, including information about altitude, heading, and speed (if available).
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the geolocation plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add geolocation -
yarn
yarn run tauri add geolocation -
pnpm
pnpm tauri add geolocation -
deno
deno task tauri add geolocation -
bun
bun tauri add geolocation -
cargo
cargo tauri add geolocation
-
-
Manual
npm run tauri add geolocation -
npm
yarn run tauri add geolocation -
yarn
pnpm tauri add geolocation -
pnpm
deno task tauri add geolocation -
deno
bun tauri add geolocation -
bun
cargo tauri add geolocation -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-geolocation --target 'cfg(any(target_os = "android", target_os = "ios"))' -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .setup(|app| { + #[cfg(mobile)] +app.handle().plugin(tauri_plugin_geolocation::init()); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
npm
npm install @tauri-apps/plugin-geolocation -
yarn
yarn add @tauri-apps/plugin-geolocation -
pnpm
pnpm add @tauri-apps/plugin-geolocation -
deno
deno add npm:@tauri-apps/plugin-geolocation -
bun
bun add @tauri-apps/plugin-geolocation
-
-
-
npm
npm install @tauri-apps/plugin-geolocation -
yarn
yarn add @tauri-apps/plugin-geolocation -
pnpm
pnpm add @tauri-apps/plugin-geolocation -
deno
deno add npm:@tauri-apps/plugin-geolocation -
bun
bun add @tauri-apps/plugin-geolocation
Configuration
iOS
Apple requires privacy descriptions to be specified in Info.plist for location information, where you should describe why your app needs to access it. Illustrated below is an example description:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Required to do XY</string>
</dict>
</plist>
Android
This plugin automatically adds the following permissions to your AndroidManifest.xml file:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
If your app requires GPS functionality to function, you should add the following to your AndroidManifest.xml file:
<uses-feature android:name="android.hardware.location.gps" android:required="true" />
The Google Play Store uses this property to decide whether it should show the app to devices without GPS capabilities.
Usage
The geolocation plugin is available in JavaScript.
import {
checkPermissions,
requestPermissions,
getCurrentPosition,
watchPosition,
} from '@tauri-apps/plugin-geolocation';
let permissions = await checkPermissions();
if (
permissions.location === 'prompt' ||
permissions.location === 'prompt-with-rationale'
) {
permissions = await requestPermissions(['location']);
}
if (permissions.location === 'granted') {
const pos = await getCurrentPosition();
await watchPosition(
{ enableHighAccuracy: true, timeout: 10000, maximumAge: 0 },
(pos) => {
console.log(pos);
}
);
}
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/mobile.json
{
"$schema": "../gen/schemas/mobile-schema.json",
"identifier": "mobile-capability",
"windows": ["main"],
"platforms": ["iOS", "android"],
"permissions": [
+"core:default",
+"geolocation:allow-check-permissions",
+"geolocation:allow-request-permissions",
+"geolocation:allow-get-current-position",
+"geolocation:allow-watch-position"
]
}
Permission Table
| Identifier | Description |
|---|---|
geolocation:allow-check-permissions |
Enables the check_permissions command without any pre-configured scope. |
geolocation:deny-check-permissions |
Denies the check_permissions command without any pre-configured scope. |
geolocation:allow-clear-permissions |
Enables the clear_permissions command without any pre-configured scope. |
geolocation:deny-clear-permissions |
Denies the clear_permissions command without any pre-configured scope. |
geolocation:allow-clear-watch |
Enables the clear_watch command without any pre-configured scope. |
geolocation:deny-clear-watch |
Denies the clear_watch command without any pre-configured scope. |
geolocation:allow-get-current-position |
Enables the get_current_position command without any pre-configured scope. |
geolocation:deny-get-current-position |
Denies the get_current_position command without any pre-configured scope. |
geolocation:allow-request-permissions |
Enables the request_permissions command without any pre-configured scope. |
geolocation:deny-request-permissions |
Denies the request_permissions command without any pre-configured scope. |
geolocation:allow-watch-position |
Enables the watch_position command without any pre-configured scope. |
geolocation:deny-watch-position |
Denies the watch_position command without any pre-configured scope. |
Global Shortcut
Register global shortcuts.
Register global shortcuts.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the global-shortcut plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add global-shortcut -
yarn
yarn run tauri add global-shortcut -
pnpm
pnpm tauri add global-shortcut -
deno
deno task tauri add global-shortcut -
bun
bun tauri add global-shortcut -
cargo
cargo tauri add global-shortcut
-
-
Manual
npm run tauri add global-shortcut -
npm
yarn run tauri add global-shortcut -
yarn
pnpm tauri add global-shortcut -
pnpm
deno task tauri add global-shortcut -
deno
bun tauri add global-shortcut -
bun
cargo tauri add global-shortcut -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-global-shortcut --target 'cfg(any(target_os = "macos", windows, target_os = "linux"))' -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
pub fn run() { tauri::Builder::default() .setup(|app| { + #[cfg(desktop)] +app.handle().plugin(tauri_plugin_global_shortcut::Builder::new().build()); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
npm
npm install @tauri-apps/plugin-global-shortcut -
yarn
yarn add @tauri-apps/plugin-global-shortcut -
pnpm
pnpm add @tauri-apps/plugin-global-shortcut -
deno
deno add npm:@tauri-apps/plugin-global-shortcut -
bun
bun add @tauri-apps/plugin-global-shortcut
-
-
-
npm
npm install @tauri-apps/plugin-global-shortcut -
yarn
yarn add @tauri-apps/plugin-global-shortcut -
pnpm
pnpm add @tauri-apps/plugin-global-shortcut -
deno
deno add npm:@tauri-apps/plugin-global-shortcut -
bun
bun add @tauri-apps/plugin-global-shortcut
Usage
The global-shortcut plugin is available in both JavaScript and Rust.
-
JavaScript
import { register } from '@tauri-apps/plugin-global-shortcut'; // when using `"withGlobalTauri": true`, you may use // const { register } = window.__TAURI__.globalShortcut; await register('CommandOrControl+Shift+C', () => { console.log('Shortcut triggered'); }); -
Rust
src-tauri/src/lib.rs
pub fn run() { tauri::Builder::default() .setup(|app| { #[cfg(desktop)] { use tauri_plugin_global_shortcut::{Code, GlobalShortcutExt, Modifiers, Shortcut, ShortcutState}; let ctrl_n_shortcut = Shortcut::new(Some(Modifiers::CONTROL), Code::KeyN); app.handle().plugin( tauri_plugin_global_shortcut::Builder::new().with_handler(move |_app, shortcut, event| { println!("{:?}", shortcut); if shortcut == &ctrl_n_shortcut { match event.state() { ShortcutState::Pressed => { println!("Ctrl-N Pressed!"); } ShortcutState::Released => { println!("Ctrl-N Released!"); } } } }) .build(), )?; app.global_shortcut().register(ctrl_n_shortcut)?; } Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
+"global-shortcut:allow-is-registered",
+"global-shortcut:allow-register",
+"global-shortcut:allow-unregister"
]
}
Default Permission
No features are enabled by default, as we believe the shortcuts can be inherently dangerous and it is application specific if specific shortcuts should be registered or unregistered.
Permission Table
| Identifier | Description |
|---|---|
global-shortcut:allow-is-registered |
Enables the is_registered command without any pre-configured scope. |
global-shortcut:deny-is-registered |
Denies the is_registered command without any pre-configured scope. |
global-shortcut:allow-register |
Enables the register command without any pre-configured scope. |
global-shortcut:deny-register |
Denies the register command without any pre-configured scope. |
global-shortcut:allow-register-all |
Enables the register_all command without any pre-configured scope. |
global-shortcut:deny-register-all |
Denies the register_all command without any pre-configured scope. |
global-shortcut:allow-unregister |
Enables the unregister command without any pre-configured scope. |
global-shortcut:deny-unregister |
Denies the unregister command without any pre-configured scope. |
global-shortcut:allow-unregister-all |
Enables the unregister_all command without any pre-configured scope. |
global-shortcut:deny-unregister-all |
Denies the unregister_all command without any pre-configured scope. |
Haptics
Haptic feedback and vibrations on Android and iOS
Haptic feedback and vibrations on Android and iOS.
There are no standards/requirements for vibration support on Android, so the feedback APIs may not work correctly on more affordable phones, including recently released ones.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the haptics plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add haptics -
yarn
yarn run tauri add haptics -
pnpm
pnpm tauri add haptics -
deno
deno task tauri add haptics -
bun
bun tauri add haptics -
cargo
cargo tauri add haptics
-
-
Manual
npm run tauri add haptics -
npm
yarn run tauri add haptics -
yarn
pnpm tauri add haptics -
pnpm
deno task tauri add haptics -
deno
bun tauri add haptics -
bun
cargo tauri add haptics -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-haptics --target 'cfg(any(target_os = "android", target_os = "ios"))' -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .setup(|app| { + #[cfg(mobile)] +app.handle().plugin(tauri_plugin_haptics::init()); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
npm
npm install @tauri-apps/plugin-haptics -
yarn
yarn add @tauri-apps/plugin-haptics -
pnpm
pnpm add @tauri-apps/plugin-haptics -
deno
deno add npm:@tauri-apps/plugin-haptics -
bun
bun add @tauri-apps/plugin-haptics
-
-
-
npm
npm install @tauri-apps/plugin-haptics -
yarn
yarn add @tauri-apps/plugin-haptics -
pnpm
pnpm add @tauri-apps/plugin-haptics -
deno
deno add npm:@tauri-apps/plugin-haptics -
bun
bun add @tauri-apps/plugin-haptics
Usage
The haptics plugin is available in JavaScript.
import {
vibrate,
impactFeedback,
notificationFeedback,
selectionFeedback,
} from '@tauri-apps/plugin-haptics';
await vibrate(1);
await impactFeedback('medium');
await notificationFeedback('warning');
await selectionFeedback();
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/mobile.json
{
"$schema": "../gen/schemas/mobile-schema.json",
"identifier": "mobile-capability",
"windows": ["main"],
"platforms": ["iOS", "android"],
"permissions": [
+"haptics:allow-impact-feedback",
+"haptics:allow-notification-feedback",
+"haptics:allow-selection-feedback",
+"haptics:allow-vibrate"
]
}
Permission Table
| Identifier | Description |
|---|---|
haptics:allow-impact-feedback |
Enables the impact_feedback command without any pre-configured scope. |
haptics:deny-impact-feedback |
Denies the impact_feedback command without any pre-configured scope. |
haptics:allow-notification-feedback |
Enables the notification_feedback command without any pre-configured scope. |
haptics:deny-notification-feedback |
Denies the notification_feedback command without any pre-configured scope. |
haptics:allow-selection-feedback |
Enables the selection_feedback command without any pre-configured scope. |
haptics:deny-selection-feedback |
Denies the selection_feedback command without any pre-configured scope. |
haptics:allow-vibrate |
Enables the vibrate command without any pre-configured scope. |
haptics:deny-vibrate |
Denies the vibrate command without any pre-configured scope. |
HTTP Client
Access the HTTP client written in Rust.
Make HTTP requests with the http plugin.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the http plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add http -
yarn
yarn run tauri add http -
pnpm
pnpm tauri add http -
deno
deno task tauri add http -
bun
bun tauri add http -
cargo
cargo tauri add http
-
-
Manual
npm run tauri add http -
npm
yarn run tauri add http -
yarn
pnpm tauri add http -
pnpm
deno task tauri add http -
deno
bun tauri add http -
bun
cargo tauri add http -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-http -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() +.plugin(tauri_plugin_http::init()) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
If you’d like to make http requests in JavaScript then install the npm package as well:
-
npm
npm install @tauri-apps/plugin-http -
yarn
yarn add @tauri-apps/plugin-http -
pnpm
pnpm add @tauri-apps/plugin-http -
deno
deno add npm:@tauri-apps/plugin-http -
bun
bun add @tauri-apps/plugin-http
-
-
-
npm
npm install @tauri-apps/plugin-http -
yarn
yarn add @tauri-apps/plugin-http -
pnpm
pnpm add @tauri-apps/plugin-http -
deno
deno add npm:@tauri-apps/plugin-http -
bun
bun add @tauri-apps/plugin-http
Usage
The HTTP plugin is available in both Rust as a reqwest re-export and JavaScript.
JavaScript
-
Configure the allowed URLs
src-tauri/capabilities/default.json
{ "permissions": [ { "identifier": "http:default", "allow": [{ "url": "https://*.tauri.app" }], "deny": [{ "url": "https://private.tauri.app" }] } ] }For more information, please see the documentation for Permissions Overview
-
Send a request
The
fetchmethod tries to be as close and compliant to thefetchWeb API as possible.import { fetch } from '@tauri-apps/plugin-http'; // Send a GET request const response = await fetch('http://test.tauri.app/data.json', { method: 'GET', }); console.log(response.status); // e.g. 200 console.log(response.statusText); // e.g. "OK"Note
Forbidden request headers are ignored by default. To use them you must enable the
unsafe-headersfeature flag:src-tauri/Cargo.toml
[dependencies] tauri-plugin-http = { version = "2", features = ["unsafe-headers"] }
Rust
In Rust you can utilize the reqwest crate re-exported by the plugin. For more details refer to reqwest docs.
use tauri_plugin_http::reqwest;
let res = reqwest::get("http://my.api.host/data.json").await;
println!("{:?}", res.status()); // e.g. 200
println!("{:?}", res.text().await); // e.g Ok("{ Content }")
Default Permission
This permission set configures what kind of fetch operations are available from the http plugin.
This enables all fetch operations but does not allow explicitly any origins to be fetched. This needs to be manually configured before usage.
Granted Permissions
All fetch operations are enabled.
This default permission set includes the following:
allow-fetchallow-fetch-cancelallow-fetch-sendallow-fetch-read-bodyallow-fetch-cancel-body
Permission Table
| Identifier | Description |
|---|---|
http:allow-fetch |
Enables the fetch command without any pre-configured scope. |
http:deny-fetch |
Denies the fetch command without any pre-configured scope. |
http:allow-fetch-cancel |
Enables the fetch_cancel command without any pre-configured scope. |
http:deny-fetch-cancel |
Denies the fetch_cancel command without any pre-configured scope. |
http:allow-fetch-cancel-body |
Enables the fetch_cancel_body command without any pre-configured scope. |
http:deny-fetch-cancel-body |
Denies the fetch_cancel_body command without any pre-configured scope. |
http:allow-fetch-read-body |
Enables the fetch_read_body command without any pre-configured scope. |
http:deny-fetch-read-body |
Denies the fetch_read_body command without any pre-configured scope. |
http:allow-fetch-send |
Enables the fetch_send command without any pre-configured scope. |
http:deny-fetch-send |
Denies the fetch_send command without any pre-configured scope. |
Localhost
Use a localhost server in production apps.
Expose your app’s assets through a localhost server instead of the default custom protocol.
Caution
This plugin brings considerable security risks and you should only use it if you know what you are doing. If in doubt, use the default custom protocol implementation.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the localhost plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add localhost -
yarn
yarn run tauri add localhost -
pnpm
pnpm tauri add localhost -
deno
deno task tauri add localhost -
bun
bun tauri add localhost -
cargo
cargo tauri add localhost
-
-
Manual
npm run tauri add localhost -
npm
yarn run tauri add localhost -
yarn
pnpm tauri add localhost -
pnpm
deno task tauri add localhost -
deno
bun tauri add localhost -
bun
cargo tauri add localhost -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-localhost -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() +.plugin(tauri_plugin_localhost::Builder::new().build()) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
-
Usage
The localhost plugin is available in Rust.
src-tauri/src/lib.rs
use tauri::{webview::WebviewWindowBuilder, WebviewUrl};
pub fn run() {
let port: u16 = 9527;
tauri::Builder::default()
.plugin(tauri_plugin_localhost::Builder::new(port).build())
.setup(move |app| {
let url = format!("http://localhost:{}", port).parse().unwrap();
WebviewWindowBuilder::new(app, "main".to_string(), WebviewUrl::External(url))
.title("Localhost Example")
.build()?;
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Logging
Configurable logging.
Configurable logging for your Tauri app.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the log plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add log -
yarn
yarn run tauri add log -
pnpm
pnpm tauri add log -
deno
deno task tauri add log -
bun
bun tauri add log -
cargo
cargo tauri add log
-
-
Manual
npm run tauri add log -
npm
yarn run tauri add log -
yarn
pnpm tauri add log -
pnpm
deno task tauri add log -
deno
bun tauri add log -
bun
cargo tauri add log -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-log -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() +.plugin(tauri_plugin_log::Builder::new().build()) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
npm
npm install @tauri-apps/plugin-log -
yarn
yarn add @tauri-apps/plugin-log -
pnpm
pnpm add @tauri-apps/plugin-log -
deno
deno add npm:@tauri-apps/plugin-log -
bun
bun add @tauri-apps/plugin-log
-
-
-
npm
npm install @tauri-apps/plugin-log -
yarn
yarn add @tauri-apps/plugin-log -
pnpm
pnpm add @tauri-apps/plugin-log -
deno
deno add npm:@tauri-apps/plugin-log -
bun
bun add @tauri-apps/plugin-log
Usage
-
First, you need to register the plugin with Tauri.
src-tauri/src/lib.rs
use tauri_plugin_log::{Target, TargetKind}; #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .plugin(tauri_plugin_log::Builder::new().build()) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Afterwards, all the plugin’s APIs are available through the JavaScript guest bindings:
import { warn, debug, trace, info, error, attachConsole, attachLogger, } from '@tauri-apps/plugin-log'; // when using `"withGlobalTauri": true`, you may use // const { warn, debug, trace, info, error, attachConsole, attachLogger } = window.__TAURI__.log;
Logging
-
JavaScript
Use one of the plugin’s
warn,debug,trace,infoorerrorAPIs to produce a log record from JavaScript code:import { warn, debug, trace, info, error } from '@tauri-apps/plugin-log'; trace('Trace'); info('Info'); error('Error');To automatically forward all
consolemessages to the log plugin you can rewrite them:import { warn, debug, trace, info, error } from '@tauri-apps/plugin-log'; function forwardConsole( fnName: 'log' | 'debug' | 'info' | 'warn' | 'error', logger: (message: string) => Promise<void> ) { const original = console[fnName]; console[fnName] = (message) => { original(message); logger(message); }; } forwardConsole('log', trace); forwardConsole('debug', debug); forwardConsole('info', info); forwardConsole('warn', warn); forwardConsole('error', error); -
Rust
To create your own logs on the Rust side you can use the
logcrate:log::error!("something bad happened!"); log::info!("Tauri is awesome!");Note that the
logcrate must be added to yourCargo.tomlfile:[dependencies] log = "0.4"
Log targets
The log plugin builder has a targets function that lets you configure common destination of all your application logs.
Note
By default the plugin logs to stdout and to a file in the application logs directory. To only use your own log targets, call clear_targets:
tauri_plugin_log::Builder::new()
.clear_targets()
.build()
Printing logs to the terminal
To forward all your logs to the terminal, enable the Stdout or Stderr targets:
tauri_plugin_log::Builder::new()
.target(tauri_plugin_log::Target::new(
tauri_plugin_log::TargetKind::Stdout,
))
.build()
This target is enabled by default.
Logging to the webview console
To view all your Rust logs in the webview console, enable the Webview target and run attachConsole in your frontend:
tauri_plugin_log::Builder::new()
.target(tauri_plugin_log::Target::new(
tauri_plugin_log::TargetKind::Webview,
))
.build()
import { attachConsole } from '@tauri-apps/plugin-log';
const detach = await attachConsole();
// call detach() if you do not want to print logs to the console anymore
Persisting logs
To write all logs to a file, you can use either the LogDir or the Folder targets.
LogDir:
tauri_plugin_log::Builder::new()
.target(tauri_plugin_log::Target::new(
tauri_plugin_log::TargetKind::LogDir {
file_name: Some("logs".to_string()),
},
))
.build()
When using the LogDir target, all logs are stored in the recommended log directory. The following table describes the location of the logs per platform:
| Platform | Value | Example |
|---|---|---|
| Linux | $XDG_DATA_HOME/{bundleIdentifier}/logs or $HOME/.local/share/{bundleIdentifier}/logs |
/home/alice/.local/share/com.tauri.dev/logs |
| macOS | {homeDir}/Library/Logs/{bundleIdentifier} |
/Users/Alice/Library/Logs/com.tauri.dev |
| Windows | {FOLDERID_LocalAppData}/{bundleIdentifier}/logs |
C:\Users\Alice\AppData\Local\com.tauri.dev\logs |
Folder:
The Folder target lets you write logs to a custom location in the filesystem.
tauri_plugin_log::Builder::new()
.target(tauri_plugin_log::Target::new(
tauri_plugin_log::TargetKind::Folder {
path: std::path::PathBuf::from("/path/to/logs"),
file_name: None,
},
))
.build()
The default file_name is the application name.
Configuring log file behavior
By default the log file gets discarded when it reaches the maximum size. The maximum file size can be configured via the builder’s max_file_size function:
tauri_plugin_log::Builder::new()
.max_file_size(50_000 /* bytes */)
.build()
Tauri can automatically rotate your log file when it reaches the size limit instead of discarding the previous file. This behavior can be configured using rotation_strategy:
tauri_plugin_log::Builder::new()
.rotation_strategy(tauri_plugin_log::RotationStrategy::KeepAll)
.build()
Filtering
By default all logs are processed. There are some mechanisms to reduce the amount of logs and filter only relevant information.
Maximum log level
To set a maximum log level, use the level function:
tauri_plugin_log::Builder::new()
.level(log::LevelFilter::Info)
.build()
In this example, debug and trace logs are discarded as they have a lower level than info.
It is also possible to define separate maximum levels for individual modules:
tauri_plugin_log::Builder::new()
.level(log::LevelFilter::Info)
// verbose logs only for the commands module
.level_for("my_crate_name::commands", log::LevelFilter::Trace)
.build()
Note that these APIs use the log crate, which must be added to your Cargo.toml file:
[dependencies]
log = "0.4"
Target filter
A filter function can be defined to discard unwanted logs by checking their metadata:
tauri_plugin_log::Builder::new()
// exclude logs with target `"hyper"`
.filter(|metadata| metadata.target() != "hyper")
.build()
Formatting
The log plugin formats each log record as DATE[TARGET][LEVEL] MESSAGE. A custom format function can be provided with format:
tauri_plugin_log::Builder::new()
.format(|out, message, record| {
out.finish(format_args!(
"[{} {}] {}",
record.level(),
record.target(),
message
))
})
.build()
Applying a different format to targets
You can specify your own log format for specific targets by using the format method on tauri_plugin_log::Target. You may also wish to call clear_format on the builder to remove the default formatter, which is applied to all targets:
tauri_plugin_log::Builder::new()
.clear_format()
.targets([
tauri_plugin_log::Target::new(
tauri_plugin_log::TargetKind::Stdout
)
.format(move |out, message, record| {
// custom formatter for stdout
}),
tauri_plugin_log::Target::new(
tauri_plugin_log::TargetKind::LogDir { file_name: None }
)
.format(move |out, message, record| {
// custom formatter for log files
}),
])
.build(),
Log dates
By default the log plugin uses the UTC timezone to format dates but you can configure it to use the local timezone with timezone_strategy:
tauri_plugin_log::Builder::new()
.timezone_strategy(tauri_plugin_log::TimezoneStrategy::UseLocal)
.build()
Permissions
By default, all plugin commands are blocked and cannot be accessed. You must define a list of permissions in your capabilities configuration.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "Capability for the main window",
"windows": ["main"],
+"permissions": ["log:default"]
}
Default Permission
Allows the log command
This default permission set includes the following:
allow-log
Permission Table
| Identifier | Description |
|---|---|
log:allow-log |
Enables the log command without any pre-configured scope. |
log:deny-log |
Denies the log command without any pre-configured scope. |
NFC
Read and write NFC tags on Android and iOS.
Read and write NFC tags on Android and iOS.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the nfc plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add nfc -
yarn
yarn run tauri add nfc -
pnpm
pnpm tauri add nfc -
bun
bun tauri add nfc -
cargo
cargo tauri add nfc
-
-
Manual
npm run tauri add nfc -
npm
yarn run tauri add nfc -
yarn
pnpm tauri add nfc -
pnpm
bun tauri add nfc -
bun
cargo tauri add nfc -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-nfc --target 'cfg(any(target_os = "android", target_os = "ios"))' -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .setup(|app| { + #[cfg(mobile)] +app.handle().plugin(tauri_plugin_nfc::init()); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
npm
npm install @tauri-apps/plugin-nfc -
yarn
yarn add @tauri-apps/plugin-nfc -
pnpm
pnpm add @tauri-apps/plugin-nfc -
deno
deno add npm:@tauri-apps/plugin-nfc -
bun
bun add @tauri-apps/plugin-nfc
-
-
-
npm
npm install @tauri-apps/plugin-nfc -
yarn
yarn add @tauri-apps/plugin-nfc -
pnpm
pnpm add @tauri-apps/plugin-nfc -
deno
deno add npm:@tauri-apps/plugin-nfc -
bun
bun add @tauri-apps/plugin-nfc
Configuration
The NFC plugin requires native configuration for iOS.
iOS
To access the NFC APIs on iOS you must adjust the target iOS version, configure a usage description on the Info.plist file and add the NFC capability to your application.
Target IOS version
The NFC plugin requires iOS 14+. This is the default for Tauri applications created with Tauri CLI v2.8 and above, but you can edit your Xcode project to configure it.
In the src-tauri/gen/apple/<project-name>.xcodeproj/project.pbxproj file, set all IPHONEOS_DEPLOYMENT_TARGET properties to 14.0:
src-tauri/gen/apple/<project-name>.xcodeproj/project.pbxproj
/* Begin XCBuildConfiguration section */
1234567890ABCDEF12345678 /* release */ = {
isa = XCBuildConfiguration;
buildSettings = {
/* ... */
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
};
name = release;
};
ABCDEF1234567890ABCDEF12 /* debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
/* ... */
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
};
name = debug;
};
Alternatively you can set the deployment target from Xcode in the General > Minimum Deployments > iOS configuration.
Info.plist
On iOS the NFC plugin requires the NFCReaderUsageDescription information property list value, which should describe why your app needs to scan or write to NFC tags.
In the src-tauri/Info.ios.plist file, add the following snippet:
src-tauri/Info.ios.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NFCReaderUsageDescription</key>
<string>Read and write various NFC tags</string>
</dict>
</plist>
NFC Capability
Additionally iOS requires the NFC capability to be associated with your application.
The capability can be added in Xcode in the project configuration’s “Signing & Capabilities” tab by clicking the “+ Capability” button and selecting the “Near Field Communication Tag Reading” capability (see Add a capability to a target for more information) or by adding the following configuration to the gen/apple/<app-name>_iOS/<app-name>_iOS.entitlements file:
gen/apple/<app-name>_iOS/<app-name>_iOS.entitlements
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
<string>TAG</string>
</array>
</dict>
</plist>
Usage
The NFC plugin is available in both JavaScript and Rust, allowing you to scan and write to NFC tags.
Checking if NFC is supported
Not every mobile device has the capability to scan NFC tags, so you should check for availability before using the scan and write APIs.
-
JavaScript
import { isAvailable } from '@tauri-apps/plugin-nfc'; const canScanNfc = await isAvailable(); -
Rust
tauri::Builder::default() .setup(|app| { #[cfg(mobile)] { use tauri_plugin_nfc::NfcExt; app.handle().plugin(tauri_plugin_nfc::init()); let can_scan_nfc = app.nfc().is_available()?; } Ok(()) })
Scanning NFC tags
The plugin can scan either generic NFC tags or NFC tags with a NDEF (NFC Data Exchange Format) message, which is a standard format to encapsulate typed data in an NFC tag.
-
JavaScript
import { scan } from '@tauri-apps/plugin-nfc'; const scanType = { type: 'ndef', // or 'tag', }; const options = { keepSessionAlive: false, // configure the messages displayed in the "Scan NFC" dialog on iOS message: 'Scan a NFC tag', successMessage: 'NFC tag successfully scanned', }; const tag = await scan(scanType, options); -
Rust
tauri::Builder::default() .setup(|app| { #[cfg(mobile)] { use tauri_plugin_nfc::NfcExt; app.handle().plugin(tauri_plugin_nfc::init()); let tag = app .nfc() .scan(tauri_plugin_nfc::ScanRequest { kind: tauri_plugin_nfc::ScanKind::Ndef { mime_type: None, uri: None, tech_list: None, }, keep_session_alive: false, })? .tag; } Ok(()) })
Note
The keepSessionAlive option can be used to directly write to the scanned NFC tag later.
If you do not provide that option, the session is recreated on the next write() call, which means the app will try to rescan the tag.
Filters
The NFC scanner can also filter tags with a specific URI format, mime type or NFC tag technologies. In this case, the scan will only detect tags that matches the provided filters.
Note
Filtering is only available on Android, so you should always check the scanned NFC tag contents.
The mime type is case sensitive and must be provided with lower case letters.
-
JavaScript
import { scan, TechKind } from '@tauri-apps/plugin-nfc'; const techLists = [ // capture anything using NfcF [TechKind.NfcF], // capture all MIFARE Classics with NDEF payloads [TechKind.NfcA, TechKind.MifareClassic, TechKind.Ndef], ]; const tag = await scan({ type: 'ndef', // or 'tag' mimeType: 'text/plain', uri: { scheme: 'https', host: 'my.domain.com', pathPrefix: '/app', }, techLists, }); -
Rust
tauri::Builder::default() .setup(|app| { #[cfg(mobile)] { use tauri_plugin_nfc::NfcExt; app.handle().plugin(tauri_plugin_nfc::init()); let tag = app .nfc() .scan(tauri_plugin_nfc::ScanRequest { kind: tauri_plugin_nfc::ScanKind::Ndef { mime_type: Some("text/plain".to_string()), uri: Some(tauri_plugin_nfc::UriFilter { scheme: Some("https".to_string()), host: Some("my.domain.com".to_string()), path_prefix: Some("/app".to_string()), }), tech_list: Some(vec![ vec![tauri_plugin_nfc::TechKind::Ndef], ]), }, })? .tag; } Ok(()) })
Writing to NFC tags
The write API can be used to write a payload to a NFC tag. If there’s no scanned tag with keepSessionAlive: true, the application will first scan an NFC tag.
-
JavaScript
import { write, textRecord, uriRecord } from '@tauri-apps/plugin-nfc'; const payload = [uriRecord('https://tauri.app'), textRecord('some payload')]; const options = { // the kind is only required if you do not have a scanned tag session alive // its format is the same as the argument provided to scan() kind: { type: 'ndef', }, // configure the messages displayed in the "Scan NFC" dialog on iOS message: 'Scan a NFC tag', successfulReadMessage: 'NFC tag successfully scanned', successMessage: 'NFC tag successfully written', }; await write(payload, options); -
Rust
Caution
The Rust API currently only provides a low level interface for writing NFC payloads.
The API will be enhanced soon.
tauri::Builder::default() .setup(|app| { #[cfg(mobile)] { use tauri_plugin_nfc::NfcExt; app.handle().plugin(tauri_plugin_nfc::init()); app .nfc() .write(vec![ tauri_plugin_nfc::NfcRecord { format: tauri_plugin_nfc::NFCTypeNameFormat::NfcWellKnown, kind: vec![0x55], // URI record id: vec![], payload: vec![], // insert payload here } ])?; } Ok(()) })
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/default.json
{
"permissions": [
...,
+"nfc:default",
]
}
Default Permission
This permission set configures what kind of operations are available from the nfc plugin.
Granted Permissions
Checking if the NFC functionality is available and scanning nearby tags is allowed. Writing to tags needs to be manually enabled.
This default permission set includes the following:
allow-is-availableallow-scan
Permission Table
| Identifier | Description |
|---|---|
nfc:allow-is-available |
Enables the is_available command without any pre-configured scope. |
nfc:deny-is-available |
Denies the is_available command without any pre-configured scope. |
nfc:allow-scan |
Enables the scan command without any pre-configured scope. |
nfc:deny-scan |
Denies the scan command without any pre-configured scope. |
nfc:allow-write |
Enables the write command without any pre-configured scope. |
nfc:deny-write |
Denies the write command without any pre-configured scope. |
Notifications
Send native notifications to the user.
Send native notifications to your user using the notification plugin.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | Only works for installed apps. Shows powershell name & icon in development. | |
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the notifications plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add notification -
yarn
yarn run tauri add notification -
pnpm
pnpm tauri add notification -
deno
deno task tauri add notification -
bun
bun tauri add notification -
cargo
cargo tauri add notification
-
-
Manual
npm run tauri add notification -
npm
yarn run tauri add notification -
yarn
pnpm tauri add notification -
pnpm
deno task tauri add notification -
deno
bun tauri add notification -
bun
cargo tauri add notification -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-notification -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() +.plugin(tauri_plugin_notification::init()) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
If you’d like to use notifications in JavaScript then install the npm package as well:
-
npm
npm install @tauri-apps/plugin-notification -
yarn
yarn add @tauri-apps/plugin-notification -
pnpm
pnpm add @tauri-apps/plugin-notification -
deno
deno add npm:@tauri-apps/plugin-notification -
bun
bun add @tauri-apps/plugin-notification
-
-
-
npm
npm install @tauri-apps/plugin-notification -
yarn
yarn add @tauri-apps/plugin-notification -
pnpm
pnpm add @tauri-apps/plugin-notification -
deno
deno add npm:@tauri-apps/plugin-notification -
bun
bun add @tauri-apps/plugin-notification
Usage
Here are a few examples of how to use the notification plugin:
- Send notification to users
- Add an action to a notification
- Add an attachment to a notification
- Send a notification in a specific channel
The notification plugin is available in both JavaScript and Rust.
Send Notification
Follow these steps to send a notification:
-
Check if permission is granted
-
Request permission if not granted
-
Send the notification
-
JavaScript
import { isPermissionGranted, requestPermission, sendNotification, } from '@tauri-apps/plugin-notification'; // when using `"withGlobalTauri": true`, you may use // const { isPermissionGranted, requestPermission, sendNotification, } = window.__TAURI__.notification; // Do you have permission to send a notification? let permissionGranted = await isPermissionGranted(); // If not we need to request it if (!permissionGranted) { const permission = await requestPermission(); permissionGranted = permission === 'granted'; } // Once permission has been granted we can send the notification if (permissionGranted) { sendNotification({ title: 'Tauri', body: 'Tauri is awesome!' }); } -
Rust
tauri::Builder::default() .plugin(tauri_plugin_notification::init()) .setup(|app| { use tauri_plugin_notification::NotificationExt; app.notification() .builder() .title("Tauri") .body("Tauri is awesome") .show() .unwrap(); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application");
Actions
Mobile Only
The Actions API is only available on mobile platforms.
Actions add interactive buttons and inputs to notifications. Use them to create a responsive experience for your users.
Register Action Types
Register action types to define interactive elements:
import { registerActionTypes } from '@tauri-apps/plugin-notification';
await registerActionTypes([
{
id: 'messages',
actions: [
{
id: 'reply',
title: 'Reply',
input: true,
inputButtonTitle: 'Send',
inputPlaceholder: 'Type your reply...',
},
{
id: 'mark-read',
title: 'Mark as Read',
foreground: false,
},
],
},
]);
Action Properties
| Property | Description |
|---|---|
id |
Unique identifier for the action |
title |
Display text for the action button |
requiresAuthentication |
Requires device authentication |
foreground |
Brings app to foreground when triggered |
destructive |
Shows action in red on iOS |
input |
Enables text input |
inputButtonTitle |
Text for input submit button |
inputPlaceholder |
Placeholder text for input field |
Listen for Actions
Listen to user interactions with notification actions:
import { onAction } from '@tauri-apps/plugin-notification';
await onAction((notification) => {
console.log('Action performed:', notification);
});
Attachments
Attachments add media content to notifications. Support varies by platform.
import { sendNotification } from '@tauri-apps/plugin-notification';
sendNotification({
title: 'New Image',
body: 'Check out this picture',
attachments: [
{
id: 'image-1',
url: 'asset:///notification-image.jpg',
},
],
});
Attachment Properties
| Property | Description |
|---|---|
id |
Unique identifier |
url |
Content URL using asset:// or file:// protocol |
Note: Test attachments on your target platforms to ensure compatibility.
Channels
Channels organize notifications into categories with different behaviors. While primarily used on Android, they provide a consistent API across platforms.
Create a Channel
import {
createChannel,
Importance,
Visibility,
} from '@tauri-apps/plugin-notification';
await createChannel({
id: 'messages',
name: 'Messages',
description: 'Notifications for new messages',
importance: Importance.High,
visibility: Visibility.Private,
lights: true,
lightColor: '#ff0000',
vibration: true,
sound: 'notification_sound',
});
Channel Properties
| Property | Description |
|---|---|
id |
Unique identifier |
name |
Display name |
description |
Purpose description |
importance |
Priority level (None, Min, Low, Default, High) |
visibility |
Privacy setting (Secret, Private, Public) |
lights |
Enable notification LED (Android) |
lightColor |
LED color (Android) |
vibration |
Enable vibrations |
sound |
Custom sound filename |
Managing Channels
List existing channels:
import { channels } from '@tauri-apps/plugin-notification';
const existingChannels = await channels();
Remove a channel:
import { removeChannel } from '@tauri-apps/plugin-notification';
await removeChannel('messages');
Using Channels
Send a notification using a channel:
import { sendNotification } from '@tauri-apps/plugin-notification';
sendNotification({
title: 'New Message',
body: 'You have a new message',
channelId: 'messages',
});
Note: Create channels before sending notifications that reference them. Invalid channel IDs prevent notifications from displaying.
Security Considerations
Aside from normal sanitization procedures of user input there are currently no known security considerations.
Default Permission
This permission set configures which notification features are by default exposed.
Granted Permissions
It allows all notification related features.
This default permission set includes the following:
allow-is-permission-grantedallow-request-permissionallow-notifyallow-register-action-typesallow-register-listenerallow-cancelallow-get-pendingallow-remove-activeallow-get-activeallow-check-permissionsallow-showallow-batchallow-list-channelsallow-delete-channelallow-create-channelallow-permission-state
Permission Table
| Identifier | Description |
|---|---|
notification:allow-batch |
Enables the batch command without any pre-configured scope. |
notification:deny-batch |
Denies the batch command without any pre-configured scope. |
notification:allow-cancel |
Enables the cancel command without any pre-configured scope. |
notification:deny-cancel |
Denies the cancel command without any pre-configured scope. |
notification:allow-check-permissions |
Enables the check_permissions command without any pre-configured scope. |
notification:deny-check-permissions |
Denies the check_permissions command without any pre-configured scope. |
notification:allow-create-channel |
Enables the create_channel command without any pre-configured scope. |
notification:deny-create-channel |
Denies the create_channel command without any pre-configured scope. |
notification:allow-delete-channel |
Enables the delete_channel command without any pre-configured scope. |
notification:deny-delete-channel |
Denies the delete_channel command without any pre-configured scope. |
notification:allow-get-active |
Enables the get_active command without any pre-configured scope. |
notification:deny-get-active |
Denies the get_active command without any pre-configured scope. |
notification:allow-get-pending |
Enables the get_pending command without any pre-configured scope. |
notification:deny-get-pending |
Denies the get_pending command without any pre-configured scope. |
notification:allow-is-permission-granted |
Enables the is_permission_granted command without any pre-configured scope. |
notification:deny-is-permission-granted |
Denies the is_permission_granted command without any pre-configured scope. |
notification:allow-list-channels |
Enables the list_channels command without any pre-configured scope. |
notification:deny-list-channels |
Denies the list_channels command without any pre-configured scope. |
notification:allow-notify |
Enables the notify command without any pre-configured scope. |
notification:deny-notify |
Denies the notify command without any pre-configured scope. |
notification:allow-permission-state |
Enables the permission_state command without any pre-configured scope. |
notification:deny-permission-state |
Denies the permission_state command without any pre-configured scope. |
notification:allow-register-action-types |
Enables the register_action_types command without any pre-configured scope. |
notification:deny-register-action-types |
Denies the register_action_types command without any pre-configured scope. |
notification:allow-register-listener |
Enables the register_listener command without any pre-configured scope. |
notification:deny-register-listener |
Denies the register_listener command without any pre-configured scope. |
notification:allow-remove-active |
Enables the remove_active command without any pre-configured scope. |
notification:deny-remove-active |
Denies the remove_active command without any pre-configured scope. |
notification:allow-request-permission |
Enables the request_permission command without any pre-configured scope. |
notification:deny-request-permission |
Denies the request_permission command without any pre-configured scope. |
notification:allow-show |
Enables the show command without any pre-configured scope. |
notification:deny-show |
Denies the show command without any pre-configured scope. |
Opener
Open files and URLs in external applications.
This plugin allows you to open files and URLs in a specified, or the default, application. It also supports “revealing” files in the system’s file explorer.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | Only allows to open URLs via open |
|
| ios | Only allows to open URLs via open |
Setup
Install the opener plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add opener -
yarn
yarn run tauri add opener -
pnpm
pnpm tauri add opener -
deno
deno task tauri add opener -
bun
bun tauri add opener -
cargo
cargo tauri add opener
-
-
Manual
npm run tauri add opener -
npm
yarn run tauri add opener -
yarn
pnpm tauri add opener -
pnpm
deno task tauri add opener -
deno
bun tauri add opener -
bun
cargo tauri add opener -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-opener -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() +.plugin(tauri_plugin_opener::init()) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
npm
npm install @tauri-apps/plugin-opener -
yarn
yarn add @tauri-apps/plugin-opener -
pnpm
pnpm add @tauri-apps/plugin-opener -
deno
deno add npm:@tauri-apps/plugin-opener -
bun
bun add @tauri-apps/plugin-opener
-
-
-
npm
npm install @tauri-apps/plugin-opener -
yarn
yarn add @tauri-apps/plugin-opener -
pnpm
pnpm add @tauri-apps/plugin-opener -
deno
deno add npm:@tauri-apps/plugin-opener -
bun
bun add @tauri-apps/plugin-opener
Usage
The opener plugin is available in both JavaScript and Rust.
-
JavaScript
import { openPath, openUrl } from '@tauri-apps/plugin-opener'; // when using `"withGlobalTauri": true`, you may use // const { openPath } = window.__TAURI__.opener; // opens a file using the default program: await openPath('/path/to/file'); // opens a file using `vlc` command on Windows: await openPath('C:/path/to/file', 'vlc'); // opens a URL using the default program: await openUrl('https://tauri.app'); -
Rust
Note that
appis an instance ofApporAppHandle.use tauri_plugin_opener::OpenerExt; // opens a file using the default program: app.opener().open_path("/path/to/file", None::<&str>); // opens a file using `vlc` command on Windows: app.opener().open_path("C:/path/to/file", Some("vlc")); // opens a URL using the default program: app.opener().open_url("https://tauri.app", None::<&str>);
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
Below are two example scope configurations. Both path and url use the glob pattern syntax to define allowed file paths and URLs.
First, an example on how to add permissions to specific paths for the openPath() function:
src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "Capability for the main window",
"windows": ["main"],
+"permissions": [
+ {
+"identifier": "opener:allow-open-path",
+"allow": [
+ {
+"path": "/path/to/file"
+ },
+ {
+"path": "$APPDATA/file"
+ }
]
}
]
}
Lastly, an example on how to add permissions for the exact https://tauri.app URL and all URLs on a custom protocol (must be known to the OS) for the openUrl() function:
src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "Capability for the main window",
"windows": ["main"],
+"permissions": [
+ {
+"identifier": "opener:allow-open-url",
+"allow": [
+ {
+"url": "https://tauri.app"
+ },
+ {
+"url": "custom:*"
+ }
]
}
]
}
Default Permission
This permission set allows opening mailto:, tel:, https:// and http:// urls using their default application as well as reveal file in directories using default file explorer
This default permission set includes the following:
allow-open-urlallow-reveal-item-in-dirallow-default-urls
Permission Table
| Identifier | Description |
|---|---|
opener:allow-default-urls |
This enables opening mailto:, tel:, https:// and http:// urls using their default application. |
opener:allow-open-path |
Enables the open_path command without any pre-configured scope. |
opener:deny-open-path |
Denies the open_path command without any pre-configured scope. |
opener:allow-open-url |
Enables the open_url command without any pre-configured scope. |
opener:deny-open-url |
Denies the open_url command without any pre-configured scope. |
opener:allow-reveal-item-in-dir |
Enables the reveal_item_in_dir command without any pre-configured scope. |
opener:deny-reveal-item-in-dir |
Denies the reveal_item_in_dir command without any pre-configured scope. |
OS Information
Read information about the operating system.
Read information about the operating system using the OS Information plugin.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the OS Information plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add os -
yarn
yarn run tauri add os -
pnpm
pnpm tauri add os -
deno
deno task tauri add os -
bun
bun tauri add os -
cargo
cargo tauri add os
-
-
Manual
npm run tauri add os -
npm
yarn run tauri add os -
yarn
pnpm tauri add os -
pnpm
deno task tauri add os -
deno
bun tauri add os -
bun
cargo tauri add os -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-os -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() +.plugin(tauri_plugin_os::init()) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
If you’d like to use in JavaScript then install the npm package as well:
-
npm
npm install @tauri-apps/plugin-os -
yarn
yarn add @tauri-apps/plugin-os -
pnpm
pnpm add @tauri-apps/plugin-os -
deno
deno add npm:@tauri-apps/plugin-os -
bun
bun add @tauri-apps/plugin-os
-
-
-
npm
npm install @tauri-apps/plugin-os -
yarn
yarn add @tauri-apps/plugin-os -
pnpm
pnpm add @tauri-apps/plugin-os -
deno
deno add npm:@tauri-apps/plugin-os -
bun
bun add @tauri-apps/plugin-os
Usage
With this plugin you can query multiple information from current operational system. See all available functions in the JavaScript API or Rust API references.
Example: OS Platform
platform returns a string describing the specific operating system in use. The value is set at compile time. Possible values are linux, macos, ios, freebsd, dragonfly, netbsd, openbsd, solaris, android, windows.
-
JavaScript
import { platform } from '@tauri-apps/plugin-os'; // when using `"withGlobalTauri": true`, you may use // const { platform } = window.__TAURI__.os; const currentPlatform = platform(); console.log(currentPlatform); // Prints "windows" to the console -
Rust
let platform = tauri_plugin_os::platform(); println!("Platform: {}", platform); // Prints "windows" to the terminal
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/default.json
{
"permissions": [
...,
+"os:default"
]
}
Default Permission
This permission set configures which operating system information are available to gather from the frontend.
Granted Permissions
All information except the host name are available.
This default permission set includes the following:
allow-archallow-exe-extensionallow-familyallow-localeallow-os-typeallow-platformallow-version
Permission Table
| Identifier | Description |
|---|---|
os:allow-arch |
Enables the arch command without any pre-configured scope. |
os:deny-arch |
Denies the arch command without any pre-configured scope. |
os:allow-exe-extension |
Enables the exe_extension command without any pre-configured scope. |
os:deny-exe-extension |
Denies the exe_extension command without any pre-configured scope. |
os:allow-family |
Enables the family command without any pre-configured scope. |
os:deny-family |
Denies the family command without any pre-configured scope. |
os:allow-hostname |
Enables the hostname command without any pre-configured scope. |
os:deny-hostname |
Denies the hostname command without any pre-configured scope. |
os:allow-locale |
Enables the locale command without any pre-configured scope. |
os:deny-locale |
Denies the locale command without any pre-configured scope. |
os:allow-os-type |
Enables the os_type command without any pre-configured scope. |
os:deny-os-type |
Denies the os_type command without any pre-configured scope. |
os:allow-platform |
Enables the platform command without any pre-configured scope. |
os:deny-platform |
Denies the platform command without any pre-configured scope. |
os:allow-version |
Enables the version command without any pre-configured scope. |
os:deny-version |
Denies the version command without any pre-configured scope. |
Persisted Scope
Persist runtime scope changes on the filesystem.
Save filesystem and asset scopes and restore them when the app is reopened.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the persisted-scope plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add persisted-scope -
yarn
yarn run tauri add persisted-scope -
pnpm
pnpm tauri add persisted-scope -
deno
deno task tauri add persisted-scope -
bun
bun tauri add persisted-scope -
cargo
cargo tauri add persisted-scope
-
-
Manual
npm run tauri add persisted-scope -
npm
yarn run tauri add persisted-scope -
yarn
pnpm tauri add persisted-scope -
pnpm
deno task tauri add persisted-scope -
deno
bun tauri add persisted-scope -
bun
cargo tauri add persisted-scope -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-persisted-scope -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() +.plugin(tauri_plugin_persisted_scope::init()) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
-
Caution
The persisted-scope plugin must be registered and initialized after the fs plugin, as illustrated by the example below:
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_fs::init()) // fs MUST BE before persisted scope!
.plugin(tauri_plugin_persisted_scope::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Not doing so will result in the persisted scope not working! You should also see a warning message upon launching your app in dev mode, similar to this:
Please make sure to register the `fs` plugin before the `persisted-scope` plugin!
Usage
After setup the plugin will automatically save and restore filesystem and asset scopes.
Positioner
Move windows to common locations.
Position your windows at well-known locations.
This plugin is a port of electron-positioner for Tauri.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the positioner plugin to get started.
Note
If you only intend on moving the window from Rust code, you only need the dependency in src-tauri/Cargo.toml, and can remove the plugin registration from lib.rs if you choose to setup automatically.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add positioner -
yarn
yarn run tauri add positioner -
pnpm
pnpm tauri add positioner -
deno
deno task tauri add positioner -
bun
bun tauri add positioner -
cargo
cargo tauri add positioner
-
-
Manual
npm run tauri add positioner -
npm
yarn run tauri add positioner -
yarn
pnpm tauri add positioner -
pnpm
deno task tauri add positioner -
deno
bun tauri add positioner -
bun
cargo tauri add positioner -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-positioner --target 'cfg(any(target_os = "macos", windows, target_os = "linux"))' -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() +.setup(|app| { #[cfg(desktop)] app.handle().plugin(tauri_plugin_positioner::init()); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
npm
npm install @tauri-apps/plugin-positioner -
yarn
yarn add @tauri-apps/plugin-positioner -
pnpm
pnpm add @tauri-apps/plugin-positioner -
deno
deno add npm:@tauri-apps/plugin-positioner -
bun
bun add @tauri-apps/plugin-positioner
-
-
-
npm
npm install @tauri-apps/plugin-positioner -
yarn
yarn add @tauri-apps/plugin-positioner -
pnpm
pnpm add @tauri-apps/plugin-positioner -
deno
deno add npm:@tauri-apps/plugin-positioner -
bun
bun add @tauri-apps/plugin-positioner
Additional setup is required to get tray-relative positions to work.
-
Add
tray-iconfeature to yourCargo.tomlfile:src-tauri/Cargo.toml
[dependencies] +tauri-plugin-positioner = { version = "2.0.0", features = ["tray-icon"] } -
Setup
on_tray_eventfor positioner plugin:src-tauri/src/lib.rs
pub fn run() { tauri::Builder::default() // This is required to get tray-relative positions to work +.setup(|app| { + #[cfg(desktop)] + { +app.handle().plugin(tauri_plugin_positioner::init()); + tauri::tray::TrayIconBuilder::new() +.on_tray_icon_event(|tray_handle, event| { + tauri_plugin_positioner::on_tray_event(tray_handle.app_handle(), &event); + }) +.build(app)?; } Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
Usage
The plugin’s APIs are available through the JavaScript guest bindings:
import { moveWindow, Position } from '@tauri-apps/plugin-positioner';
// when using `"withGlobalTauri": true`, you may use
// const { moveWindow, Position } = window.__TAURI__.positioner;
moveWindow(Position.TopRight);
You can import and use the Window trait extension directly through Rust:
use tauri_plugin_positioner::{WindowExt, Position};
let mut win = app.get_webview_window("main").unwrap();
let _ = win.as_ref().window().move_window(Position::TopRight);
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/default.json
{
"permissions": [
...,
+"positioner:default",
]
}
Default Permission
Allows the moveWindow and handleIconState APIs
This default permission set includes the following:
allow-move-windowallow-move-window-constrainedallow-set-tray-icon-state
Permission Table
| Identifier | Description |
|---|---|
positioner:allow-move-window |
Enables the move_window command without any pre-configured scope. |
positioner:deny-move-window |
Denies the move_window command without any pre-configured scope. |
positioner:allow-move-window-constrained |
Enables the move_window_constrained command without any pre-configured scope. |
positioner:deny-move-window-constrained |
Denies the move_window_constrained command without any pre-configured scope. |
positioner:allow-set-tray-icon-state |
Enables the set_tray_icon_state command without any pre-configured scope. |
positioner:deny-set-tray-icon-state |
Denies the set_tray_icon_state command without any pre-configured scope. |
Process
Access the current process.
This plugin provides APIs to access the current process. To spawn child processes, see the shell plugin.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the plugin-process to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add process -
yarn
yarn run tauri add process -
pnpm
pnpm tauri add process -
deno
deno task tauri add process -
bun
bun tauri add process -
cargo
cargo tauri add process
-
-
Manual
npm run tauri add process -
npm
yarn run tauri add process -
yarn
pnpm tauri add process -
pnpm
deno task tauri add process -
deno
bun tauri add process -
bun
cargo tauri add process -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-process -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() +.plugin(tauri_plugin_process::init()) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
If you’d like to utilize the plugin in JavaScript then install the npm package as well:
-
npm
npm install @tauri-apps/plugin-process -
yarn
yarn add @tauri-apps/plugin-process -
pnpm
pnpm add @tauri-apps/plugin-process -
deno
deno add npm:@tauri-apps/plugin-process -
bun
bun add @tauri-apps/plugin-process
-
-
-
npm
npm install @tauri-apps/plugin-process -
yarn
yarn add @tauri-apps/plugin-process -
pnpm
pnpm add @tauri-apps/plugin-process -
deno
deno add npm:@tauri-apps/plugin-process -
bun
bun add @tauri-apps/plugin-process
Usage
The process plugin is available in both JavaScript and Rust.
-
JavaScript
import { exit, relaunch } from '@tauri-apps/plugin-process'; // when using `"withGlobalTauri": true`, you may use // const { exit, relaunch } = window.__TAURI__.process; // exits the app with the given status code await exit(0); // restarts the app await relaunch(); -
Rust
Note that
appis an instance ofAppHandle.// exits the app with the given status code app.exit(0); // restarts the app app.restart();
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/default.json
{
"permissions": [
...,
+"process:default",
]
}
Default Permission
This permission set configures which process features are by default exposed.
Granted Permissions
This enables to quit via allow-exit and restart via allow-restart the application.
This default permission set includes the following:
allow-exitallow-restart
Permission Table
| Identifier | Description |
|---|---|
process:allow-exit |
Enables the exit command without any pre-configured scope. |
process:deny-exit |
Denies the exit command without any pre-configured scope. |
process:allow-restart |
Enables the restart command without any pre-configured scope. |
process:deny-restart |
Denies the restart command without any pre-configured scope. |
Shell
Access the system shell to spawn child processes.
Access the system shell. Allows you to spawn child processes.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | Only allows to open URLs via open |
|
| ios | Only allows to open URLs via open |
Opener
If you’re looking for documentation for the shell.open API, check out the new Opener plugin instead.
Setup
Install the shell plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add shell -
yarn
yarn run tauri add shell -
pnpm
pnpm tauri add shell -
deno
deno task tauri add shell -
bun
bun tauri add shell -
cargo
cargo tauri add shell
-
-
Manual
npm run tauri add shell -
npm
yarn run tauri add shell -
yarn
pnpm tauri add shell -
pnpm
deno task tauri add shell -
deno
bun tauri add shell -
bun
cargo tauri add shell -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-shell -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() +.plugin(tauri_plugin_shell::init()) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
npm
npm install @tauri-apps/plugin-shell -
yarn
yarn add @tauri-apps/plugin-shell -
pnpm
pnpm add @tauri-apps/plugin-shell -
deno
deno add npm:@tauri-apps/plugin-shell -
bun
bun add @tauri-apps/plugin-shell
-
-
-
npm
npm install @tauri-apps/plugin-shell -
yarn
yarn add @tauri-apps/plugin-shell -
pnpm
pnpm add @tauri-apps/plugin-shell -
deno
deno add npm:@tauri-apps/plugin-shell -
bun
bun add @tauri-apps/plugin-shell
Usage
The shell plugin is available in both JavaScript and Rust.
-
JavaScript
import { Command } from '@tauri-apps/plugin-shell'; // when using `"withGlobalTauri": true`, you may use // const { Command } = window.__TAURI__.shell; let result = await Command.create('exec-sh', [ '-c', "echo 'Hello World!'", ]).execute(); console.log(result); -
Rust
use tauri_plugin_shell::ShellExt; let shell = app_handle.shell(); let output = tauri::async_runtime::block_on(async move { shell .command("echo") .args(["Hello from Rust!"]) .output() .await .unwrap() }); if output.status.success() { println!("Result: {:?}", String::from_utf8(output.stdout)); } else { println!("Exit with code: {}", output.status.code().unwrap()); }
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "Capability for the main window",
"windows": ["main"],
+"permissions": [
+ {
+"identifier": "shell:allow-execute",
+"allow": [
+ {
+"name": "exec-sh",
+"cmd": "sh",
+"args": [
+"-c",
+ {
+"validator": "\\S+"
+ }
+ ],
+"sidecar": false
+ }
+ ]
+ }
+ ]
}
Default Permission
This permission set configures which shell functionality is exposed by default.
Granted Permissions
It allows to use the open functionality with a reasonable scope pre-configured. It will allow opening http(s)://, tel: and mailto: links.
This default permission set includes the following:
allow-open
Permission Table
| Identifier | Description |
|---|---|
shell:allow-execute |
Enables the execute command without any pre-configured scope. |
shell:deny-execute |
Denies the execute command without any pre-configured scope. |
shell:allow-kill |
Enables the kill command without any pre-configured scope. |
shell:deny-kill |
Denies the kill command without any pre-configured scope. |
shell:allow-open |
Enables the open command without any pre-configured scope. |
shell:deny-open |
Denies the open command without any pre-configured scope. |
shell:allow-spawn |
Enables the spawn command without any pre-configured scope. |
shell:deny-spawn |
Denies the spawn command without any pre-configured scope. |
shell:allow-stdin-write |
Enables the stdin_write command without any pre-configured scope. |
shell:deny-stdin-write |
Denies the stdin_write command without any pre-configured scope. |
Single Instance
Ensure that a single instance of your Tauri app is running at a time.
Ensure that a single instance of your tauri app is running at a time using the Single Instance Plugin.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the Single Instance plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add single-instance -
yarn
yarn run tauri add single-instance -
pnpm
pnpm tauri add single-instance -
deno
deno task tauri add single-instance -
bun
bun tauri add single-instance -
cargo
cargo tauri add single-instance
-
-
Manual
npm run tauri add single-instance -
npm
yarn run tauri add single-instance -
yarn
pnpm tauri add single-instance -
pnpm
deno task tauri add single-instance -
deno
bun tauri add single-instance -
bun
cargo tauri add single-instance -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-single-instance --target 'cfg(any(target_os = "macos", windows, target_os = "linux"))' -
Modify
lib.rsto initialize the plugin:lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .setup(|app| { + #[cfg(desktop)] +app.handle().plugin(tauri_plugin_single_instance::init(|app, args, cwd| {})); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
-
Note
The Single Instance plugin must be the first one to be registered to work well. This assures that it runs before other plugins can interfere.
Usage
The plugin is already installed and initialized, and it should be functioning correctly right away. Nevertheless, we can also enhance its functionality with the init() method.
The plugin init() method takes a closure that is invoked when a new app instance was started, but closed by the plugin. The closure has three arguments:
app: The AppHandle of the application.args: The list of arguments, that was passed by the user to initiate this new instance.cwd: The Current Working Directory denotes the directory from which the new application instance was launched.
So, the closure should look like below
.plugin(tauri_plugin_single_instance::init(|app, args, cwd| {
// Write your code here...
}))
Focusing on New Instance
By default, when you initiate a new instance while the application is already running, no action is taken. To focus the window of the running instance when user tries to open a new instance, alter the callback closure as follows:
src-tauri/src/lib.rs
use tauri::{AppHandle, Manager};
pub fn run() {
let mut builder = tauri::Builder::default();
#[cfg(desktop)]
{
builder = builder.plugin(tauri_plugin_single_instance::init(|app, args, cwd| {
let _ = app.get_webview_window("main")
.expect("no main window")
.set_focus();
}));
}
builder
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Usage in Snap and Flatpak
On Linux the Single Instance plugin uses DBus to ensure that there will be only one instance running. It does so by publishing a service to DBus when the first instance starts running. Then, the following instances will try to publish the same service and, if it is already published, they will send a request to the service to notify the first instance, and exit right away.
Despite this working pretty well when your app is bundled as a deb or rpm package or an AppImage, it won’t work as intended for snap or flatpak packages by default because these packages run in a constrained sandboxed environment, where most of the communication to DBus services will be blocked if not explicitly declared on the packaging manifest.
Here’s a guide that shows how to declare the needed permissions to enable the Single Instance for snap and flatpak packages:
Getting your app ID
The Single Instance plugin will publish a service named org.{id}.SingleInstance.
{id} will be the identifier from your tauri.conf.json file, but with with dots (.) and dashes (-) replaced by underline (_).
For example, if your identifier is net.mydomain.MyApp:
net_mydomain_MyAppwill be your app{id}org.net_mydomain_MyApp.SingleInstancewill be your app SingleInstance service name
You will need the service name to authorize your app to use the DBus service on snap and flatpak manifests, as seen below.
Snap
In your snapcraft.yml file, declare a plug and a slot for the single instance service, and use both on your app declaration:
snapcraft.yml
# ...
slots:
single-instance:
interface: dbus
bus: session
name: org.net_mydomain_MyApp.SingleInstance # Remember to change net_mydomain_MyApp to your app ID
plugs:
single-instance-plug:
interface: dbus
bus: session
name: org.net_mydomain_MyApp.SingleInstance # Remember to change net_mydomain_MyApp to your app ID
# .....
apps:
my-app:
# ...
plugs:
# ....
- single-instance-plug
slots:
# ...
- single-instance
# ....
This will allow your app to send and receive requests from/to the DBus service as expected by the Single Instance plugin.
Flatpak
In your flatpak manifest file (your.app.id.yml or your.app.id.json), declare a --talk-name and a --own-name finish args with the service name:
net.mydomain.MyApp.yml
# ...
finish-args:
- --socket=wayland
- --socket=fallback-x11
- --device=dri
- --share=ipc
# ....
- --talk-name=org.net_mydomain_MyApp.SingleInstance # Remember to change net_mydomain_MyApp to your app ID
- --own-name=org.net_mydomain_MyApp.SingleInstance # Remember to change net_mydomain_MyApp to your app ID
# ...
This will allow your app to send and receive requests from/to the DBus service as expected by the Single Instance plugin.
Permissions
Because this Plugin currently does not have JavaScript APIs you do not have to configure capabilities to use it.
SQL
Tauri Plugin providing an interface for the frontend to communicate with SQL databases through sqlx.
Plugin providing an interface for the frontend to communicate with SQL databases through sqlx. It supports the SQLite, MySQL and PostgreSQL drivers, enabled by a Cargo feature.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the SQL plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add sql -
yarn
yarn run tauri add sql -
pnpm
pnpm tauri add sql -
deno
deno task tauri add sql -
bun
bun tauri add sql -
cargo
cargo tauri add sql
-
-
Manual
npm run tauri add sql -
npm
yarn run tauri add sql -
yarn
pnpm tauri add sql -
pnpm
deno task tauri add sql -
deno
bun tauri add sql -
bun
cargo tauri add sql -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-sql -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() +.plugin(tauri_plugin_sql::Builder::default().build()) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
npm
npm install @tauri-apps/plugin-sql -
yarn
yarn add @tauri-apps/plugin-sql -
pnpm
pnpm add @tauri-apps/plugin-sql -
deno
deno add npm:@tauri-apps/plugin-sql -
bun
bun add @tauri-apps/plugin-sql
-
-
-
npm
npm install @tauri-apps/plugin-sql -
yarn
yarn add @tauri-apps/plugin-sql -
pnpm
pnpm add @tauri-apps/plugin-sql -
deno
deno add npm:@tauri-apps/plugin-sql -
bun
bun add @tauri-apps/plugin-sql
After installing the plugin, you must select the supported database engine. The available engines are Sqlite, MySQL and PostgreSQL. Run the following command in the src-tauri folder to enable your preferred engine:
-
SQLite
cargo add tauri-plugin-sql --features sqlite -
MySQL
cargo add tauri-plugin-sql --features mysql -
PostgreSQL
cargo add tauri-plugin-sql --features postgres
Usage
All the plugin’s APIs are available through the JavaScript guest bindings:
-
SQLite
The path is relative to
tauri::api::path::BaseDirectory::AppConfig.import Database from '@tauri-apps/plugin-sql'; // when using `"withGlobalTauri": true`, you may use // const Database = window.__TAURI__.sql; const db = await Database.load('sqlite:test.db'); await db.execute('INSERT INTO ...'); -
MySQL
import Database from '@tauri-apps/plugin-sql'; // when using `"withGlobalTauri": true`, you may use // const Database = window.__TAURI__.sql; const db = await Database.load('mysql://user:password@host/test'); await db.execute('INSERT INTO ...'); -
PostgreSQL
import Database from '@tauri-apps/plugin-sql'; // when using `"withGlobalTauri": true`, you may use // const Database = window.__TAURI__.sql; const db = await Database.load('postgres://user:password@host/test'); await db.execute('INSERT INTO ...');
Syntax
We use sqlx as the underlying library and adopt their query syntax.
-
SQLite
Use the “$#” syntax when substituting query data
const result = await db.execute( 'INSERT into todos (id, title, status) VALUES ($1, $2, $3)', [todos.id, todos.title, todos.status] ); const result = await db.execute( 'UPDATE todos SET title = $1, status = $2 WHERE id = $3', [todos.title, todos.status, todos.id] ); -
MySQL
Use “?” when substituting query data
const result = await db.execute( 'INSERT into todos (id, title, status) VALUES (?, ?, ?)', [todos.id, todos.title, todos.status] ); const result = await db.execute( 'UPDATE todos SET title = ?, status = ? WHERE id = ?', [todos.title, todos.status, todos.id] ); -
PostgreSQL
Use the “$#” syntax when substituting query data
const result = await db.execute( 'INSERT into todos (id, title, status) VALUES ($1, $2, $3)', [todos.id, todos.title, todos.status] ); const result = await db.execute( 'UPDATE todos SET title = $1, status = $2 WHERE id = $3', [todos.title, todos.status, todos.id] );
Migrations
This plugin supports database migrations, allowing you to manage database schema evolution over time.
Defining Migrations
Migrations are defined in Rust using the Migration struct. Each migration should include a unique version number, a description, the SQL to be executed, and the type of migration (Up or Down).
Example of a migration:
use tauri_plugin_sql::{Migration, MigrationKind};
let migration = Migration {
version: 1,
description: "create_initial_tables",
sql: "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT);",
kind: MigrationKind::Up,
};
Or if you want to use SQL from a file, you can include it by using include_str!:
use tauri_plugin_sql::{Migration, MigrationKind};
let migration = Migration {
version: 1,
description: "create_initial_tables",
sql: include_str!("../drizzle/0000_graceful_boomer.sql"),
kind: MigrationKind::Up,
};
Adding Migrations to the Plugin Builder
Migrations are registered with the Builder struct provided by the plugin. Use the add_migrations method to add your migrations to the plugin for a specific database connection.
Example of adding migrations:
src-tauri/src/main.rs
use tauri_plugin_sql::{Builder, Migration, MigrationKind};
fn main() {
let migrations = vec![
// Define your migrations here
Migration {
version: 1,
description: "create_initial_tables",
sql: "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT);",
kind: MigrationKind::Up,
}
];
tauri::Builder::default()
.plugin(
tauri_plugin_sql::Builder::default()
.add_migrations("sqlite:mydatabase.db", migrations)
.build(),
)
...
}
Applying Migrations
To apply the migrations when the plugin is initialized, add the connection string to the tauri.conf.json file:
src-tauri/tauri.conf.json
{
"plugins": {
"sql": {
"preload": ["sqlite:mydatabase.db"]
}
}
}
Alternatively, the client side load() also runs the migrations for a given connection string:
import Database from '@tauri-apps/plugin-sql';
const db = await Database.load('sqlite:mydatabase.db');
Ensure that the migrations are defined in the correct order and are safe to run multiple times.
Note
All migrations are executed within a transaction, ensuring atomicity. If any migration fails, the entire transaction is rolled back, leaving the database in a consistent state.
Migration Management
- Version Control: Each migration must have a unique version number. This is crucial for ensuring the migrations are applied in the correct order.
- Idempotency: Write migrations in a way that they can be safely re-run without causing errors or unintended consequences.
- Testing: Thoroughly test migrations to ensure they work as expected and do not compromise the integrity of your database.
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/default.json
{
"permissions": [
...,
+"sql:default",
+"sql:allow-execute",
]
}
Default Permission
Default Permissions
This permission set configures what kind of database operations are available from the sql plugin.
Granted Permissions
All reading related operations are enabled. Also allows to load or close a connection.
This default permission set includes the following:
allow-closeallow-loadallow-select
Permission Table
| Identifier | Description |
|---|---|
sql:allow-close |
Enables the close command without any pre-configured scope. |
sql:deny-close |
Denies the close command without any pre-configured scope. |
sql:allow-execute |
Enables the execute command without any pre-configured scope. |
sql:deny-execute |
Denies the execute command without any pre-configured scope. |
sql:allow-load |
Enables the load command without any pre-configured scope. |
sql:deny-load |
Denies the load command without any pre-configured scope. |
sql:allow-select |
Enables the select command without any pre-configured scope. |
sql:deny-select |
Denies the select command without any pre-configured scope. |
Store
Persistent key value storage.
This plugin provides a persistent key-value store. This is one of many options to handle state in your application. See the state management overview for more information on additional options.
This store will allow you to persist state to a file which can be saved and loaded on demand including between app restarts. Note that this process is asynchronous which will require handling it within your code. It can be used both in the webview or within Rust.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the store plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add store -
yarn
yarn run tauri add store -
pnpm
pnpm tauri add store -
deno
deno task tauri add store -
bun
bun tauri add store -
cargo
cargo tauri add store
-
-
Manual
npm run tauri add store -
npm
yarn run tauri add store -
yarn
pnpm tauri add store -
pnpm
deno task tauri add store -
deno
bun tauri add store -
bun
cargo tauri add store -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-store -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() +.plugin(tauri_plugin_store::Builder::new().build()) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
npm
npm install @tauri-apps/plugin-store -
yarn
yarn add @tauri-apps/plugin-store -
pnpm
pnpm add @tauri-apps/plugin-store -
deno
deno add npm:@tauri-apps/plugin-store -
bun
bun add @tauri-apps/plugin-store
-
-
-
npm
npm install @tauri-apps/plugin-store -
yarn
yarn add @tauri-apps/plugin-store -
pnpm
pnpm add @tauri-apps/plugin-store -
deno
deno add npm:@tauri-apps/plugin-store -
bun
bun add @tauri-apps/plugin-store
Usage
-
JavaScript
import { load } from '@tauri-apps/plugin-store'; // when using `"withGlobalTauri": true`, you may use // const { load } = window.__TAURI__.store; // Create a new store or load the existing one, // note that the options will be ignored if a `Store` with that path has already been created const store = await load('store.json', { autoSave: false }); // Set a value. await store.set('some-key', { value: 5 }); // Get a value. const val = await store.get<{ value: number }>('some-key'); console.log(val); // { value: 5 } // You can manually save the store after making changes. // Otherwise, it will save upon graceful exit // And if you set `autoSave` to a number or left empty, // it will save the changes to disk after a debounce delay, 100ms by default. await store.save(); -
Rust
src-tauri/src/lib.rs
use tauri::Wry; use tauri_plugin_store::StoreExt; use serde_json::json; #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .plugin(tauri_plugin_store::Builder::default().build()) .setup(|app| { // Create a new store or load the existing one // this also put the store in the app's resource table // so your following `store` calls (from both Rust and JS) // will reuse the same store. let store = app.store("store.json")?; // Note that values must be serde_json::Value instances, // otherwise, they will not be compatible with the JavaScript bindings. store.set("some-key", json!({ "value": 5 })); // Get a value from the store. let value = store.get("some-key").expect("Failed to get value from store"); println!("{}", value); // {"value":5} // Remove the store from the resource table store.close_resource(); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
LazyStore
There’s also a high level JavaScript API LazyStore which only loads the store on first access
import { LazyStore } from '@tauri-apps/plugin-store';
const store = new LazyStore('settings.json');
Migrating from v1 and v2 beta/rc
-
JavaScript
import { Store } from '@tauri-apps/plugin-store'; import { LazyStore } from '@tauri-apps/plugin-store'; -
Rust
with_store(app.handle().clone(), stores, path, |store| { store.insert("some-key".to_string(), json!({ "value": 5 }))?; Ok(()) }); let store = app.store(path)?; store.set("some-key".to_string(), json!({ "value": 5 }));
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/default.json
{
"permissions": [
...,
+"store:default",
]
}
Default Permission
This permission set configures what kind of operations are available from the store plugin.
Granted Permissions
All operations are enabled by default.
This default permission set includes the following:
allow-loadallow-get-storeallow-setallow-getallow-hasallow-deleteallow-clearallow-resetallow-keysallow-valuesallow-entriesallow-lengthallow-reloadallow-save
Permission Table
| Identifier | Description |
|---|---|
store:allow-clear |
Enables the clear command without any pre-configured scope. |
store:deny-clear |
Denies the clear command without any pre-configured scope. |
store:allow-delete |
Enables the delete command without any pre-configured scope. |
store:deny-delete |
Denies the delete command without any pre-configured scope. |
store:allow-entries |
Enables the entries command without any pre-configured scope. |
store:deny-entries |
Denies the entries command without any pre-configured scope. |
store:allow-get |
Enables the get command without any pre-configured scope. |
store:deny-get |
Denies the get command without any pre-configured scope. |
store:allow-get-store |
Enables the get_store command without any pre-configured scope. |
store:deny-get-store |
Denies the get_store command without any pre-configured scope. |
store:allow-has |
Enables the has command without any pre-configured scope. |
store:deny-has |
Denies the has command without any pre-configured scope. |
store:allow-keys |
Enables the keys command without any pre-configured scope. |
store:deny-keys |
Denies the keys command without any pre-configured scope. |
store:allow-length |
Enables the length command without any pre-configured scope. |
store:deny-length |
Denies the length command without any pre-configured scope. |
store:allow-load |
Enables the load command without any pre-configured scope. |
store:deny-load |
Denies the load command without any pre-configured scope. |
store:allow-reload |
Enables the reload command without any pre-configured scope. |
store:deny-reload |
Denies the reload command without any pre-configured scope. |
store:allow-reset |
Enables the reset command without any pre-configured scope. |
store:deny-reset |
Denies the reset command without any pre-configured scope. |
store:allow-save |
Enables the save command without any pre-configured scope. |
store:deny-save |
Denies the save command without any pre-configured scope. |
store:allow-set |
Enables the set command without any pre-configured scope. |
store:deny-set |
Denies the set command without any pre-configured scope. |
store:allow-values |
Enables the values command without any pre-configured scope. |
store:deny-values |
Denies the values command without any pre-configured scope. |
Stronghold
Encrypted, secure database.
Store secrets and keys using the IOTA Stronghold secret management engine.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the stronghold plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add stronghold -
yarn
yarn run tauri add stronghold -
pnpm
pnpm tauri add stronghold -
deno
deno task tauri add stronghold -
bun
bun tauri add stronghold -
cargo
cargo tauri add stronghold
-
-
Manual
npm run tauri add stronghold -
npm
yarn run tauri add stronghold -
yarn
pnpm tauri add stronghold -
pnpm
deno task tauri add stronghold -
deno
bun tauri add stronghold -
bun
cargo tauri add stronghold -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-stronghold -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() +.plugin(tauri_plugin_stronghold::Builder::new(|password| {}).build()) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
npm
npm install @tauri-apps/plugin-stronghold -
yarn
yarn add @tauri-apps/plugin-stronghold -
pnpm
pnpm add @tauri-apps/plugin-stronghold -
deno
deno add npm:@tauri-apps/plugin-stronghold -
bun
bun add @tauri-apps/plugin-stronghold
-
-
-
npm
npm install @tauri-apps/plugin-stronghold -
yarn
yarn add @tauri-apps/plugin-stronghold -
pnpm
pnpm add @tauri-apps/plugin-stronghold -
deno
deno add npm:@tauri-apps/plugin-stronghold -
bun
bun add @tauri-apps/plugin-stronghold
Due to an upstream bug we also recommend that you add this to your Cargo.toml file:
[profile.dev.package.scrypt]
opt-level = 3
Usage
The plugin must be initialized with a password hash function, which takes the password string and must return a 32 bytes hash derived from it.
Initialize with argon2 password hash function
The Stronghold plugin offers a default hash function using the argon2 algorithm.
src-tauri/src/lib.rs
use tauri::Manager;
pub fn run() {
tauri::Builder::default()
.setup(|app| {
let salt_path = app
.path()
.app_local_data_dir()
.expect("could not resolve app local data path")
.join("salt.txt");
app.handle().plugin(tauri_plugin_stronghold::Builder::with_argon2(&salt_path).build())?;
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Initialize with custom password hash function
Alternatively you can provide your own hash algorithm by using the tauri_plugin_stronghold::Builder::new constructor.
Note
The password hash must contain exactly 32 bytes. This is a Stronghold requirement.
src-tauri/src/lib.rs
pub fn run() {
tauri::Builder::default()
.plugin(
tauri_plugin_stronghold::Builder::new(|password| {
// Hash the password here with e.g. argon2, blake2b or any other secure algorithm
// Here is an example implementation using the `rust-argon2` crate for hashing the password
use argon2::{hash_raw, Config, Variant, Version};
let config = Config {
lanes: 4,
mem_cost: 10_000,
time_cost: 10,
variant: Variant::Argon2id,
version: Version::Version13,
..Default::default()
};
let salt = "your-salt".as_bytes();
let key = hash_raw(password.as_ref(), salt, &config).expect("failed to hash password");
key.to_vec()
})
.build(),
)
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Usage from JavaScript
The stronghold plugin is available in JavaScript.
import { Client, Stronghold } from '@tauri-apps/plugin-stronghold';
// when using `"withGlobalTauri": true`, you may use
// const { Client, Stronghold } = window.__TAURI__.stronghold;
import { appDataDir } from '@tauri-apps/api/path';
// when using `"withGlobalTauri": true`, you may use
// const { appDataDir } = window.__TAURI__.path;
const initStronghold = async () => {
const vaultPath = `${await appDataDir()}/vault.hold`;
const vaultPassword = 'vault password';
const stronghold = await Stronghold.load(vaultPath, vaultPassword);
let client: Client;
const clientName = 'name your client';
try {
client = await stronghold.loadClient(clientName);
} catch {
client = await stronghold.createClient(clientName);
}
return {
stronghold,
client,
};
};
// Insert a record to the store
async function insertRecord(store: any, key: string, value: string) {
const data = Array.from(new TextEncoder().encode(value));
await store.insert(key, data);
}
// Read a record from store
async function getRecord(store: any, key: string): Promise<string> {
const data = await store.get(key);
return new TextDecoder().decode(new Uint8Array(data));
}
const { stronghold, client } = await initStronghold();
const store = client.getStore();
const key = 'my_key';
// Insert a record to the store
insertRecord(store, key, 'secret value');
// Read a record from store
const value = await getRecord(store, key);
console.log(value); // 'secret value'
// Save your updates
await stronghold.save();
// Remove a record from store
await store.remove(key);
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/default.json
{
...,
"permissions": [
+"stronghold:default",
]
}
Default Permission
This permission set configures what kind of operations are available from the stronghold plugin.
Granted Permissions
All non-destructive operations are enabled by default.
This default permission set includes the following:
allow-create-clientallow-get-store-recordallow-initializeallow-execute-procedureallow-load-clientallow-save-secretallow-save-store-recordallow-save
Permission Table
| Identifier | Description |
|---|---|
stronghold:allow-create-client |
Enables the create_client command without any pre-configured scope. |
stronghold:deny-create-client |
Denies the create_client command without any pre-configured scope. |
stronghold:allow-destroy |
Enables the destroy command without any pre-configured scope. |
stronghold:deny-destroy |
Denies the destroy command without any pre-configured scope. |
stronghold:allow-execute-procedure |
Enables the execute_procedure command without any pre-configured scope. |
stronghold:deny-execute-procedure |
Denies the execute_procedure command without any pre-configured scope. |
stronghold:allow-get-store-record |
Enables the get_store_record command without any pre-configured scope. |
stronghold:deny-get-store-record |
Denies the get_store_record command without any pre-configured scope. |
stronghold:allow-initialize |
Enables the initialize command without any pre-configured scope. |
stronghold:deny-initialize |
Denies the initialize command without any pre-configured scope. |
stronghold:allow-load-client |
Enables the load_client command without any pre-configured scope. |
stronghold:deny-load-client |
Denies the load_client command without any pre-configured scope. |
stronghold:allow-remove-secret |
Enables the remove_secret command without any pre-configured scope. |
stronghold:deny-remove-secret |
Denies the remove_secret command without any pre-configured scope. |
stronghold:allow-remove-store-record |
Enables the remove_store_record command without any pre-configured scope. |
stronghold:deny-remove-store-record |
Denies the remove_store_record command without any pre-configured scope. |
stronghold:allow-save |
Enables the save command without any pre-configured scope. |
stronghold:deny-save |
Denies the save command without any pre-configured scope. |
stronghold:allow-save-secret |
Enables the save_secret command without any pre-configured scope. |
stronghold:deny-save-secret |
Denies the save_secret command without any pre-configured scope. |
stronghold:allow-save-store-record |
Enables the save_store_record command without any pre-configured scope. |
stronghold:deny-save-store-record |
Denies the save_store_record command without any pre-configured scope. |
Updater
In-app updates for Tauri applications.
Automatically update your Tauri app with an update server or a static JSON.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the Tauri updater plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add updater -
yarn
yarn run tauri add updater -
pnpm
pnpm tauri add updater -
deno
deno task tauri add updater -
bun
bun tauri add updater -
cargo
cargo tauri add updater
-
-
Manual
npm run tauri add updater -
npm
yarn run tauri add updater -
yarn
pnpm tauri add updater -
pnpm
deno task tauri add updater -
deno
bun tauri add updater -
bun
cargo tauri add updater -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-updater --target 'cfg(any(target_os = "macos", windows, target_os = "linux"))' -
Modify
lib.rsto initialize the plugin:lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .setup(|app| { + #[cfg(desktop)] +app.handle().plugin(tauri_plugin_updater::Builder::new().build()); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
You can install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
npm
npm install @tauri-apps/plugin-updater -
yarn
yarn add @tauri-apps/plugin-updater -
pnpm
pnpm add @tauri-apps/plugin-updater -
deno
deno add npm:@tauri-apps/plugin-updater -
bun
bun add @tauri-apps/plugin-updater
-
-
-
npm
npm install @tauri-apps/plugin-updater -
yarn
yarn add @tauri-apps/plugin-updater -
pnpm
pnpm add @tauri-apps/plugin-updater -
deno
deno add npm:@tauri-apps/plugin-updater -
bun
bun add @tauri-apps/plugin-updater
Signing updates
Tauri’s updater needs a signature to verify that the update is from a trusted source. This cannot be disabled.
To sign your updates you need two keys:
- The public key, which will be set in the
tauri.conf.jsonto validate the artifacts before the installation. This public key can be uploaded and shared safely as long as your private key is secure. - The private key, which is used to sign your installer files. You should NEVER share this key with anyone. Also, if you lose this key you will NOT be able to publish new updates to the users that have the app already installed. It is important to store this key in a safe place!
To generate the keys the Tauri CLI provides the signer generate command. You can run this to create the keys in the home folder:
-
npm
npm run tauri signer generate -- -w ~/.tauri/myapp.key -
yarn
yarn tauri signer generate -w ~/.tauri/myapp.key -
pnpm
pnpm tauri signer generate -w ~/.tauri/myapp.key -
deno
deno task tauri signer generate -w ~/.tauri/myapp.key -
bun
bunx tauri signer generate -w ~/.tauri/myapp.key -
cargo
cargo tauri signer generate -w ~/.tauri/myapp.key
Building
While building your update artifacts, you need to have the private key you generated above in your environment variables. .env files do not work!
-
Mac/Linux
export TAURI_SIGNING_PRIVATE_KEY="Path or content of your private key" # optionally also add a password export TAURI_SIGNING_PRIVATE_KEY_PASSWORD="" -
Windows
Run this in
PowerShell:$env:TAURI_SIGNING_PRIVATE_KEY="Path or content of your private key" <# optionally also add a password #> $env:TAURI_SIGNING_PRIVATE_KEY_PASSWORD=""
After that, you can run Tauri build as usual and Tauri will generate the update bundles and their signatures. The generated files depend on the createUpdaterArtifacts configuration value configured below.
-
v2
{ "bundle": { "createUpdaterArtifacts": true } }On Linux, Tauri will create the normal AppImage inside the
target/release/bundle/appimage/folder:myapp.AppImage- The standard app bundle. It will be re-used by the updater.myapp.AppImage.sig- The signature of the updater bundle.
On macOS, Tauri will create a .tar.gz archive from the application bundle inside the target/release/bundle/macos/ folder:
myapp.app- The standard app bundle.myapp.app.tar.gz- The updater bundle.myapp.app.tar.gz.sig- The signature of the update bundle.
On Windows, Tauri will create the normal MSI and NSIS installers inside the target/release/bundle/msi/ and target/release/bundle/nsis folders:
myapp-setup.exe- The standard app bundle. It will be re-used by the updater.myapp-setup.exe.sig- The signature of the update bundle.myapp.msi- The standard app bundle. It will be re-used by the updater.myapp.msi.sig- The signature of the update bundle.
-
v1 compatible
{ "bundle": { "createUpdaterArtifacts": "v1Compatible" } }On Linux, Tauri will create a .tar.gz archive from the AppImage inside the
target/release/bundle/appimage/folder:myapp.AppImage- The standard app bundle.myapp.AppImage.tar.gz- The updater bundle.myapp.AppImage.tar.gz.sig- The signature of the update bundle.
On macOS, Tauri will create a .tar.gz archive from the application bundle inside the target/release/bundle/macos/ folder:
myapp.app- The standard app bundle.myapp.app.tar.gz- The updater bundle.myapp.app.tar.gz.sig- The signature of the update bundle.
On Windows, Tauri will create .zip archives from the MSI and NSIS installers inside the target/release/bundle/msi/ and target/release/bundle/nsis folders:
myapp-setup.exe- The standard app bundle.myapp-setup.nsis.zip- The updater bundle.myapp-setup.nsis.zip.sig- The signature of the update bundle.myapp.msi- The standard app bundle.myapp.msi.zip- The updater bundle.myapp.msi.zip.sig- The signature of the update bundle.
Tauri Configuration
Set up the tauri.conf.json in this format for the updater to start working.
| Keys | Description |
|---|---|
createUpdaterArtifacts |
Setting this to true tells Tauri’s app bundler to create updater artifacts. If you’re migrating your app from an older Tauri version, set it to "v1Compatible" instead. This setting will be removed in v3 so make sure to change it to true once all your users are migrated to v2. |
pubkey |
This has to be the public key generated from the Tauri CLI in the step above. It cannot be a file path! |
endpoints |
This must be an array of endpoint URLs as strings. TLS is enforced in production mode. Tauri will only continue to the next url if a non-2XX status code is returned! |
dangerousInsecureTransportProtocol |
Setting this to true allows the updater to accept non-HTTPS endpoints. Use this configuration with caution! |
Each updater URL can contain the following dynamic variables, allowing you to determine server-side if an update is available.
{{current_version}}: The version of the app that is requesting the update.{{target}}: The operating system name (one oflinux,windowsordarwin).{{arch}}: The architecture of the machine (one ofx86_64,i686,aarch64orarmv7).
tauri.conf.json
{
"bundle": {
"createUpdaterArtifacts": true
},
"plugins": {
"updater": {
"pubkey": "CONTENT FROM PUBLICKEY.PEM",
"endpoints": [
"https://releases.myapp.com/{{target}}/{{arch}}/{{current_version}}",
// or a static github json file
"https://github.com/user/repo/releases/latest/download/latest.json"
]
}
}
}
Tip
Custom variables are not supported, but you can define a custom {{target}}.
installMode on Windows
On Windows there is an additional optional "installMode" config to change how the update is installed.
tauri.conf.json
{
"plugins": {
"updater": {
"windows": {
"installMode": "passive"
}
}
}
}
"passive": There will be a small window with a progress bar. The update will be installed without requiring any user interaction. Generally recommended and the default mode."basicUi": There will be a basic user interface shown which requires user interaction to finish the installation."quiet": There will be no progress feedback to the user. With this mode the installer cannot request admin privileges by itself so it only works in user-wide installations or when your app itself already runs with admin privileges. Generally not recommended.
Server Support
The updater plugin can be used in two ways. Either with a dynamic update server or a static JSON file (to use on services like S3 or GitHub gists).
Static JSON File
When using static, you just need to return a JSON containing the required information.
| Keys | Description |
|---|---|
version |
Must be a valid SemVer, with or without a leading v, meaning that both 1.0.0 and v1.0.0 are valid. |
notes |
Notes about the update. |
pub_date |
The date must be formatted according to RFC 3339 if present. |
platforms |
Each platform key is in the OS-ARCH format, where OS is one of linux, darwin or windows, and ARCH is one of x86_64, aarch64, i686 or armv7. |
signature |
The content of the generated .sig file, which may change with each build. A path or URL does not work! |
Note
When using custom targets the provided target string is matched against the platforms key instead of the default OS-ARCH value.
The required keys are "version", "platforms.[target].url" and "platforms.[target].signature"; the others are optional.
{
"version": "",
"notes": "",
"pub_date": "",
"platforms": {
"linux-x86_64": {
"signature": "",
"url": ""
},
"windows-x86_64": {
"signature": "",
"url": ""
},
"darwin-x86_64": {
"signature": "",
"url": ""
}
}
}
Note that Tauri will validate the whole file before checking the version field, so make sure all existing platform configurations are valid and complete.
Tip
Tauri Action generates a static JSON file for you to use on CDNs such as GitHub Releases.
Dynamic Update Server
When using a dynamic update server, Tauri will follow the server’s instructions. To disable the internal version check you can overwrite the plugin’s version comparison, this will install the version sent by the server (useful if you need to roll back your app).
Your server can use variables defined in the endpoint URL above to determine if an update is required. If you need more data, you can include additional request headers in Rust to your liking.
Your server should respond with a status code of 204 No Content if there is no update available.
If an update is required, your server should respond with a status code of 200 OK and a JSON response in this format:
| Keys | Description |
|---|---|
version |
This Must be a valid SemVer, with or without a leading v, meaning that both 1.0.0 and v1.0.0 are valid. |
notes |
Notes about the update. |
pub_date |
The date must be formatted according to RFC 3339 if present. |
url |
This Must be a valid URL to the update bundle. |
signature |
The content of the generated .sig file, which may change with each build. A path or URL does not work! |
The required keys are "url", "version" and "signature"; the others are optional.
{
"version": "",
"pub_date": "",
"url": "",
"signature": "",
"notes": ""
}
Tip
CrabNebula, an official Tauri partner, offers a dynamic update server. For more information, see the Distributing with CrabNebula Cloud documentation.
Checking for Updates
The default API for checking updates and installing them leverages the configured endpoints and can be accessed by both JavaScript and Rust code.
-
JavaScript
import { check } from '@tauri-apps/plugin-updater'; import { relaunch } from '@tauri-apps/plugin-process'; const update = await check(); if (update) { console.log( `found update ${update.version} from ${update.date} with notes ${update.body}` ); let downloaded = 0; let contentLength = 0; // alternatively we could also call update.download() and update.install() separately await update.downloadAndInstall((event) => { switch (event.event) { case 'Started': contentLength = event.data.contentLength; console.log(`started downloading ${event.data.contentLength} bytes`); break; case 'Progress': downloaded += event.data.chunkLength; console.log(`downloaded ${downloaded} from ${contentLength}`); break; case 'Finished': console.log('download finished'); break; } }); console.log('update installed'); await relaunch(); }For more information see the JavaScript API documentation.
-
Rust
src-tauri/src/lib.rs
use tauri_plugin_updater::UpdaterExt; pub fn run() { tauri::Builder::default() .setup(|app| { let handle = app.handle().clone(); tauri::async_runtime::spawn(async move { update(handle).await.unwrap(); }); Ok(()) }) .run(tauri::generate_context!()) .unwrap(); } async fn update(app: tauri::AppHandle) -> tauri_plugin_updater::Result<()> { if let Some(update) = app.updater()?.check().await? { let mut downloaded = 0; // alternatively we could also call update.download() and update.install() separately update .download_and_install( |chunk_length, content_length| { downloaded += chunk_length; println!("downloaded {downloaded} from {content_length:?}"); }, || { println!("download finished"); }, ) .await?; println!("update installed"); app.restart(); } Ok(()) }Tip
To notify the frontend of the download progress consider using a command with a channel.
Updater command
#[cfg(desktop)] mod app_updates { use std::sync::Mutex; use serde::Serialize; use tauri::{ipc::Channel, AppHandle, State}; use tauri_plugin_updater::{Update, UpdaterExt}; #[derive(Debug, thiserror::Error)] pub enum Error { #[error(transparent)] Updater(#[from] tauri_plugin_updater::Error), #[error("there is no pending update")] NoPendingUpdate, } impl Serialize for Error { fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> where S: serde::Serializer, { serializer.serialize_str(self.to_string().as_str()) } } type Result<T> = std::result::Result<T, Error>; #[derive(Clone, Serialize)] #[serde(tag = "event", content = "data")] pub enum DownloadEvent { #[serde(rename_all = "camelCase")] Started { content_length: Option<u64>, }, #[serde(rename_all = "camelCase")] Progress { chunk_length: usize, }, Finished, } #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct UpdateMetadata { version: String, current_version: String, } #[tauri::command] pub async fn fetch_update( app: AppHandle, pending_update: State<'_, PendingUpdate>, ) -> Result<Option<UpdateMetadata>> { let channel = "stable"; let url = url::Url::parse(&format!( "https://cdn.myupdater.com/{{{{target}}}}-{{{{arch}}}}/{{{{current_version}}}}?channel={channel}", )).expect("invalid URL"); let update = app .updater_builder() .endpoints(vec![url])? .build()? .check() .await?; let update_metadata = update.as_ref().map(|update| UpdateMetadata { version: update.version.clone(), current_version: update.current_version.clone(), }); *pending_update.0.lock().unwrap() = update; Ok(update_metadata) } #[tauri::command] pub async fn install_update(pending_update: State<'_, PendingUpdate>, on_event: Channel<DownloadEvent>) -> Result<()> { let Some(update) = pending_update.0.lock().unwrap().take() else { return Err(Error::NoPendingUpdate); }; let started = false; update .download_and_install( |chunk_length, content_length| { if !started { let _ = on_event.send(DownloadEvent::Started { content_length }); started = true; } let _ = on_event.send(DownloadEvent::Progress { chunk_length }); }, || { let _ = on_event.send(DownloadEvent::Finished); }, ) .await?; Ok(()) } struct PendingUpdate(Mutex<Option<Update>>); } #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .plugin(tauri_plugin_process::init()) .setup(|app| { #[cfg(desktop)] { app.handle().plugin(tauri_plugin_updater::Builder::new().build()); app.manage(app_updates::PendingUpdate(Mutex::new(None))); } Ok(()) }) .invoke_handler(tauri::generate_handler![ #[cfg(desktop)] app_updates::fetch_update, #[cfg(desktop)] app_updates::install_update ]) }For more information see the Rust API documentation.
Note that restarting your app immediately after installing an update is not required and you can choose how to handle the update by either waiting until the user manually restarts the app, or prompting them to select when to do so.
Note
On Windows the application is automatically exited when the install step is executed due to a limitation of Windows installers.
When checking and downloading updates it is possible to define a custom request timeout, a proxy and request headers.
-
JavaScript
import { check } from '@tauri-apps/plugin-updater'; const update = await check({ proxy: '<proxy url>', timeout: 30000 /* milliseconds */, headers: { Authorization: 'Bearer <token>', }, }); -
Rust
use tauri_plugin_updater::UpdaterExt; let update = app .updater_builder() .timeout(std::time::Duration::from_secs(30)) .proxy("<proxy-url>".parse().expect("invalid URL")) .header("Authorization", "Bearer <token>") .build()? .check() .await?;
Runtime Configuration
The updater APIs also allows the updater to be configured at runtime for more flexibility. For security reasons some APIs are only available for Rust.
Endpoints
Setting the URLs that should be requested to check updates at runtime allows more dynamic updates such as separate release channels:
use tauri_plugin_updater::UpdaterExt;
let channel = if beta { "beta" } else { "stable" };
let update_url = format!("https://{channel}.myserver.com/{{{{target}}}}-{{{{arch}}}}/{{{{current_version}}}}");
let update = app
.updater_builder()
.endpoints(vec![update_url])?
.build()?
.check()
.await?;
Tip
Note that when using format!() to interpolate the update URL you need double escapes for the variables e.g. {{{{target}}}}.
Public key
Setting the public key at runtime can be useful to implement a key rotation logic. It can be set by either the plugin builder or updater builder:
tauri_plugin_updater::Builder::new().pubkey("<your public key>").build()
use tauri_plugin_updater::UpdaterExt;
let update = app
.updater_builder()
.pubkey("<your public key>")
.build()?
.check()
.await?;
Custom target
By default the updater lets you use the {{target}} and {{arch}} variables to determine which update asset must be delivered. If you need more information on your updates (e.g. when distributing a Universal macOS binary option or having more build flavors) you can set a custom target.
-
JavaScript
import { check } from '@tauri-apps/plugin-updater'; const update = await check({ target: 'macos-universal', }); -
Rust
Custom targets can be set by either the plugin builder or updater builder:
tauri_plugin_updater::Builder::new().target("macos-universal").build()use tauri_plugin_updater::UpdaterExt; let update = app .updater_builder() .target("macos-universal") .build()? .check() .await?;Tip
The default
$target-$archkey can be retrieved usingtauri_plugin_updater::target()which returns anOption<String>that isNonewhen the updater is not supported on the current platform.
Note
- When using a custom target it might be easier to use it exclusively to determine the update platform, so you could remove the
{{arch}}variable. - The value provided as target is the key that is matched against the platform key when using a Static JSON file.
Allowing downgrades
By default Tauri checks if the update version is greater than the current app version to verify if it should update or not. To allow downgrades, you must use the updater builder’s version_comparator API:
use tauri_plugin_updater::UpdaterExt;
let update = app
.updater_builder()
.version_comparator(|current, update| {
// default comparison: `update.version > current`
update.version != current
})
.build()?
.check()
.await?;
Windows before exit hook
Due to a limitation of Windows installers, Tauri will automatically quit your application before installing updates on Windows. To perform an action before that happens, use the on_before_exit function:
use tauri_plugin_updater::UpdaterExt;
let update = app
.updater_builder()
.on_before_exit(|| {
println!("app is about to exit on Windows!");
})
.build()?
.check()
.await?;
Note
The values from the configuration are used as fallback if any of the builder values are not set.
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/default.json
{
"permissions": [
...,
+"updater:default",
]
}
Default Permission
This permission set configures which kind of updater functions are exposed to the frontend.
Granted Permissions
The full workflow from checking for updates to installing them is enabled.
This default permission set includes the following:
allow-checkallow-downloadallow-installallow-download-and-install
Permission Table
| Identifier | Description |
|---|---|
updater:allow-check |
Enables the check command without any pre-configured scope. |
updater:deny-check |
Denies the check command without any pre-configured scope. |
updater:allow-download |
Enables the download command without any pre-configured scope. |
updater:deny-download |
Denies the download command without any pre-configured scope. |
updater:allow-download-and-install |
Enables the download_and_install command without any pre-configured scope. |
updater:deny-download-and-install |
Denies the download_and_install command without any pre-configured scope. |
updater:allow-install |
Enables the install command without any pre-configured scope. |
updater:deny-install |
Denies the install command without any pre-configured scope. |
Upload
File uploads through HTTP.
Upload files from disk to a remote server over HTTP. Download files from a remote HTTP server to disk.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add upload -
yarn
yarn run tauri add upload -
pnpm
pnpm tauri add upload -
deno
deno task tauri add upload -
bun
bun tauri add upload -
cargo
cargo tauri add upload
-
-
Manual
npm run tauri add upload -
npm
yarn run tauri add upload -
yarn
pnpm tauri add upload -
pnpm
deno task tauri add upload -
deno
bun tauri add upload -
bun
cargo tauri add upload -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-upload -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() +.plugin(tauri_plugin_upload::init()) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
npm
npm install @tauri-apps/plugin-upload -
yarn
yarn add @tauri-apps/plugin-upload -
pnpm
pnpm add @tauri-apps/plugin-upload -
deno
deno add npm:@tauri-apps/plugin-upload -
bun
bun add @tauri-apps/plugin-upload
-
-
-
npm
npm install @tauri-apps/plugin-upload -
yarn
yarn add @tauri-apps/plugin-upload -
pnpm
pnpm add @tauri-apps/plugin-upload -
deno
deno add npm:@tauri-apps/plugin-upload -
bun
bun add @tauri-apps/plugin-upload
Usage
Once you’ve completed the registration and setup process for the plugin, you can access all of its APIs through the JavaScript guest bindings.
Here’s an example of how you can use the plugin to upload and download files:
import { upload } from '@tauri-apps/plugin-upload';
// when using `"withGlobalTauri": true`, you may use
// const { upload } = window.__TAURI__.upload;
upload(
'https://example.com/file-upload',
'./path/to/my/file.txt',
({ progress, total }) =>
console.log(`Uploaded ${progress} of ${total} bytes`), // a callback that will be called with the upload progress
{ 'Content-Type': 'text/plain' } // optional headers to send with the request
);
import { download } from '@tauri-apps/plugin-upload';
// when using `"withGlobalTauri": true`, you may use
// const { download } = window.__TAURI__.upload;
download(
'https://example.com/file-download-link',
'./path/to/save/my/file.txt',
({ progress, total }) =>
console.log(`Downloaded ${progress} of ${total} bytes`), // a callback that will be called with the download progress
{ 'Content-Type': 'text/plain' } // optional headers to send with the request
);
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/default.json
{
"permissions": [
...,
+"upload:default",
]
}
Default Permission
This permission set configures what kind of operations are available from the upload plugin.
Granted Permissions
All operations are enabled by default.
This default permission set includes the following:
allow-uploadallow-download
Permission Table
| Identifier | Description |
|---|---|
upload:allow-download |
Enables the download command without any pre-configured scope. |
upload:deny-download |
Denies the download command without any pre-configured scope. |
upload:allow-upload |
Enables the upload command without any pre-configured scope. |
upload:deny-upload |
Denies the upload command without any pre-configured scope. |
Websocket
Open a WebSocket connection using a Rust client in JavaScript.
Open a WebSocket connection using a Rust client in JavaScript.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the websocket plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add websocket -
yarn
yarn run tauri add websocket -
pnpm
pnpm tauri add websocket -
deno
deno task tauri add websocket -
bun
bun tauri add websocket -
cargo
cargo tauri add websocket
-
-
Manual
npm run tauri add websocket -
npm
yarn run tauri add websocket -
yarn
pnpm tauri add websocket -
pnpm
deno task tauri add websocket -
deno
bun tauri add websocket -
bun
cargo tauri add websocket -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-websocket -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() +.plugin(tauri_plugin_websocket::init()) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
npm
npm install @tauri-apps/plugin-websocket -
yarn
yarn add @tauri-apps/plugin-websocket -
pnpm
pnpm add @tauri-apps/plugin-websocket -
deno
deno add npm:@tauri-apps/plugin-websocket -
bun
bun add @tauri-apps/plugin-websocket
-
-
-
npm
npm install @tauri-apps/plugin-websocket -
yarn
yarn add @tauri-apps/plugin-websocket -
pnpm
pnpm add @tauri-apps/plugin-websocket -
deno
deno add npm:@tauri-apps/plugin-websocket -
bun
bun add @tauri-apps/plugin-websocket
Usage
The websocket plugin is available in JavaScript.
import WebSocket from '@tauri-apps/plugin-websocket';
// when using `"withGlobalTauri": true`, you may use
// const WebSocket = window.__TAURI__.websocket;
const ws = await WebSocket.connect('ws://127.0.0.1:8080');
const removeListener = ws.addListener((msg) => {
console.log('Received Message:', msg);
});
await ws.send('Hello World!');
// optionally remove the listener
removeListener();
await ws.disconnect();
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "Capability for the main window",
"windows": ["main"],
+"permissions": ["websocket:default"]
}
Default Permission
Allows connecting and sending data to a WebSocket server
This default permission set includes the following:
allow-connectallow-send
Permission Table
| Identifier | Description |
|---|---|
websocket:allow-connect |
Enables the connect command without any pre-configured scope. |
websocket:deny-connect |
Denies the connect command without any pre-configured scope. |
websocket:allow-send |
Enables the send command without any pre-configured scope. |
websocket:deny-send |
Denies the send command without any pre-configured scope. |
Window State
Persist window sizes and positions.
Save window positions and sizes and restore them when the app is reopened.
Supported Platforms
This plugin requires a Rust version of at least 1.77.2
| Platform | Level | Notes |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Setup
Install the window-state plugin to get started.
-
Automatic
Use your project’s package manager to add the dependency:
-
npm
npm run tauri add window-state -
yarn
yarn run tauri add window-state -
pnpm
pnpm tauri add window-state -
deno
deno task tauri add window-state -
bun
bun tauri add window-state -
cargo
cargo tauri add window-state
-
-
Manual
npm run tauri add window-state -
npm
yarn run tauri add window-state -
yarn
pnpm tauri add window-state -
pnpm
deno task tauri add window-state -
deno
bun tauri add window-state -
bun
cargo tauri add window-state -
cargo
-
Run the following command in the
src-taurifolder to add the plugin to the project’s dependencies inCargo.toml:cargo add tauri-plugin-window-state --target 'cfg(any(target_os = "macos", windows, target_os = "linux"))' -
Modify
lib.rsto initialize the plugin:src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() +.setup(|app| { #[cfg(desktop)] app.handle().plugin(tauri_plugin_window_state::Builder::default().build()); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); } -
Install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
npm
npm install @tauri-apps/plugin-window-state -
yarn
yarn add @tauri-apps/plugin-window-state -
pnpm
pnpm add @tauri-apps/plugin-window-state -
deno
deno add npm:@tauri-apps/plugin-window-state -
bun
bun add @tauri-apps/plugin-window-state
-
-
-
npm
npm install @tauri-apps/plugin-window-state -
yarn
yarn add @tauri-apps/plugin-window-state -
pnpm
pnpm add @tauri-apps/plugin-window-state -
deno
deno add npm:@tauri-apps/plugin-window-state -
bun
bun add @tauri-apps/plugin-window-state
Usage
After adding the window-state plugin, all windows will remember their state when the app is being closed and will restore to their previous state on the next launch.
You can also access the window-state plugin in both JavaScript and Rust.
Tip
Restoring the state will happen after window creation, so to prevent the window from flashing, you can set visible to false when creating the window, the plugin will show the window when it restores the state
JavaScript
You can use saveWindowState to manually save the window state:
import { saveWindowState, StateFlags } from '@tauri-apps/plugin-window-state';
// when using `"withGlobalTauri": true`, you may use
// const { saveWindowState, StateFlags } = window.__TAURI__.windowState;
saveWindowState(StateFlags.ALL);
Similarly you can manually restore a window’s state from disk:
import {
restoreStateCurrent,
StateFlags,
} from '@tauri-apps/plugin-window-state';
// when using `"withGlobalTauri": true`, you may use
// const { restoreStateCurrent, StateFlags } = window.__TAURI__.windowState;
restoreStateCurrent(StateFlags.ALL);
Rust
You can use the save_window_state() method exposed by the AppHandleExt trait:
use tauri_plugin_window_state::{AppHandleExt, StateFlags};
// `tauri::AppHandle` now has the following additional method
app.save_window_state(StateFlags::all()); // will save the state of all open windows to disk
Similarly you can manually restore a window’s state from disk using the restore_state() method exposed by the WindowExt trait:
use tauri_plugin_window_state::{WindowExt, StateFlags};
// all `Window` types now have the following additional method
window.restore_state(StateFlags::all()); // will restore the window's state from disk
Permissions
By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.
See the Capabilities Overview for more information and the step by step guide to use plugin permissions.
src-tauri/capabilities/default.json
{
"permissions": [
...,
+"window-state:default",
]
}
Default Permission
This permission set configures what kind of operations are available from the window state plugin.
Granted Permissions
All operations are enabled by default.
This default permission set includes the following:
allow-filenameallow-restore-stateallow-save-window-state
Permission Table
| Identifier | Description |
|---|---|
window-state:allow-filename |
Enables the filename command without any pre-configured scope. |
window-state:deny-filename |
Denies the filename command without any pre-configured scope. |
window-state:allow-restore-state |
Enables the restore_state command without any pre-configured scope. |
window-state:deny-restore-state |
Denies the restore_state command without any pre-configured scope. |
window-state:allow-save-window-state |
Enables the save_window_state command without any pre-configured scope. |
window-state:deny-save-window-state |
Denies the save_window_state command without any pre-configured scope. |
Capability
A grouping and boundary mechanism developers can use to isolate access to the IPC layer.
It controls application windows’ and webviews’ fine grained access to the Tauri core, application, or plugin commands. If a webview or its window is not matching any capability then it has no access to the IPC layer at all.
This can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. main-window) or glob patterns like * or admin-*. A Window can have none, one, or multiple associated capabilities.
Example
{
"identifier": "main-user-files-write",
"description": "This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programmatic access to files selected by the user.",
"windows": [
"main"
],
"permissions": [
"core:default",
"dialog:open",
{
"identifier": "fs:allow-write-text-file",
"allow": [{ "path": "$HOME/test.txt" }]
},
],
"platforms": ["macOS","windows"]
}
Object Properties:
- description
- identifier (required)
- local
- permissions (required)
- platforms
- remote
- webviews
- windows
description
string
Description of what the capability is intended to allow on associated windows.
It should contain a description of what the grouped permissions should allow.
Example
This capability allows the main window access to filesystem write related commands and dialog commands to enable programmatic access to files selected by the user.
identifier
string
Identifier of the capability.
Example
main-user-files-write
local
boolean
Whether this capability is enabled for local app URLs or not. Defaults to true.
Default: true
permissions
PermissionEntry[] each item must be unique
List of permissions attached to this capability.
Must include the plugin name as prefix in the form of ${plugin-name}:${permission-name}. For commands directly implemented in the application itself only ${permission-name} is required.
Example
[
"core:default",
"shell:allow-open",
"dialog:open",
{
"identifier": "fs:allow-write-text-file",
"allow": [{ "path": "$HOME/test.txt" }]
}
]
platforms
Target[] | null
Limit which target platforms this capability applies to.
By default all platforms are targeted.
Example
["macOS","windows"]
remote
CapabilityRemote | null
Configure remote URLs that can use the capability permissions.
This setting is optional and defaults to not being set, as our default use case is that the content is served from our local application.
Caution
Make sure you understand the security implications of providing remote sources with local system access.
Example
{
"urls": ["https://*.mydomain.dev"]
}
webviews
string[]
List of webviews that are affected by this capability. Can be a glob pattern.
The capability will be enabled on all the webviews whose label matches any of the patterns in this list, regardless of whether the webview’s window label matches a pattern in [Self::windows].
Example
["sub-webview-one", "sub-webview-two"]
windows
string[]
List of windows that are affected by this capability. Can be a glob pattern.
If a window label matches any of the patterns in this list, the capability will be enabled on all the webviews of that window, regardless of the value of [Self::webviews].
On multiwebview windows, prefer specifying [Self::webviews] and omitting [Self::windows] for a fine grained access control.
Example
["main"]
Definitions
CapabilityRemote
Configuration for remote URLs that are associated with the capability.
Object Properties:
- urls (required)
urls
string[]
Remote domains this capability refers to using the URLPattern standard.
Examples
- “https://*.mydomain.dev”: allows subdomains of mydomain.dev
- “https://mydomain.dev/api/*”: allows any subpath of mydomain.dev/api
Identifier
string
Number
Any of the following:
integerformatted asint64Represents an [i64].numberformatted asdoubleRepresents a [f64].
A valid ACL number.
PermissionEntry
Any of the following:
IdentifierReference a permission or permission set by identifier.- Reference a permission or permission set by identifier and extends its scope. Object Properties: - allow - deny - identifier (required) ##### allow
Value[] |nullData that defines what is allowed by the scope. ##### denyValue[] |nullData that defines what is denied by the scope. This should be prioritized by validation logic. ##### identifierIdentifierIdentifier of the permission or permission set.
An entry for a permission value in a [Capability] can be either a raw permission [Identifier] or an object that references a permission and extends its scope.
Target
One of the following:
"macOS"MacOS."windows"Windows."linux"Linux."android"Android."iOS"iOS.
Platform target.
Value
Any of the following:
nullRepresents a null JSON value.booleanRepresents a [bool].NumberRepresents a valid ACL [Number].stringRepresents a [String].Value[] Represents a list of other [Value]s.- Represents a map of [
String] keys to [Value]s. Allows additional properties:Value
All supported ACL values.
Core Permissions
A list of all permissions that can be used with the core of the Tauri framework.
If you are looking for permissions to specific Tauri plugins, please refer to the Plugins section of the documentation.
Default Permissions
The core:default permission in Tauri automatically adds:
core:app:defaultcore:event:defaultcore:image:defaultcore:menu:defaultcore:path:defaultcore:resources:defaultcore:tray:defaultcore:webview:defaultcore:window:default
App
Default Permission
The default permission, core:app:default, includes the following:
allow-versionallow-nameallow-tauri-versionallow-identifierallow-bundle-typeallow-register-listenerallow-remove-listenerallow-supports-multiple-windows
Permission Table
| Identifier | Description |
|---|---|
core:app:allow-app-hide |
Enables the app_hide command without any pre-configured scope. |
core:app:deny-app-hide |
Denies the app_hide command without any pre-configured scope. |
core:app:allow-app-show |
Enables the app_show command without any pre-configured scope. |
core:app:deny-app-show |
Denies the app_show command without any pre-configured scope. |
core:app:allow-bundle-type |
Enables the bundle_type command without any pre-configured scope. |
core:app:deny-bundle-type |
Denies the bundle_type command without any pre-configured scope. |
core:app:allow-default-window-icon |
Enables the default_window_icon command without any pre-configured scope. |
core:app:deny-default-window-icon |
Denies the default_window_icon command without any pre-configured scope. |
core:app:allow-fetch-data-store-identifiers |
Enables the fetch_data_store_identifiers command without any pre-configured scope. |
core:app:deny-fetch-data-store-identifiers |
Denies the fetch_data_store_identifiers command without any pre-configured scope. |
core:app:allow-identifier |
Enables the identifier command without any pre-configured scope. |
core:app:deny-identifier |
Denies the identifier command without any pre-configured scope. |
core:app:allow-name |
Enables the name command without any pre-configured scope. |
core:app:deny-name |
Denies the name command without any pre-configured scope. |
core:app:allow-register-listener |
Enables the register_listener command without any pre-configured scope. |
core:app:deny-register-listener |
Denies the register_listener command without any pre-configured scope. |
core:app:allow-remove-data-store |
Enables the remove_data_store command without any pre-configured scope. |
core:app:deny-remove-data-store |
Denies the remove_data_store command without any pre-configured scope. |
core:app:allow-remove-listener |
Enables the remove_listener command without any pre-configured scope. |
core:app:deny-remove-listener |
Denies the remove_listener command without any pre-configured scope. |
core:app:allow-set-app-theme |
Enables the set_app_theme command without any pre-configured scope. |
core:app:deny-set-app-theme |
Denies the set_app_theme command without any pre-configured scope. |
core:app:allow-set-dock-visibility |
Enables the set_dock_visibility command without any pre-configured scope. |
core:app:deny-set-dock-visibility |
Denies the set_dock_visibility command without any pre-configured scope. |
core:app:allow-supports-multiple-windows |
Enables the supports_multiple_windows command without any pre-configured scope. |
core:app:deny-supports-multiple-windows |
Denies the supports_multiple_windows command without any pre-configured scope. |
core:app:allow-tauri-version |
Enables the tauri_version command without any pre-configured scope. |
core:app:deny-tauri-version |
Denies the tauri_version command without any pre-configured scope. |
core:app:allow-version |
Enables the version command without any pre-configured scope. |
core:app:deny-version |
Denies the version command without any pre-configured scope. |
Event
Default Permission
The default permission, core:event:default, includes the following:
allow-listenallow-unlistenallow-emitallow-emit-to
Permission Table
| Identifier | Description |
|---|---|
core:event:allow-emit |
Enables the emit command without any pre-configured scope. |
core:event:deny-emit |
Denies the emit command without any pre-configured scope. |
core:event:allow-emit-to |
Enables the emit_to command without any pre-configured scope. |
core:event:deny-emit-to |
Denies the emit_to command without any pre-configured scope. |
core:event:allow-listen |
Enables the listen command without any pre-configured scope. |
core:event:deny-listen |
Denies the listen command without any pre-configured scope. |
core:event:allow-unlisten |
Enables the unlisten command without any pre-configured scope. |
core:event:deny-unlisten |
Denies the unlisten command without any pre-configured scope. |
Image
Default Permission
The default permission, core:image:default, includes the following:
allow-newallow-from-bytesallow-from-pathallow-rgbaallow-size
Permission Table
| Identifier | Description |
|---|---|
core:image:allow-from-bytes |
Enables the from_bytes command without any pre-configured scope. |
core:image:deny-from-bytes |
Denies the from_bytes command without any pre-configured scope. |
core:image:allow-from-path |
Enables the from_path command without any pre-configured scope. |
core:image:deny-from-path |
Denies the from_path command without any pre-configured scope. |
core:image:allow-new |
Enables the new command without any pre-configured scope. |
core:image:deny-new |
Denies the new command without any pre-configured scope. |
core:image:allow-rgba |
Enables the rgba command without any pre-configured scope. |
core:image:deny-rgba |
Denies the rgba command without any pre-configured scope. |
core:image:allow-size |
Enables the size command without any pre-configured scope. |
core:image:deny-size |
Denies the size command without any pre-configured scope. |
Menu
Default Permission
The default permission, core:menu:default, includes the following:
allow-newallow-appendallow-prependallow-insertallow-removeallow-remove-atallow-itemsallow-getallow-popupallow-create-defaultallow-set-as-app-menuallow-set-as-window-menuallow-textallow-set-textallow-is-enabledallow-set-enabledallow-set-acceleratorallow-set-as-windows-menu-for-nsappallow-set-as-help-menu-for-nsappallow-is-checkedallow-set-checkedallow-set-icon
Permission Table
| Identifier | Description |
|---|---|
core:menu:allow-append |
Enables the append command without any pre-configured scope. |
core:menu:deny-append |
Denies the append command without any pre-configured scope. |
core:menu:allow-create-default |
Enables the create_default command without any pre-configured scope. |
core:menu:deny-create-default |
Denies the create_default command without any pre-configured scope. |
core:menu:allow-get |
Enables the get command without any pre-configured scope. |
core:menu:deny-get |
Denies the get command without any pre-configured scope. |
core:menu:allow-insert |
Enables the insert command without any pre-configured scope. |
core:menu:deny-insert |
Denies the insert command without any pre-configured scope. |
core:menu:allow-is-checked |
Enables the is_checked command without any pre-configured scope. |
core:menu:deny-is-checked |
Denies the is_checked command without any pre-configured scope. |
core:menu:allow-is-enabled |
Enables the is_enabled command without any pre-configured scope. |
core:menu:deny-is-enabled |
Denies the is_enabled command without any pre-configured scope. |
core:menu:allow-items |
Enables the items command without any pre-configured scope. |
core:menu:deny-items |
Denies the items command without any pre-configured scope. |
core:menu:allow-new |
Enables the new command without any pre-configured scope. |
core:menu:deny-new |
Denies the new command without any pre-configured scope. |
core:menu:allow-popup |
Enables the popup command without any pre-configured scope. |
core:menu:deny-popup |
Denies the popup command without any pre-configured scope. |
core:menu:allow-prepend |
Enables the prepend command without any pre-configured scope. |
core:menu:deny-prepend |
Denies the prepend command without any pre-configured scope. |
core:menu:allow-remove |
Enables the remove command without any pre-configured scope. |
core:menu:deny-remove |
Denies the remove command without any pre-configured scope. |
core:menu:allow-remove-at |
Enables the remove_at command without any pre-configured scope. |
core:menu:deny-remove-at |
Denies the remove_at command without any pre-configured scope. |
core:menu:allow-set-accelerator |
Enables the set_accelerator command without any pre-configured scope. |
core:menu:deny-set-accelerator |
Denies the set_accelerator command without any pre-configured scope. |
core:menu:allow-set-as-app-menu |
Enables the set_as_app_menu command without any pre-configured scope. |
core:menu:deny-set-as-app-menu |
Denies the set_as_app_menu command without any pre-configured scope. |
core:menu:allow-set-as-help-menu-for-nsapp |
Enables the set_as_help_menu_for_nsapp command without any pre-configured scope. |
core:menu:deny-set-as-help-menu-for-nsapp |
Denies the set_as_help_menu_for_nsapp command without any pre-configured scope. |
core:menu:allow-set-as-window-menu |
Enables the set_as_window_menu command without any pre-configured scope. |
core:menu:deny-set-as-window-menu |
Denies the set_as_window_menu command without any pre-configured scope. |
core:menu:allow-set-as-windows-menu-for-nsapp |
Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope. |
core:menu:deny-set-as-windows-menu-for-nsapp |
Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope. |
core:menu:allow-set-checked |
Enables the set_checked command without any pre-configured scope. |
core:menu:deny-set-checked |
Denies the set_checked command without any pre-configured scope. |
core:menu:allow-set-enabled |
Enables the set_enabled command without any pre-configured scope. |
core:menu:deny-set-enabled |
Denies the set_enabled command without any pre-configured scope. |
core:menu:allow-set-icon |
Enables the set_icon command without any pre-configured scope. |
core:menu:deny-set-icon |
Denies the set_icon command without any pre-configured scope. |
core:menu:allow-set-text |
Enables the set_text command without any pre-configured scope. |
core:menu:deny-set-text |
Denies the set_text command without any pre-configured scope. |
core:menu:allow-text |
Enables the text command without any pre-configured scope. |
core:menu:deny-text |
Denies the text command without any pre-configured scope. |
Path
Default Permission
The default permission, core:path:default, includes the following:
allow-resolve-directoryallow-resolveallow-normalizeallow-joinallow-dirnameallow-extnameallow-basenameallow-is-absolute
Permission Table
| Identifier | Description |
|---|---|
core:path:allow-basename |
Enables the basename command without any pre-configured scope. |
core:path:deny-basename |
Denies the basename command without any pre-configured scope. |
core:path:allow-dirname |
Enables the dirname command without any pre-configured scope. |
core:path:deny-dirname |
Denies the dirname command without any pre-configured scope. |
core:path:allow-extname |
Enables the extname command without any pre-configured scope. |
core:path:deny-extname |
Denies the extname command without any pre-configured scope. |
core:path:allow-is-absolute |
Enables the is_absolute command without any pre-configured scope. |
core:path:deny-is-absolute |
Denies the is_absolute command without any pre-configured scope. |
core:path:allow-join |
Enables the join command without any pre-configured scope. |
core:path:deny-join |
Denies the join command without any pre-configured scope. |
core:path:allow-normalize |
Enables the normalize command without any pre-configured scope. |
core:path:deny-normalize |
Denies the normalize command without any pre-configured scope. |
core:path:allow-resolve |
Enables the resolve command without any pre-configured scope. |
core:path:deny-resolve |
Denies the resolve command without any pre-configured scope. |
core:path:allow-resolve-directory |
Enables the resolve_directory command without any pre-configured scope. |
core:path:deny-resolve-directory |
Denies the resolve_directory command without any pre-configured scope. |
Resources
Default Permission
The default permission, core:resources:default, includes the following:
allow-close
Permission Table
| Identifier | Description |
|---|---|
core:resources:allow-close |
Enables the close command without any pre-configured scope. |
core:resources:deny-close |
Denies the close command without any pre-configured scope. |
Tray
Default Permission
The default permission, core:tray:default, includes the following:
allow-newallow-get-by-idallow-remove-by-idallow-set-iconallow-set-menuallow-set-tooltipallow-set-titleallow-set-visibleallow-set-temp-dir-pathallow-set-icon-as-templateallow-set-icon-with-as-templateallow-set-show-menu-on-left-click
Permission Table
| Identifier | Description |
|---|---|
core:tray:allow-get-by-id |
Enables the get_by_id command without any pre-configured scope. |
core:tray:deny-get-by-id |
Denies the get_by_id command without any pre-configured scope. |
core:tray:allow-new |
Enables the new command without any pre-configured scope. |
core:tray:deny-new |
Denies the new command without any pre-configured scope. |
core:tray:allow-remove-by-id |
Enables the remove_by_id command without any pre-configured scope. |
core:tray:deny-remove-by-id |
Denies the remove_by_id command without any pre-configured scope. |
core:tray:allow-set-icon |
Enables the set_icon command without any pre-configured scope. |
core:tray:deny-set-icon |
Denies the set_icon command without any pre-configured scope. |
core:tray:allow-set-icon-as-template |
Enables the set_icon_as_template command without any pre-configured scope. |
core:tray:deny-set-icon-as-template |
Denies the set_icon_as_template command without any pre-configured scope. |
core:tray:allow-set-icon-with-as-template |
Enables the set_icon_with_as_template command without any pre-configured scope. |
core:tray:deny-set-icon-with-as-template |
Denies the set_icon_with_as_template command without any pre-configured scope. |
core:tray:allow-set-menu |
Enables the set_menu command without any pre-configured scope. |
core:tray:deny-set-menu |
Denies the set_menu command without any pre-configured scope. |
core:tray:allow-set-show-menu-on-left-click |
Enables the set_show_menu_on_left_click command without any pre-configured scope. |
core:tray:deny-set-show-menu-on-left-click |
Denies the set_show_menu_on_left_click command without any pre-configured scope. |
core:tray:allow-set-temp-dir-path |
Enables the set_temp_dir_path command without any pre-configured scope. |
core:tray:deny-set-temp-dir-path |
Denies the set_temp_dir_path command without any pre-configured scope. |
core:tray:allow-set-title |
Enables the set_title command without any pre-configured scope. |
core:tray:deny-set-title |
Denies the set_title command without any pre-configured scope. |
core:tray:allow-set-tooltip |
Enables the set_tooltip command without any pre-configured scope. |
core:tray:deny-set-tooltip |
Denies the set_tooltip command without any pre-configured scope. |
core:tray:allow-set-visible |
Enables the set_visible command without any pre-configured scope. |
core:tray:deny-set-visible |
Denies the set_visible command without any pre-configured scope. |
Webview
Default Permission
The default permission, core:webview:default, includes the following:
allow-get-all-webviewsallow-webview-positionallow-webview-sizeallow-internal-toggle-devtools
Permission Table
| Identifier | Description |
|---|---|
core:webview:allow-clear-all-browsing-data |
Enables the clear_all_browsing_data command without any pre-configured scope. |
core:webview:deny-clear-all-browsing-data |
Denies the clear_all_browsing_data command without any pre-configured scope. |
core:webview:allow-create-webview |
Enables the create_webview command without any pre-configured scope. |
core:webview:deny-create-webview |
Denies the create_webview command without any pre-configured scope. |
core:webview:allow-create-webview-window |
Enables the create_webview_window command without any pre-configured scope. |
core:webview:deny-create-webview-window |
Denies the create_webview_window command without any pre-configured scope. |
core:webview:allow-get-all-webviews |
Enables the get_all_webviews command without any pre-configured scope. |
core:webview:deny-get-all-webviews |
Denies the get_all_webviews command without any pre-configured scope. |
core:webview:allow-internal-toggle-devtools |
Enables the internal_toggle_devtools command without any pre-configured scope. |
core:webview:deny-internal-toggle-devtools |
Denies the internal_toggle_devtools command without any pre-configured scope. |
core:webview:allow-print |
Enables the print command without any pre-configured scope. |
core:webview:deny-print |
Denies the print command without any pre-configured scope. |
core:webview:allow-reparent |
Enables the reparent command without any pre-configured scope. |
core:webview:deny-reparent |
Denies the reparent command without any pre-configured scope. |
core:webview:allow-set-webview-auto-resize |
Enables the set_webview_auto_resize command without any pre-configured scope. |
core:webview:deny-set-webview-auto-resize |
Denies the set_webview_auto_resize command without any pre-configured scope. |
core:webview:allow-set-webview-background-color |
Enables the set_webview_background_color command without any pre-configured scope. |
core:webview:deny-set-webview-background-color |
Denies the set_webview_background_color command without any pre-configured scope. |
core:webview:allow-set-webview-focus |
Enables the set_webview_focus command without any pre-configured scope. |
core:webview:deny-set-webview-focus |
Denies the set_webview_focus command without any pre-configured scope. |
core:webview:allow-set-webview-position |
Enables the set_webview_position command without any pre-configured scope. |
core:webview:deny-set-webview-position |
Denies the set_webview_position command without any pre-configured scope. |
core:webview:allow-set-webview-size |
Enables the set_webview_size command without any pre-configured scope. |
core:webview:deny-set-webview-size |
Denies the set_webview_size command without any pre-configured scope. |
core:webview:allow-set-webview-zoom |
Enables the set_webview_zoom command without any pre-configured scope. |
core:webview:deny-set-webview-zoom |
Denies the set_webview_zoom command without any pre-configured scope. |
core:webview:allow-webview-close |
Enables the webview_close command without any pre-configured scope. |
core:webview:deny-webview-close |
Denies the webview_close command without any pre-configured scope. |
core:webview:allow-webview-hide |
Enables the webview_hide command without any pre-configured scope. |
core:webview:deny-webview-hide |
Denies the webview_hide command without any pre-configured scope. |
core:webview:allow-webview-position |
Enables the webview_position command without any pre-configured scope. |
core:webview:deny-webview-position |
Denies the webview_position command without any pre-configured scope. |
core:webview:allow-webview-show |
Enables the webview_show command without any pre-configured scope. |
core:webview:deny-webview-show |
Denies the webview_show command without any pre-configured scope. |
core:webview:allow-webview-size |
Enables the webview_size command without any pre-configured scope. |
core:webview:deny-webview-size |
Denies the webview_size command without any pre-configured scope. |
Window
Default Permission
The default permission, core:window:default, includes the following:
allow-get-all-windowsallow-scale-factorallow-inner-positionallow-outer-positionallow-inner-sizeallow-outer-sizeallow-is-fullscreenallow-is-minimizedallow-is-maximizedallow-is-focusedallow-is-decoratedallow-is-resizableallow-is-maximizableallow-is-minimizableallow-is-closableallow-is-visibleallow-is-enabledallow-titleallow-current-monitorallow-primary-monitorallow-monitor-from-pointallow-available-monitorsallow-cursor-positionallow-themeallow-is-always-on-topallow-activity-nameallow-scene-identifierallow-internal-toggle-maximize
Permission Table
| Identifier | Description |
|---|---|
core:window:allow-activity-name |
Enables the activity_name command without any pre-configured scope. |
core:window:deny-activity-name |
Denies the activity_name command without any pre-configured scope. |
core:window:allow-available-monitors |
Enables the available_monitors command without any pre-configured scope. |
core:window:deny-available-monitors |
Denies the available_monitors command without any pre-configured scope. |
core:window:allow-center |
Enables the center command without any pre-configured scope. |
core:window:deny-center |
Denies the center command without any pre-configured scope. |
core:window:allow-close |
Enables the close command without any pre-configured scope. |
core:window:deny-close |
Denies the close command without any pre-configured scope. |
core:window:allow-create |
Enables the create command without any pre-configured scope. |
core:window:deny-create |
Denies the create command without any pre-configured scope. |
core:window:allow-current-monitor |
Enables the current_monitor command without any pre-configured scope. |
core:window:deny-current-monitor |
Denies the current_monitor command without any pre-configured scope. |
core:window:allow-cursor-position |
Enables the cursor_position command without any pre-configured scope. |
core:window:deny-cursor-position |
Denies the cursor_position command without any pre-configured scope. |
core:window:allow-destroy |
Enables the destroy command without any pre-configured scope. |
core:window:deny-destroy |
Denies the destroy command without any pre-configured scope. |
core:window:allow-get-all-windows |
Enables the get_all_windows command without any pre-configured scope. |
core:window:deny-get-all-windows |
Denies the get_all_windows command without any pre-configured scope. |
core:window:allow-hide |
Enables the hide command without any pre-configured scope. |
core:window:deny-hide |
Denies the hide command without any pre-configured scope. |
core:window:allow-inner-position |
Enables the inner_position command without any pre-configured scope. |
core:window:deny-inner-position |
Denies the inner_position command without any pre-configured scope. |
core:window:allow-inner-size |
Enables the inner_size command without any pre-configured scope. |
core:window:deny-inner-size |
Denies the inner_size command without any pre-configured scope. |
core:window:allow-internal-toggle-maximize |
Enables the internal_toggle_maximize command without any pre-configured scope. |
core:window:deny-internal-toggle-maximize |
Denies the internal_toggle_maximize command without any pre-configured scope. |
core:window:allow-is-always-on-top |
Enables the is_always_on_top command without any pre-configured scope. |
core:window:deny-is-always-on-top |
Denies the is_always_on_top command without any pre-configured scope. |
core:window:allow-is-closable |
Enables the is_closable command without any pre-configured scope. |
core:window:deny-is-closable |
Denies the is_closable command without any pre-configured scope. |
core:window:allow-is-decorated |
Enables the is_decorated command without any pre-configured scope. |
core:window:deny-is-decorated |
Denies the is_decorated command without any pre-configured scope. |
core:window:allow-is-enabled |
Enables the is_enabled command without any pre-configured scope. |
core:window:deny-is-enabled |
Denies the is_enabled command without any pre-configured scope. |
core:window:allow-is-focused |
Enables the is_focused command without any pre-configured scope. |
core:window:deny-is-focused |
Denies the is_focused command without any pre-configured scope. |
core:window:allow-is-fullscreen |
Enables the is_fullscreen command without any pre-configured scope. |
core:window:deny-is-fullscreen |
Denies the is_fullscreen command without any pre-configured scope. |
core:window:allow-is-maximizable |
Enables the is_maximizable command without any pre-configured scope. |
core:window:deny-is-maximizable |
Denies the is_maximizable command without any pre-configured scope. |
core:window:allow-is-maximized |
Enables the is_maximized command without any pre-configured scope. |
core:window:deny-is-maximized |
Denies the is_maximized command without any pre-configured scope. |
core:window:allow-is-minimizable |
Enables the is_minimizable command without any pre-configured scope. |
core:window:deny-is-minimizable |
Denies the is_minimizable command without any pre-configured scope. |
core:window:allow-is-minimized |
Enables the is_minimized command without any pre-configured scope. |
core:window:deny-is-minimized |
Denies the is_minimized command without any pre-configured scope. |
core:window:allow-is-resizable |
Enables the is_resizable command without any pre-configured scope. |
core:window:deny-is-resizable |
Denies the is_resizable command without any pre-configured scope. |
core:window:allow-is-visible |
Enables the is_visible command without any pre-configured scope. |
core:window:deny-is-visible |
Denies the is_visible command without any pre-configured scope. |
core:window:allow-maximize |
Enables the maximize command without any pre-configured scope. |
core:window:deny-maximize |
Denies the maximize command without any pre-configured scope. |
core:window:allow-minimize |
Enables the minimize command without any pre-configured scope. |
core:window:deny-minimize |
Denies the minimize command without any pre-configured scope. |
core:window:allow-monitor-from-point |
Enables the monitor_from_point command without any pre-configured scope. |
core:window:deny-monitor-from-point |
Denies the monitor_from_point command without any pre-configured scope. |
core:window:allow-outer-position |
Enables the outer_position command without any pre-configured scope. |
core:window:deny-outer-position |
Denies the outer_position command without any pre-configured scope. |
core:window:allow-outer-size |
Enables the outer_size command without any pre-configured scope. |
core:window:deny-outer-size |
Denies the outer_size command without any pre-configured scope. |
core:window:allow-primary-monitor |
Enables the primary_monitor command without any pre-configured scope. |
core:window:deny-primary-monitor |
Denies the primary_monitor command without any pre-configured scope. |
core:window:allow-request-user-attention |
Enables the request_user_attention command without any pre-configured scope. |
core:window:deny-request-user-attention |
Denies the request_user_attention command without any pre-configured scope. |
core:window:allow-scale-factor |
Enables the scale_factor command without any pre-configured scope. |
core:window:deny-scale-factor |
Denies the scale_factor command without any pre-configured scope. |
core:window:allow-scene-identifier |
Enables the scene_identifier command without any pre-configured scope. |
core:window:deny-scene-identifier |
Denies the scene_identifier command without any pre-configured scope. |
core:window:allow-set-always-on-bottom |
Enables the set_always_on_bottom command without any pre-configured scope. |
core:window:deny-set-always-on-bottom |
Denies the set_always_on_bottom command without any pre-configured scope. |
core:window:allow-set-always-on-top |
Enables the set_always_on_top command without any pre-configured scope. |
core:window:deny-set-always-on-top |
Denies the set_always_on_top command without any pre-configured scope. |
core:window:allow-set-background-color |
Enables the set_background_color command without any pre-configured scope. |
core:window:deny-set-background-color |
Denies the set_background_color command without any pre-configured scope. |
core:window:allow-set-badge-count |
Enables the set_badge_count command without any pre-configured scope. |
core:window:deny-set-badge-count |
Denies the set_badge_count command without any pre-configured scope. |
core:window:allow-set-badge-label |
Enables the set_badge_label command without any pre-configured scope. |
core:window:deny-set-badge-label |
Denies the set_badge_label command without any pre-configured scope. |
core:window:allow-set-closable |
Enables the set_closable command without any pre-configured scope. |
core:window:deny-set-closable |
Denies the set_closable command without any pre-configured scope. |
core:window:allow-set-content-protected |
Enables the set_content_protected command without any pre-configured scope. |
core:window:deny-set-content-protected |
Denies the set_content_protected command without any pre-configured scope. |
core:window:allow-set-cursor-grab |
Enables the set_cursor_grab command without any pre-configured scope. |
core:window:deny-set-cursor-grab |
Denies the set_cursor_grab command without any pre-configured scope. |
core:window:allow-set-cursor-icon |
Enables the set_cursor_icon command without any pre-configured scope. |
core:window:deny-set-cursor-icon |
Denies the set_cursor_icon command without any pre-configured scope. |
core:window:allow-set-cursor-position |
Enables the set_cursor_position command without any pre-configured scope. |
core:window:deny-set-cursor-position |
Denies the set_cursor_position command without any pre-configured scope. |
core:window:allow-set-cursor-visible |
Enables the set_cursor_visible command without any pre-configured scope. |
core:window:deny-set-cursor-visible |
Denies the set_cursor_visible command without any pre-configured scope. |
core:window:allow-set-decorations |
Enables the set_decorations command without any pre-configured scope. |
core:window:deny-set-decorations |
Denies the set_decorations command without any pre-configured scope. |
core:window:allow-set-effects |
Enables the set_effects command without any pre-configured scope. |
core:window:deny-set-effects |
Denies the set_effects command without any pre-configured scope. |
core:window:allow-set-enabled |
Enables the set_enabled command without any pre-configured scope. |
core:window:deny-set-enabled |
Denies the set_enabled command without any pre-configured scope. |
core:window:allow-set-focus |
Enables the set_focus command without any pre-configured scope. |
core:window:deny-set-focus |
Denies the set_focus command without any pre-configured scope. |
core:window:allow-set-focusable |
Enables the set_focusable command without any pre-configured scope. |
core:window:deny-set-focusable |
Denies the set_focusable command without any pre-configured scope. |
core:window:allow-set-fullscreen |
Enables the set_fullscreen command without any pre-configured scope. |
core:window:deny-set-fullscreen |
Denies the set_fullscreen command without any pre-configured scope. |
core:window:allow-set-icon |
Enables the set_icon command without any pre-configured scope. |
core:window:deny-set-icon |
Denies the set_icon command without any pre-configured scope. |
core:window:allow-set-ignore-cursor-events |
Enables the set_ignore_cursor_events command without any pre-configured scope. |
core:window:deny-set-ignore-cursor-events |
Denies the set_ignore_cursor_events command without any pre-configured scope. |
core:window:allow-set-max-size |
Enables the set_max_size command without any pre-configured scope. |
core:window:deny-set-max-size |
Denies the set_max_size command without any pre-configured scope. |
core:window:allow-set-maximizable |
Enables the set_maximizable command without any pre-configured scope. |
core:window:deny-set-maximizable |
Denies the set_maximizable command without any pre-configured scope. |
core:window:allow-set-min-size |
Enables the set_min_size command without any pre-configured scope. |
core:window:deny-set-min-size |
Denies the set_min_size command without any pre-configured scope. |
core:window:allow-set-minimizable |
Enables the set_minimizable command without any pre-configured scope. |
core:window:deny-set-minimizable |
Denies the set_minimizable command without any pre-configured scope. |
core:window:allow-set-overlay-icon |
Enables the set_overlay_icon command without any pre-configured scope. |
core:window:deny-set-overlay-icon |
Denies the set_overlay_icon command without any pre-configured scope. |
core:window:allow-set-position |
Enables the set_position command without any pre-configured scope. |
core:window:deny-set-position |
Denies the set_position command without any pre-configured scope. |
core:window:allow-set-progress-bar |
Enables the set_progress_bar command without any pre-configured scope. |
core:window:deny-set-progress-bar |
Denies the set_progress_bar command without any pre-configured scope. |
core:window:allow-set-resizable |
Enables the set_resizable command without any pre-configured scope. |
core:window:deny-set-resizable |
Denies the set_resizable command without any pre-configured scope. |
core:window:allow-set-shadow |
Enables the set_shadow command without any pre-configured scope. |
core:window:deny-set-shadow |
Denies the set_shadow command without any pre-configured scope. |
core:window:allow-set-simple-fullscreen |
Enables the set_simple_fullscreen command without any pre-configured scope. |
core:window:deny-set-simple-fullscreen |
Denies the set_simple_fullscreen command without any pre-configured scope. |
core:window:allow-set-size |
Enables the set_size command without any pre-configured scope. |
core:window:deny-set-size |
Denies the set_size command without any pre-configured scope. |
core:window:allow-set-size-constraints |
Enables the set_size_constraints command without any pre-configured scope. |
core:window:deny-set-size-constraints |
Denies the set_size_constraints command without any pre-configured scope. |
core:window:allow-set-skip-taskbar |
Enables the set_skip_taskbar command without any pre-configured scope. |
core:window:deny-set-skip-taskbar |
Denies the set_skip_taskbar command without any pre-configured scope. |
core:window:allow-set-theme |
Enables the set_theme command without any pre-configured scope. |
core:window:deny-set-theme |
Denies the set_theme command without any pre-configured scope. |
core:window:allow-set-title |
Enables the set_title command without any pre-configured scope. |
core:window:deny-set-title |
Denies the set_title command without any pre-configured scope. |
core:window:allow-set-title-bar-style |
Enables the set_title_bar_style command without any pre-configured scope. |
core:window:deny-set-title-bar-style |
Denies the set_title_bar_style command without any pre-configured scope. |
core:window:allow-set-visible-on-all-workspaces |
Enables the set_visible_on_all_workspaces command without any pre-configured scope. |
core:window:deny-set-visible-on-all-workspaces |
Denies the set_visible_on_all_workspaces command without any pre-configured scope. |
core:window:allow-show |
Enables the show command without any pre-configured scope. |
core:window:deny-show |
Denies the show command without any pre-configured scope. |
core:window:allow-start-dragging |
Enables the start_dragging command without any pre-configured scope. |
core:window:deny-start-dragging |
Denies the start_dragging command without any pre-configured scope. |
core:window:allow-start-resize-dragging |
Enables the start_resize_dragging command without any pre-configured scope. |
core:window:deny-start-resize-dragging |
Denies the start_resize_dragging command without any pre-configured scope. |
core:window:allow-theme |
Enables the theme command without any pre-configured scope. |
core:window:deny-theme |
Denies the theme command without any pre-configured scope. |
core:window:allow-title |
Enables the title command without any pre-configured scope. |
core:window:deny-title |
Denies the title command without any pre-configured scope. |
core:window:allow-toggle-maximize |
Enables the toggle_maximize command without any pre-configured scope. |
core:window:deny-toggle-maximize |
Denies the toggle_maximize command without any pre-configured scope. |
core:window:allow-unmaximize |
Enables the unmaximize command without any pre-configured scope. |
core:window:deny-unmaximize |
Denies the unmaximize command without any pre-configured scope. |
core:window:allow-unminimize |
Enables the unminimize command without any pre-configured scope. |
core:window:deny-unminimize |
Denies the unminimize command without any pre-configured scope. |
Permission
Descriptions of explicit privileges of commands.
It can enable commands to be accessible in the frontend of the application.
If the scope is defined it can be used to fine grain control the access of individual or multiple commands.
Object Properties:
- commands
- description
- identifier (required)
- platforms
- scope
- version
commands
Allowed or denied commands when using this permission.
Default
{
"allow": [],
"deny": []
}
description
string | null
Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.
identifier
string
A unique identifier for the permission.
platforms
Target[] | null
Target platforms this permission applies. By default all platforms are affected by this permission.
scope
Allowed or denied scoped when using this permission.
version
integer | null minimum of 1, formatted as uint64
The version of the permission.
Definitions
Commands
Allowed and denied commands inside a permission.
If two commands clash inside of allow and deny, it should be denied by default.
Object Properties:
- allow
- deny
allow
string[]
Allowed command.
Default: []
deny
string[]
Denied command, which takes priority.
Default: []
Number
Any of the following:
integerformatted asint64Represents an [i64].numberformatted asdoubleRepresents a [f64].
A valid ACL number.
Scopes
An argument for fine grained behavior control of Tauri commands.
It can be of any serde serializable type and is used to allow or prevent certain actions inside a Tauri command. The configured scope is passed to the command and will be enforced by the command implementation.
Example
{
"allow": [{ "path": "$HOME/**" }],
"deny": [{ "path": "$HOME/secret.txt" }]
}
Object Properties:
- allow
- deny
allow
Value[] | null
Data that defines what is allowed by the scope.
deny
Value[] | null
Data that defines what is denied by the scope. This should be prioritized by validation logic.
Target
One of the following:
"macOS"MacOS."windows"Windows."linux"Linux."android"Android."iOS"iOS.
Platform target.
Value
Any of the following:
nullRepresents a null JSON value.booleanRepresents a [bool].NumberRepresents a valid ACL [Number].stringRepresents a [String].Value[] Represents a list of other [Value]s.- Represents a map of [
String] keys to [Value]s. Allows additional properties:Value
All supported ACL values.
Scope
An argument for fine grained behavior control of Tauri commands.
It can be of any serde serializable type and is used to allow or prevent certain actions inside a Tauri command. The configured scope is passed to the command and will be enforced by the command implementation.
Example
{
"allow": [{ "path": "$HOME/**" }],
"deny": [{ "path": "$HOME/secret.txt" }]
}
Object Properties:
- allow
- deny
allow
Value[] | null
Data that defines what is allowed by the scope.
deny
Value[] | null
Data that defines what is denied by the scope. This should be prioritized by validation logic.
Definitions
Number
Any of the following:
integerformatted asint64Represents an [i64].numberformatted asdoubleRepresents a [f64].
A valid ACL number.
Value
Any of the following:
nullRepresents a null JSON value.booleanRepresents a [bool].NumberRepresents a valid ACL [Number].stringRepresents a [String].Value[] Represents a list of other [Value]s.- Represents a map of [
String] keys to [Value]s. Allows additional properties:Value
All supported ACL values.
Command Line Interface
The Tauri command line interface (CLI) is the way to interact with Tauri throughout the development lifecycle.
You can add the Tauri CLI to your current project using your package manager of choice:
-
npm
npm install --save-dev @tauri-apps/cli@latest -
yarn
yarn add -D @tauri-apps/cli@latest -
pnpm
pnpm add -D @tauri-apps/cli@latest -
deno
deno add -D npm:@tauri-apps/cli@latest -
cargo
cargo install tauri-cli --version "^2.0.0" --locked
Developing a Plugin
For CLI commands related to developing plugins visit the Develop a Tauri Plugin guide.
List of Commands
| Command | Description |
|---|---|
init |
Initialize a Tauri project in an existing directory |
dev |
Run your app in development mode |
build |
Build your app in release mode and generate bundles and installers |
bundle |
Generate bundles and installers for your app (already built by tauri build) |
android |
Android commands |
android init |
Initialize Android target in the project |
android dev |
Run your app in development mode on Android |
android build |
Build your app in release mode for Android and generate APKs and AABs |
android run |
Run your app in production mode on Android |
ios |
iOS commands |
ios init |
Initialize iOS target in the project |
ios dev |
Run your app in development mode on iOS |
ios build |
Build your app in release mode for iOS and generate IPAs |
ios run |
Run your app in production mode on iOS |
migrate |
Migrate from v1 to v2 |
info |
Show a concise list of information about the environment, Rust, Node.js and their versions as well as a few relevant project configurations |
add |
Add a tauri plugin to the project |
remove |
Remove a tauri plugin from the project |
plugin |
Manage or create Tauri plugins |
plugin new |
Initializes a new Tauri plugin project |
plugin init |
Initialize a Tauri plugin project on an existing directory |
plugin android |
Manage the Android project for a Tauri plugin |
plugin ios |
Manage the iOS project for a Tauri plugin |
plugin android init |
Initializes the Android project for an existing Tauri plugin |
plugin ios init |
Initializes the iOS project for an existing Tauri plugin |
icon |
Generate various icons for all major platforms |
signer |
Generate signing keys for Tauri updater or sign files |
signer sign |
Sign a file |
signer generate |
Generate a new signing key to sign files |
completions |
Generate Tauri CLI shell completions for Bash, Zsh, PowerShell or Fish |
permission |
Manage or create permissions for your app or plugin |
permission new |
Create a new permission file |
permission add |
Add a permission to capabilities |
permission rm |
Remove a permission file, and its reference from any capability |
permission ls |
List permissions available to your application |
capability |
Manage or create capabilities for your app |
capability new |
Create a new permission file |
inspect |
Inspect values used by Tauri |
inspect wix-upgrade-code |
Print the default Upgrade Code used by MSI installer derived from productName |
init
-
npm
npm run tauri init -
yarn
yarn tauri init -
pnpm
pnpm tauri init -
deno
deno task tauri init -
bun
bun tauri init -
cargo
cargo tauri init
Initialize a Tauri project in an existing directory
Usage: tauri init [OPTIONS]
Options:
--ci
Skip prompting for values [env: CI=true]
-v, --verbose...
Enables verbose logging
-f, --force
Force init to overwrite the src-tauri folder
-l, --log
Enables logging
-d, --directory <DIRECTORY>
Set target directory for init [default: /opt/build/repo/packages/cli-generator]
-t, --tauri-path <TAURI_PATH>
Path of the Tauri project to use (relative to the cwd)
-A, --app-name <APP_NAME>
Name of your Tauri application
-W, --window-title <WINDOW_TITLE>
Window title of your Tauri application
-D, --frontend-dist <FRONTEND_DIST>
Web assets location, relative to <project-dir>/src-tauri
-P, --dev-url <DEV_URL>
Url of your dev server
--before-dev-command <BEFORE_DEV_COMMAND>
A shell command to run before `tauri dev` kicks in
--before-build-command <BEFORE_BUILD_COMMAND>
A shell command to run before `tauri build` kicks in
-h, --help
Print help
-V, --version
Print version
dev
-
npm
npm run tauri dev -
yarn
yarn tauri dev -
pnpm
pnpm tauri dev -
deno
deno task tauri dev -
bun
bun tauri dev -
cargo
cargo tauri dev
Run your app in development mode with hot-reloading for the Rust code. It makes use of the `build.devUrl` property from your `tauri.conf.json` file. It also runs your `build.beforeDevCommand` which usually starts your frontend devServer.
Usage: tauri dev [OPTIONS] [ARGS]...
Arguments:
[ARGS]...
Command line arguments passed to the runner. Use `--` to explicitly mark the start of the arguments. Arguments after a second `--` are passed to the application e.g. `tauri dev -- [runnerArgs] -- [appArgs]`
Options:
-r, --runner <RUNNER>
Binary to use to run the application
-v, --verbose...
Enables verbose logging
-t, --target <TARGET>
Target triple to build against
-f, --features [<FEATURES>...]
List of cargo features to activate
-e, --exit-on-panic
Exit on panic
-c, --config <CONFIG>
JSON strings or paths to JSON, JSON5 or TOML files to merge with the default configuration file
Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
Note that a platform-specific file is looked up and merged with the default file by default (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json) but you can use this for more specific use cases such as different build flavors.
--release
Run the code in release mode
--no-dev-server-wait
Skip waiting for the frontend dev server to start before building the tauri application
[env: TAURI_CLI_NO_DEV_SERVER_WAIT=]
--no-watch
Disable the file watcher
--additional-watch-folders <ADDITIONAL_WATCH_FOLDERS>
Additional paths to watch for changes
--no-dev-server
Disable the built-in dev server for static files
--port <PORT>
Specify port for the built-in dev server for static files. Defaults to 1430
[env: TAURI_CLI_PORT=]
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
build
-
npm
npm run tauri build -
yarn
yarn tauri build -
pnpm
pnpm tauri build -
deno
deno task tauri build -
bun
bun tauri build -
cargo
cargo tauri build
Build your app in release mode and generate bundles and installers. It makes use of the `build.frontendDist` property from your `tauri.conf.json` file. It also runs your `build.beforeBuildCommand` which usually builds your frontend into `build.frontendDist`. This will also run `build.beforeBundleCommand` before generating the bundles and installers of your app.
Usage: tauri build [OPTIONS] [ARGS]...
Arguments:
[ARGS]...
Command line arguments passed to the runner. Use `--` to explicitly mark the start of the arguments
Options:
-r, --runner <RUNNER>
Binary to use to build the application, defaults to `cargo`
-v, --verbose...
Enables verbose logging
-d, --debug
Builds with the debug flag
-t, --target <TARGET>
Target triple to build against.
It must be one of the values outputted by `$rustc --print target-list` or `universal-apple-darwin` for an universal macOS application.
Note that compiling an universal macOS application requires both `aarch64-apple-darwin` and `x86_64-apple-darwin` targets to be installed.
-f, --features [<FEATURES>...]
Space or comma separated list of features to activate
-b, --bundles [<BUNDLES>...]
Space or comma separated list of bundles to package
[possible values: deb, rpm, appimage]
--no-bundle
Skip the bundling step even if `bundle > active` is `true` in tauri config
-c, --config <CONFIG>
JSON strings or paths to JSON, JSON5 or TOML files to merge with the default configuration file
Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
Note that a platform-specific file is looked up and merged with the default file by default (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json) but you can use this for more specific use cases such as different build flavors.
--ci
Skip prompting for values
[env: CI=true]
--skip-stapling
Whether to wait for notarization to finish and `staple` the ticket onto the app.
Gatekeeper will look for stapled tickets to tell whether your app was notarized without reaching out to Apple's servers which is helpful in offline environments.
Enabling this option will also result in `tauri build` not waiting for notarization to finish which is helpful for the very first time your app is notarized as this can take multiple hours. On subsequent runs, it's recommended to disable this setting again.
--ignore-version-mismatches
Do not error out if a version mismatch is detected on a Tauri package.
Only use this when you are sure the mismatch is incorrectly detected as version mismatched Tauri packages can lead to unknown behavior.
--no-sign
Skip code signing when bundling the app
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
bundle
-
npm
npm run tauri bundle -
yarn
yarn tauri bundle -
pnpm
pnpm tauri bundle -
deno
deno task tauri bundle -
bun
bun tauri bundle -
cargo
cargo tauri bundle
Generate bundles and installers for your app (already built by `tauri build`). This run `build.beforeBundleCommand` before generating the bundles and installers of your app.
Usage: tauri bundle [OPTIONS]
Options:
-d, --debug
Builds with the debug flag
-v, --verbose...
Enables verbose logging
-b, --bundles [<BUNDLES>...]
Space or comma separated list of bundles to package
[possible values: deb, rpm, appimage]
-c, --config <CONFIG>
JSON strings or paths to JSON, JSON5 or TOML files to merge with the default configuration file
Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
Note that a platform-specific file is looked up and merged with the default file by default (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json) but you can use this for more specific use cases such as different build flavors.
-f, --features [<FEATURES>...]
Space or comma separated list of features, should be the same features passed to `tauri build` if any
-t, --target <TARGET>
Target triple to build against.
It must be one of the values outputted by `$rustc --print target-list` or `universal-apple-darwin` for an universal macOS application.
Note that compiling an universal macOS application requires both `aarch64-apple-darwin` and `x86_64-apple-darwin` targets to be installed.
--ci
Skip prompting for values
[env: CI=true]
--skip-stapling
Whether to wait for notarization to finish and `staple` the ticket onto the app.
Gatekeeper will look for stapled tickets to tell whether your app was notarized without reaching out to Apple's servers which is helpful in offline environments.
Enabling this option will also result in `tauri build` not waiting for notarization to finish which is helpful for the very first time your app is notarized as this can take multiple hours. On subsequent runs, it's recommended to disable this setting again.
--no-sign
Skip code signing during the build or bundling process.
Useful for local development and CI environments where signing certificates or environment variables are not available or not needed.
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
android
-
npm
npm run tauri android -
yarn
yarn tauri android -
pnpm
pnpm tauri android -
deno
deno task tauri android -
bun
bun tauri android -
cargo
cargo tauri android
Android commands
Usage: tauri android [OPTIONS] <COMMAND>
Commands:
init Initialize Android target in the project
dev Run your app in development mode on Android
build Build your app in release mode for Android and generate APKs and AABs
run Run your app in production mode on Android
help Print this message or the help of the given subcommand(s)
Options:
-v, --verbose... Enables verbose logging
-h, --help Print help
-V, --version Print version
android init
-
npm
npm run tauri android init -
yarn
yarn tauri android init -
pnpm
pnpm tauri android init -
deno
deno task tauri android init -
bun
bun tauri android init -
cargo
cargo tauri android init
Initialize Android target in the project
Usage: tauri android init [OPTIONS]
Options:
--ci
Skip prompting for values
[env: CI=true]
-v, --verbose...
Enables verbose logging
--skip-targets-install
Skips installing rust toolchains via rustup
-c, --config <CONFIG>
JSON strings or paths to JSON, JSON5 or TOML files to merge with the default configuration file
Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
Note that a platform-specific file is looked up and merged with the default file by default (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json) but you can use this for more specific use cases such as different build flavors.
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
android dev
-
npm
npm run tauri android dev -
yarn
yarn tauri android dev -
pnpm
pnpm tauri android dev -
deno
deno task tauri android dev -
bun
bun tauri android dev -
cargo
cargo tauri android dev
Run your app in development mode on Android with hot-reloading for the Rust code. It makes use of the `build.devUrl` property from your `tauri.conf.json` file. It also runs your `build.beforeDevCommand` which usually starts your frontend devServer.
Usage: tauri android dev [OPTIONS] [DEVICE] [-- <ARGS>...]
Arguments:
[DEVICE]
Runs on the given device name
[ARGS]...
Command line arguments passed to the runner. Use `--` to explicitly mark the start of the arguments. e.g. `tauri android dev -- [runnerArgs]`
Options:
-f, --features [<FEATURES>...]
List of cargo features to activate
-v, --verbose...
Enables verbose logging
-e, --exit-on-panic
Exit on panic
-c, --config <CONFIG>
JSON strings or paths to JSON, JSON5 or TOML files to merge with the default configuration file
Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
Note that a platform-specific file is looked up and merged with the default file by default (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json) but you can use this for more specific use cases such as different build flavors.
--release
Run the code in release mode
--no-dev-server-wait
Skip waiting for the frontend dev server to start before building the tauri application
[env: TAURI_CLI_NO_DEV_SERVER_WAIT=]
--no-watch
Disable the file watcher
--additional-watch-folders <ADDITIONAL_WATCH_FOLDERS>
Additional paths to watch for changes
-o, --open
Open Android Studio instead of trying to run on a connected device
--force-ip-prompt
Force prompting for an IP to use to connect to the dev server on mobile
--host [<HOST>]
Use the public network address for the development server. If an actual address it provided, it is used instead of prompting to pick one.
On Windows we use the public network address by default.
This option is particularly useful along the `--open` flag when you intend on running on a physical device.
This replaces the devUrl configuration value to match the public network address host, it is your responsibility to set up your development server to listen on this address by using 0.0.0.0 as host for instance.
When this is set or when running on an iOS device the CLI sets the `TAURI_DEV_HOST` environment variable so you can check this on your framework's configuration to expose the development server on the public network address.
[default: <none>]
--no-dev-server
Disable the built-in dev server for static files
--port <PORT>
Specify port for the built-in dev server for static files. Defaults to 1430
[env: TAURI_CLI_PORT=]
--root-certificate-path <ROOT_CERTIFICATE_PATH>
Path to the certificate file used by your dev server. Required for mobile dev when using HTTPS
[env: TAURI_DEV_ROOT_CERTIFICATE_PATH=]
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
android build
-
npm
npm run tauri android build -
yarn
yarn tauri android build -
pnpm
pnpm tauri android build -
deno
deno task tauri android build -
bun
bun tauri android build -
cargo
cargo tauri android build
Build your app in release mode for Android and generate APKs and AABs. It makes use of the `build.frontendDist` property from your `tauri.conf.json` file. It also runs your `build.beforeBuildCommand` which usually builds your frontend into `build.frontendDist`.
Usage: tauri android build [OPTIONS] [-- <ARGS>...]
Arguments:
[ARGS]...
Command line arguments passed to the runner. Use `--` to explicitly mark the start of the arguments. e.g. `tauri android build -- [runnerArgs]`
Options:
-d, --debug
Builds with the debug flag
-v, --verbose...
Enables verbose logging
-t, --target [<TARGETS>...]
Which targets to build (all by default)
[possible values: aarch64, armv7, i686, x86_64]
-f, --features [<FEATURES>...]
List of cargo features to activate
-c, --config <CONFIG>
JSON strings or paths to JSON, JSON5 or TOML files to merge with the default configuration file
Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
Note that a platform-specific file is looked up and merged with the default file by default (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json) but you can use this for more specific use cases such as different build flavors.
--split-per-abi
Whether to split the APKs and AABs per ABIs
--apk
Build APKs
--aab
Build AABs
-o, --open
Open Android Studio
--ci
Skip prompting for values
[env: CI=true]
--ignore-version-mismatches
Do not error out if a version mismatch is detected on a Tauri package.
Only use this when you are sure the mismatch is incorrectly detected as version mismatched Tauri packages can lead to unknown behavior.
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
android run
-
npm
npm run tauri android run -
yarn
yarn tauri android run -
pnpm
pnpm tauri android run -
deno
deno task tauri android run -
bun
bun tauri android run -
cargo
cargo tauri android run
Run your app in production mode on Android. It makes use of the `build.frontendDist` property from your `tauri.conf.json` file. It also runs your `build.beforeBuildCommand` which usually builds your frontend into `build.frontendDist`.
Usage: tauri android run [OPTIONS] [DEVICE] [-- <ARGS>...]
Arguments:
[DEVICE]
Runs on the given device name
[ARGS]...
Command line arguments passed to the runner. Use `--` to explicitly mark the start of the arguments. e.g. `tauri android build -- [runnerArgs]`
Options:
-r, --release
Run the app in release mode
-v, --verbose...
Enables verbose logging
-f, --features [<FEATURES>...]
List of cargo features to activate
-c, --config <CONFIG>
JSON strings or paths to JSON, JSON5 or TOML files to merge with the default configuration file
Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
Note that a platform-specific file is looked up and merged with the default file by default (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json) but you can use this for more specific use cases such as different build flavors.
--no-watch
Disable the file watcher
--additional-watch-folders <ADDITIONAL_WATCH_FOLDERS>
Additional paths to watch for changes
-o, --open
Open Android Studio
--ignore-version-mismatches
Do not error out if a version mismatch is detected on a Tauri package.
Only use this when you are sure the mismatch is incorrectly detected as version mismatched Tauri packages can lead to unknown behavior.
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
ios
All iOS commands are only available on macOS hosts.
-
npm
npm run tauri ios -
yarn
yarn tauri ios -
pnpm
pnpm tauri ios -
deno
deno task tauri ios -
bun
bun tauri ios -
cargo
cargo tauri ios
iOS commands
Usage: tauri ios [OPTIONS] <COMMAND>
Commands:
init Initialize iOS target in the project
dev Run your app in development mode on iOS
build Build your app in release mode for iOS and generate IPAs
run Run your app in production mode on iOS
help Print this message or the help of the given subcommand(s)
Options:
-v, --verbose... Enables verbose logging
-h, --help Print help
-V, --version Print version
ios init
All iOS commands are only available on macOS hosts.
-
npm
npm run tauri ios init -
yarn
yarn tauri ios init -
pnpm
pnpm tauri ios init -
deno
deno task tauri ios init -
bun
bun tauri ios init -
cargo
cargo tauri ios init
Initialize iOS target in the project
Usage: tauri ios init [OPTIONS]
Options:
--ci
Skip prompting for values
[env: CI=]
-v, --verbose...
Enables verbose logging
-r, --reinstall-deps
Reinstall dependencies
--skip-targets-install
Skips installing rust toolchains via rustup
-c, --config <CONFIG>
JSON strings or paths to JSON, JSON5 or TOML files to merge with the default configuration file
Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
Note that a platform-specific file is looked up and merged with the default file by default (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json) but you can use this for more specific use cases such as different build flavors.
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
ios dev
All iOS commands are only available on macOS hosts.
-
npm
npm run tauri ios dev -
yarn
yarn tauri ios dev -
pnpm
pnpm tauri ios dev -
deno
deno task tauri ios dev -
bun
bun tauri ios dev -
cargo
cargo tauri ios dev
Run your app in development mode on iOS with hot-reloading for the Rust code.
It makes use of the `build.devUrl` property from your `tauri.conf.json` file.
It also runs your `build.beforeDevCommand` which usually starts your frontend devServer.
When connected to a physical iOS device, the public network address must be used instead of `localhost`
for the devUrl property. Tauri makes that change automatically, but your dev server might need
a different configuration to listen on the public address. You can check the `TAURI_DEV_HOST`
environment variable to determine whether the public network should be used or not.
Usage: tauri ios dev [OPTIONS] [DEVICE] [-- <ARGS>...]
Arguments:
[DEVICE]
Runs on the given device name
[ARGS]...
Command line arguments passed to the runner. Use `--` to explicitly mark the start of the arguments. e.g. `tauri ios dev -- [runnerArgs]`
Options:
-f, --features [<FEATURES>...]
List of cargo features to activate
-v, --verbose...
Enables verbose logging
-e, --exit-on-panic
Exit on panic
-c, --config <CONFIG>
JSON strings or paths to JSON, JSON5 or TOML files to merge with the default configuration file
Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
Note that a platform-specific file is looked up and merged with the default file by default (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json) but you can use this for more specific use cases such as different build flavors.
--release
Run the code in release mode
--no-dev-server-wait
Skip waiting for the frontend dev server to start before building the tauri application
[env: TAURI_CLI_NO_DEV_SERVER_WAIT=]
--no-watch
Disable the file watcher
--additional-watch-folders <ADDITIONAL_WATCH_FOLDERS>
Additional paths to watch for changes
-o, --open
Open Xcode instead of trying to run on a connected device
--force-ip-prompt
Force prompting for an IP to use to connect to the dev server on mobile
--host [<HOST>]
Use the public network address for the development server. If an actual address it provided, it is used instead of prompting to pick one.
This option is particularly useful along the `--open` flag when you intend on running on a physical device.
This replaces the devUrl configuration value to match the public network address host, it is your responsibility to set up your development server to listen on this address by using 0.0.0.0 as host for instance.
When this is set or when running on an iOS device the CLI sets the `TAURI_DEV_HOST` environment variable so you can check this on your framework's configuration to expose the development server on the public network address.
[default: <none>]
--no-dev-server
Disable the built-in dev server for static files
--port <PORT>
Specify port for the built-in dev server for static files. Defaults to 1430
[env: TAURI_CLI_PORT=]
--root-certificate-path <ROOT_CERTIFICATE_PATH>
Path to the certificate file used by your dev server. Required for mobile dev when using HTTPS
[env: TAURI_DEV_ROOT_CERTIFICATE_PATH=]
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
ios build
All iOS commands are only available on macOS hosts.
-
npm
npm run tauri ios build -
yarn
yarn tauri ios build -
pnpm
pnpm tauri ios build -
deno
deno task tauri ios build -
bun
bun tauri ios build -
cargo
cargo tauri ios build
Build your app in release mode for iOS and generate IPAs. It makes use of the `build.frontendDist` property from your `tauri.conf.json` file. It also runs your `build.beforeBuildCommand` which usually builds your frontend into `build.frontendDist`.
Usage: tauri ios build [OPTIONS] [-- <ARGS>...]
Arguments:
[ARGS]...
Command line arguments passed to the runner. Use `--` to explicitly mark the start of the arguments. e.g. `tauri ios build -- [runnerArgs]`
Options:
-d, --debug
Builds with the debug flag
-v, --verbose...
Enables verbose logging
-t, --target [<TARGETS>...]
Which targets to build
[default: aarch64]
[possible values: aarch64, aarch64-sim, x86_64]
-f, --features [<FEATURES>...]
List of cargo features to activate
-c, --config <CONFIG>
JSON strings or paths to JSON, JSON5 or TOML files to merge with the default configuration file
Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
Note that a platform-specific file is looked up and merged with the default file by default (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json) but you can use this for more specific use cases such as different build flavors.
--build-number <BUILD_NUMBER>
Build number to append to the app version
-o, --open
Open Xcode
--ci
Skip prompting for values
[env: CI=]
--export-method <EXPORT_METHOD>
Describes how Xcode should export the archive.
Use this to create a package ready for the App Store (app-store-connect option) or TestFlight (release-testing option).
[possible values: app-store-connect, release-testing, debugging]
--ignore-version-mismatches
Do not error out if a version mismatch is detected on a Tauri package.
Only use this when you are sure the mismatch is incorrectly detected as version mismatched Tauri packages can lead to unknown behavior.
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
ios run
All iOS commands are only available on macOS hosts.
-
npm
npm run tauri ios run -
yarn
yarn tauri ios run -
pnpm
pnpm tauri ios run -
deno
deno task tauri ios run -
bun
bun tauri ios run -
cargo
cargo tauri ios run
Run your app in production mode on iOS. It makes use of the `build.frontendDist` property from your `tauri.conf.json` file. It also runs your `build.beforeBuildCommand` which usually builds your frontend into `build.frontendDist`.
Usage: tauri ios run [OPTIONS] [DEVICE] [-- <ARGS>...]
Arguments:
[DEVICE]
Runs on the given device name
[ARGS]...
Command line arguments passed to the runner. Use `--` to explicitly mark the start of the arguments. e.g. `tauri android build -- [runnerArgs]`
Options:
-r, --release
Run the app in release mode
-v, --verbose...
Enables verbose logging
-f, --features [<FEATURES>...]
List of cargo features to activate
-c, --config <CONFIG>
JSON strings or paths to JSON, JSON5 or TOML files to merge with the default configuration file
Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
Note that a platform-specific file is looked up and merged with the default file by default (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json) but you can use this for more specific use cases such as different build flavors.
--no-watch
Disable the file watcher
--additional-watch-folders <ADDITIONAL_WATCH_FOLDERS>
Additional paths to watch for changes
-o, --open
Open Xcode
--ignore-version-mismatches
Do not error out if a version mismatch is detected on a Tauri package.
Only use this when you are sure the mismatch is incorrectly detected as version mismatched Tauri packages can lead to unknown behavior.
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
migrate
-
npm
npm run tauri migrate -
yarn
yarn tauri migrate -
pnpm
pnpm tauri migrate -
deno
deno task tauri migrate -
bun
bun tauri migrate -
cargo
cargo tauri migrate
Migrate from v1 to v2
Usage: tauri migrate [OPTIONS]
Options:
-v, --verbose... Enables verbose logging
-h, --help Print help
-V, --version Print version
info
-
npm
npm run tauri info -
yarn
yarn tauri info -
pnpm
pnpm tauri info -
deno
deno task tauri info -
bun
bun tauri info -
cargo
cargo tauri info
Show a concise list of information about the environment, Rust, Node.js and their versions as well as a few relevant project configurations
Usage: tauri info [OPTIONS]
Options:
--interactive Interactive mode to apply automatic fixes
-v, --verbose... Enables verbose logging
-h, --help Print help
-V, --version Print version
add
-
npm
npm run tauri add -
yarn
yarn tauri add -
pnpm
pnpm tauri add -
deno
deno task tauri add -
bun
bun tauri add -
cargo
cargo tauri add
Add a tauri plugin to the project
Usage: tauri add [OPTIONS] <PLUGIN>
Arguments:
<PLUGIN> The plugin to add
Options:
-t, --tag <TAG> Git tag to use
-v, --verbose... Enables verbose logging
-r, --rev <REV> Git rev to use
-b, --branch <BRANCH> Git branch to use
--no-fmt Don't format code with rustfmt
-h, --help Print help
-V, --version Print version
remove
-
npm
npm run tauri remove -
yarn
yarn tauri remove -
pnpm
pnpm tauri remove -
deno
deno task tauri remove -
bun
bun tauri remove -
cargo
cargo tauri remove
Remove a tauri plugin from the project
Usage: tauri remove [OPTIONS] <PLUGIN>
Arguments:
<PLUGIN> The plugin to remove
Options:
-v, --verbose... Enables verbose logging
-h, --help Print help
-V, --version Print version
plugin
-
npm
npm run tauri plugin -
yarn
yarn tauri plugin -
pnpm
pnpm tauri plugin -
deno
deno task tauri plugin -
bun
bun tauri plugin -
cargo
cargo tauri plugin
Manage or create Tauri plugins
Usage: tauri plugin [OPTIONS] <COMMAND>
Commands:
new Initializes a new Tauri plugin project
init Initialize a Tauri plugin project on an existing directory
android Manage the Android project for a Tauri plugin
ios Manage the iOS project for a Tauri plugin
help Print this message or the help of the given subcommand(s)
Options:
-v, --verbose... Enables verbose logging
-h, --help Print help
-V, --version Print version
plugin new
-
npm
npm run tauri plugin new -
yarn
yarn tauri plugin new -
pnpm
pnpm tauri plugin new -
deno
deno task tauri plugin new -
bun
bun tauri plugin new -
cargo
cargo tauri plugin new
Initializes a new Tauri plugin project
Usage: tauri plugin new [OPTIONS] <PLUGIN_NAME>
Arguments:
<PLUGIN_NAME>
Name of your Tauri plugin
Options:
--no-api
Initializes a Tauri plugin without the TypeScript API
-v, --verbose...
Enables verbose logging
--no-example
Initialize without an example project
-d, --directory <DIRECTORY>
Set target directory for init
-a, --author <AUTHOR>
Author name
--android
Whether to initialize an Android project for the plugin
--ios
Whether to initialize an iOS project for the plugin
--mobile
Whether to initialize Android and iOS projects for the plugin
--ios-framework <IOS_FRAMEWORK>
Type of framework to use for the iOS project
[default: spm]
Possible values:
- spm: Swift Package Manager project
- xcode: Xcode project
--github-workflows
Generate github workflows
-t, --tauri-path <TAURI_PATH>
Path of the Tauri project to use (relative to the cwd)
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
plugin init
-
npm
npm run tauri plugin init -
yarn
yarn tauri plugin init -
pnpm
pnpm tauri plugin init -
deno
deno task tauri plugin init -
bun
bun tauri plugin init -
cargo
cargo tauri plugin init
Initialize a Tauri plugin project on an existing directory
Usage: tauri plugin init [OPTIONS] [PLUGIN_NAME]
Arguments:
[PLUGIN_NAME]
Name of your Tauri plugin. If not specified, it will be inferred from the current directory
Options:
--no-api
Initializes a Tauri plugin without the TypeScript API
-v, --verbose...
Enables verbose logging
--no-example
Initialize without an example project
-d, --directory <DIRECTORY>
Set target directory for init
[default: /opt/build/repo/packages/cli-generator]
-a, --author <AUTHOR>
Author name
--android
Whether to initialize an Android project for the plugin
--ios
Whether to initialize an iOS project for the plugin
--mobile
Whether to initialize Android and iOS projects for the plugin
--ios-framework <IOS_FRAMEWORK>
Type of framework to use for the iOS project
[default: spm]
Possible values:
- spm: Swift Package Manager project
- xcode: Xcode project
--github-workflows
Generate github workflows
-t, --tauri-path <TAURI_PATH>
Path of the Tauri project to use (relative to the cwd)
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
plugin android
-
npm
npm run tauri plugin android -
yarn
yarn tauri plugin android -
pnpm
pnpm tauri plugin android -
deno
deno task tauri plugin android -
bun
bun tauri plugin android -
cargo
cargo tauri plugin android
Manage the Android project for a Tauri plugin
Usage: tauri plugin android [OPTIONS] <COMMAND>
Commands:
init Initializes the Android project for an existing Tauri plugin
help Print this message or the help of the given subcommand(s)
Options:
-v, --verbose... Enables verbose logging
-h, --help Print help
-V, --version Print version
plugin android init
-
npm
npm run tauri plugin android init -
yarn
yarn tauri plugin android init -
pnpm
pnpm tauri plugin android init -
deno
deno task tauri plugin android init -
bun
bun tauri plugin android init -
cargo
cargo tauri plugin android init
Initializes the Android project for an existing Tauri plugin
Usage: tauri plugin android init [OPTIONS] [PLUGIN_NAME]
Arguments:
[PLUGIN_NAME] Name of your Tauri plugin. Must match the current plugin's name. If not specified, it will be inferred from the current directory
Options:
-o, --out-dir <OUT_DIR> The output directory [default: /opt/build/repo/packages/cli-generator]
-v, --verbose... Enables verbose logging
-h, --help Print help
-V, --version Print version
plugin ios
-
npm
npm run tauri plugin ios -
yarn
yarn tauri plugin ios -
pnpm
pnpm tauri plugin ios -
deno
deno task tauri plugin ios -
bun
bun tauri plugin ios -
cargo
cargo tauri plugin ios
Manage the iOS project for a Tauri plugin
Usage: tauri plugin ios [OPTIONS] <COMMAND>
Commands:
init Initializes the iOS project for an existing Tauri plugin
help Print this message or the help of the given subcommand(s)
Options:
-v, --verbose... Enables verbose logging
-h, --help Print help
-V, --version Print version
plugin ios init
-
npm
npm run tauri plugin ios init -
yarn
yarn tauri plugin ios init -
pnpm
pnpm tauri plugin ios init -
deno
deno task tauri plugin ios init -
bun
bun tauri plugin ios init -
cargo
cargo tauri plugin ios init
Initializes the iOS project for an existing Tauri plugin
Usage: tauri plugin ios init [OPTIONS] [PLUGIN_NAME]
Arguments:
[PLUGIN_NAME]
Name of your Tauri plugin. Must match the current plugin's name. If not specified, it will be inferred from the current directory
Options:
-o, --out-dir <OUT_DIR>
The output directory
[default: /opt/build/repo/packages/cli-generator]
-v, --verbose...
Enables verbose logging
--ios-framework <IOS_FRAMEWORK>
Type of framework to use for the iOS project
[default: spm]
Possible values:
- spm: Swift Package Manager project
- xcode: Xcode project
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
icon
-
npm
npm run tauri icon -
yarn
yarn tauri icon -
pnpm
pnpm tauri icon -
deno
deno task tauri icon -
bun
bun tauri icon -
cargo
cargo tauri icon
Generate various icons for all major platforms
Usage: tauri icon [OPTIONS] [INPUT]
Arguments:
[INPUT]
Path to the source icon (squared PNG or SVG file with transparency) or a manifest file.
The manifest file is a JSON file with the following structure: { "default": "app-icon.png", "bg_color": "#fff", "android_bg": "app-icon-bg.png", "android_fg": "app-icon-fg.png", "android_fg_scale": 85, "android_monochrome": "app-icon-monochrome.png" }
All file paths defined in the manifest JSON are relative to the manifest file path.
Only the `default` manifest property is required.
The `bg_color` manifest value overwrites the `--ios-color` option if set.
[default: ./app-icon.png]
Options:
-o, --output <OUTPUT>
Output directory. Default: 'icons' directory next to the tauri.conf.json file
-v, --verbose...
Enables verbose logging
-p, --png <PNG>
Custom PNG icon sizes to generate. When set, the default icons are not generated
--ios-color <IOS_COLOR>
The background color of the iOS icon - string as defined in the W3C's CSS Color Module Level 4 <https://www.w3.org/TR/css-color-4/>
[default: #fff]
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
signer
-
npm
npm run tauri signer -
yarn
yarn tauri signer -
pnpm
pnpm tauri signer -
deno
deno task tauri signer -
bun
bun tauri signer -
cargo
cargo tauri signer
Generate signing keys for Tauri updater or sign files
Usage: tauri signer [OPTIONS] <COMMAND>
Commands:
sign Sign a file
generate Generate a new signing key to sign files
help Print this message or the help of the given subcommand(s)
Options:
-v, --verbose... Enables verbose logging
-h, --help Print help
-V, --version Print version
signer sign
-
npm
npm run tauri signer sign -
yarn
yarn tauri signer sign -
pnpm
pnpm tauri signer sign -
deno
deno task tauri signer sign -
bun
bun tauri signer sign -
cargo
cargo tauri signer sign
Sign a file
Usage: tauri signer sign [OPTIONS] <FILE>
Arguments:
<FILE> Sign the specified file
Options:
-k, --private-key <PRIVATE_KEY>
Load the private key from a string [env: TAURI_SIGNING_PRIVATE_KEY=]
-v, --verbose...
Enables verbose logging
-f, --private-key-path <PRIVATE_KEY_PATH>
Load the private key from a file [env: TAURI_SIGNING_PRIVATE_KEY_PATH=]
-p, --password <PASSWORD>
Set private key password when signing [env: TAURI_SIGNING_PRIVATE_KEY_PASSWORD=]
-h, --help
Print help
-V, --version
Print version
signer generate
-
npm
npm run tauri signer generate -
yarn
yarn tauri signer generate -
pnpm
pnpm tauri signer generate -
deno
deno task tauri signer generate -
bun
bun tauri signer generate -
cargo
cargo tauri signer generate
Generate a new signing key to sign files
Usage: tauri signer generate [OPTIONS]
Options:
-p, --password <PASSWORD> Set private key password when signing
-v, --verbose... Enables verbose logging
-w, --write-keys <WRITE_KEYS> Write private key to a file
-f, --force Overwrite private key even if it exists on the specified path
--ci Skip prompting for values [env: CI=true]
-h, --help Print help
-V, --version Print version
completions
-
npm
npm run tauri completions -
yarn
yarn tauri completions -
pnpm
pnpm tauri completions -
deno
deno task tauri completions -
bun
bun tauri completions -
cargo
cargo tauri completions
Generate Tauri CLI shell completions for Bash, Zsh, PowerShell or Fish
Usage: tauri completions [OPTIONS] --shell <SHELL>
Options:
-s, --shell <SHELL> Shell to generate a completion script for. [possible values: bash, elvish, fish, powershell, zsh]
-v, --verbose... Enables verbose logging
-o, --output <OUTPUT> Output file for the shell completions. By default the completions are printed to stdout
-h, --help Print help
-V, --version Print version
permission
-
npm
npm run tauri permission -
yarn
yarn tauri permission -
pnpm
pnpm tauri permission -
deno
deno task tauri permission -
bun
bun tauri permission -
cargo
cargo tauri permission
Manage or create permissions for your app or plugin
Usage: tauri permission [OPTIONS] <COMMAND>
Commands:
new Create a new permission file
add Add a permission to capabilities
rm Remove a permission file, and its reference from any capability
ls List permissions available to your application
help Print this message or the help of the given subcommand(s)
Options:
-v, --verbose... Enables verbose logging
-h, --help Print help
-V, --version Print version
permission new
-
npm
npm run tauri permission new -
yarn
yarn tauri permission new -
pnpm
pnpm tauri permission new -
deno
deno task tauri permission new -
bun
bun tauri permission new -
cargo
cargo tauri permission new
Create a new permission file
Usage: tauri permission new [OPTIONS] [IDENTIFIER]
Arguments:
[IDENTIFIER] Permission identifier
Options:
--description <DESCRIPTION> Permission description
-v, --verbose... Enables verbose logging
-a, --allow <ALLOW> List of commands to allow
-d, --deny <DENY> List of commands to deny
--format <FORMAT> Output file format [default: json] [possible values: json, toml]
-o, --out <OUT> The output file
-h, --help Print help
-V, --version Print version
permission add
-
npm
npm run tauri permission add -
yarn
yarn tauri permission add -
pnpm
pnpm tauri permission add -
deno
deno task tauri permission add -
bun
bun tauri permission add -
cargo
cargo tauri permission add
Add a permission to capabilities
Usage: tauri permission add [OPTIONS] <IDENTIFIER> [CAPABILITY]
Arguments:
<IDENTIFIER> Permission to add
[CAPABILITY] Capability to add the permission to
Options:
-v, --verbose... Enables verbose logging
-h, --help Print help
-V, --version Print version
permission rm
-
npm
npm run tauri permission rm -
yarn
yarn tauri permission rm -
pnpm
pnpm tauri permission rm -
deno
deno task tauri permission rm -
bun
bun tauri permission rm -
cargo
cargo tauri permission rm
Remove a permission file, and its reference from any capability
Usage: tauri permission rm [OPTIONS] <IDENTIFIER>
Arguments:
<IDENTIFIER>
Permission to remove.
To remove all permissions for a given plugin, provide `<plugin-name>:*`
Options:
-v, --verbose...
Enables verbose logging
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
permission ls
-
npm
npm run tauri permission ls -
yarn
yarn tauri permission ls -
pnpm
pnpm tauri permission ls -
deno
deno task tauri permission ls -
bun
bun tauri permission ls -
cargo
cargo tauri permission ls
List permissions available to your application
Usage: tauri permission ls [OPTIONS] [PLUGIN]
Arguments:
[PLUGIN] Name of the plugin to list permissions
Options:
-f, --filter <FILTER> Permission identifier filter
-v, --verbose... Enables verbose logging
-h, --help Print help
-V, --version Print version
capability
-
npm
npm run tauri capability -
yarn
yarn tauri capability -
pnpm
pnpm tauri capability -
deno
deno task tauri capability -
bun
bun tauri capability -
cargo
cargo tauri capability
Manage or create capabilities for your app
Usage: tauri capability [OPTIONS] <COMMAND>
Commands:
new Create a new permission file
help Print this message or the help of the given subcommand(s)
Options:
-v, --verbose... Enables verbose logging
-h, --help Print help
-V, --version Print version
capability new
-
npm
npm run tauri capability new -
yarn
yarn tauri capability new -
pnpm
pnpm tauri capability new -
deno
deno task tauri capability new -
bun
bun tauri capability new -
cargo
cargo tauri capability new
Create a new permission file
Usage: tauri capability new [OPTIONS] [IDENTIFIER]
Arguments:
[IDENTIFIER] Capability identifier
Options:
--description <DESCRIPTION> Capability description
-v, --verbose... Enables verbose logging
--windows <WINDOWS> Capability windows
--permission <PERMISSION> Capability permissions
--format <FORMAT> Output file format [default: json] [possible values: json, toml]
-o, --out <OUT> The output file
-h, --help Print help
-V, --version Print version
inspect
-
npm
npm run tauri inspect -
yarn
yarn tauri inspect -
pnpm
pnpm tauri inspect -
deno
deno task tauri inspect -
bun
bun tauri inspect -
cargo
cargo tauri inspect
Inspect values used by Tauri
Usage: tauri inspect [OPTIONS] <COMMAND>
Commands:
wix-upgrade-code Print the default Upgrade Code used by MSI installer derived from productName
help Print this message or the help of the given subcommand(s)
Options:
-v, --verbose... Enables verbose logging
-h, --help Print help
-V, --version Print version
inspect wix-upgrade-code
-
npm
npm run tauri inspect wix-upgrade-code -
yarn
yarn tauri inspect wix-upgrade-code -
pnpm
pnpm tauri inspect wix-upgrade-code -
deno
deno task tauri inspect wix-upgrade-code -
bun
bun tauri inspect wix-upgrade-code -
cargo
cargo tauri inspect wix-upgrade-code
Print the default Upgrade Code used by MSI installer derived from productName
Usage: tauri inspect wix-upgrade-code [OPTIONS]
Options:
-v, --verbose... Enables verbose logging
-h, --help Print help
-V, --version Print version
Configuration
The Tauri configuration object. It is read from a file where you can define your frontend assets, configure the bundler and define a tray icon.
The configuration file is generated by the tauri init command that lives in your Tauri application source directory (src-tauri).
Once generated, you may modify it at will to customize your Tauri application.
File Formats
By default, the configuration is defined as a JSON file named tauri.conf.json.
Tauri also supports JSON5 and TOML files via the config-json5 and config-toml Cargo features, respectively. The JSON5 file name must be either tauri.conf.json or tauri.conf.json5. The TOML file name is Tauri.toml.
Platform-Specific Configuration
In addition to the default configuration file, Tauri can read a platform-specific configuration from tauri.linux.conf.json, tauri.windows.conf.json, tauri.macos.conf.json, tauri.android.conf.json and tauri.ios.conf.json (or Tauri.linux.toml, Tauri.windows.toml, Tauri.macos.toml, Tauri.android.toml and Tauri.ios.toml if the Tauri.toml format is used), which gets merged with the main configuration object.
Configuration Structure
The configuration is composed of the following objects:
app: The Tauri configurationbuild: The build configurationbundle: The bundle configurationsplugins: The plugins configuration
Example tauri.config.json file:
{
"productName": "tauri-app",
"version": "0.1.0",
"build": {
"beforeBuildCommand": "",
"beforeDevCommand": "",
"devUrl": "http://localhost:3000",
"frontendDist": "../dist"
},
"app": {
"security": {
"csp": null
},
"windows": [
{
"fullscreen": false,
"height": 600,
"resizable": true,
"title": "Tauri App",
"width": 800
}
]
},
"bundle": {},
"plugins": {}
}
Object Properties:
- app
- build
- bundle
- identifier (required)
- mainBinaryName
- plugins
- productName
- version
app
The App configuration.
Default
{
"enableGTKAppId": false,
"macOSPrivateApi": false,
"security": {
"assetProtocol": {
"enable": false,
"scope": []
},
"capabilities": [],
"dangerousDisableAssetCspModification": false,
"freezePrototype": false,
"pattern": {
"use": "brownfield"
}
},
"windows": [],
"withGlobalTauri": false
}
build
The build configuration.
Default
{
"additionalWatchFolders": [],
"removeUnusedCommands": false,
"windows": {
"staticVCRuntime": true
}
}
bundle
The bundler configuration.
Default
{
"active": false,
"android": {
"autoIncrementVersionCode": false,
"minSdkVersion": 24
},
"createUpdaterArtifacts": false,
"iOS": {
"minimumSystemVersion": "14.0"
},
"icon": [],
"linux": {
"appimage": {
"bundleMediaFramework": false,
"files": {}
},
"deb": {
"files": {}
},
"rpm": {
"epoch": 0,
"files": {},
"release": "1"
}
},
"macOS": {
"dmg": {
"appPosition": {
"x": 180,
"y": 170
},
"applicationFolderPosition": {
"x": 480,
"y": 170
},
"windowSize": {
"height": 400,
"width": 660
}
},
"files": {},
"hardenedRuntime": true,
"minimumSystemVersion": "10.13"
},
"targets": "all",
"useLocalToolsDir": false,
"windows": {
"allowDowngrades": true,
"bundleVCRuntime": false,
"certificateThumbprint": null,
"digestAlgorithm": null,
"minimumWebview2Version": null,
"nsis": null,
"signCommand": null,
"timestampUrl": null,
"tsp": false,
"webviewInstallMode": {
"silent": true,
"type": "downloadBootstrapper"
},
"wix": null
}
}
identifier
string
The application identifier in reverse domain name notation (e.g. com.tauri.example). This string must be unique across applications since it is used in system configurations like the bundle ID and path to the webview data directory. This string must contain only alphanumeric characters (A-Z, a-z, and 0-9), hyphens (-), and periods (.).
mainBinaryName
string | null
Overrides app’s main binary filename.
By default, Tauri uses the output binary from cargo, by setting this, we will rename that binary in tauri-cli’s tauri build command, and target tauri bundle to it
If possible, change the package name or set the name field instead, and if that’s not enough and you’re using nightly, consider using the different-binary-name feature instead
Note: this config should not include the binary extension (e.g. .exe), we’ll add that for you
plugins
The plugins config.
Default: {}
productName
string | null pattern of ^[^/\:*?"<>|]+$
App name.
version
string | null
App version. It is a semver version number or a path to a package.json file containing the version field.
If removed the version number from Cargo.toml is used. It’s recommended to manage the app versioning in the Tauri config.
Platform-specific
- macOS: Translates to the bundle’s CFBundleShortVersionString property and is used as the default CFBundleVersion. You can set an specific bundle version using
bundle > macOS > bundleVersion. - iOS: Translates to the bundle’s CFBundleShortVersionString property and is used as the default CFBundleVersion. You can set an specific bundle version using
bundle > iOS > bundleVersion. Thetauri ios buildCLI command has a--build-number <number>option that lets you append a build number to the app version. - Android: By default version 1.0 is used. You can set a version code using
bundle > android > versionCode.
By default version 1.0 is used on Android.
Definitions
AndroidConfig
General configuration for the Android target.
Object Properties:
- autoIncrementVersionCode
- debugApplicationIdSuffix
- minSdkVersion
- versionCode
autoIncrementVersionCode
boolean
Whether to automatically increment the versionCode on each build.
- If
true, the generator will try to read the lastversionCodefromtauri.propertiesand increment it by 1 for every build. - If
falseor not set, it falls back toversion_codeor semver-derived logic.
Note that to use this feature, you should remove /tauri.properties from src-tauri/gen/android/app/.gitignore so the current versionCode is committed to the repository.
debugApplicationIdSuffix
string | null
Application ID suffix to append for debug builds. This allows installing debug and release versions side-by-side on the same device. Example: “.debug” will make debug builds use “com.example.app.debug” as the application ID.
minSdkVersion
integer formatted as uint32
The minimum API level required for the application to run. The Android system will prevent the user from installing the application if the system’s API level is lower than the value specified.
Default: 24
versionCode
integer | null maximum of 2100000000, minimum of 1, formatted as uint32
The version code of the application. It is limited to 2,100,000,000 as per Google Play Store requirements.
By default we use your configured version and perform the following math: versionCode = version.major * 1000000 + version.minor * 1000 + version.patch
AndroidIntentAction
One of the following:
"send"ACTION_SEND. <https://developer.android.com/reference/android/content/Intent#ACTION_SEND>"sendMultiple"ACTION_SEND_MULTIPLE. <https://developer.android.com/reference/android/content/Intent#ACTION_SEND_MULTIPLE>"view"ACTION_VIEW. <https://developer.android.com/reference/android/content/Intent#ACTION_SEND>
Android intent action.
AppConfig
The App configuration object.
See more: <https://v2.tauri.app/reference/config/#appconfig>
Object Properties:
- enableGTKAppId
- macOSPrivateApi
- security
- trayIcon
- windows
- withGlobalTauri
enableGTKAppId
boolean
If set to true “identifier” will be set as GTK app ID (on systems that use GTK).
macOSPrivateApi
boolean
MacOS private API configuration. Enables the transparent background API and sets the fullScreenEnabled preference to true.
security
Security configuration.
Default
{
"assetProtocol": {
"enable": false,
"scope": []
},
"capabilities": [],
"dangerousDisableAssetCspModification": false,
"freezePrototype": false,
"pattern": {
"use": "brownfield"
}
}
trayIcon
TrayIconConfig | null
Configuration for app tray icon.
windows
The app windows configuration.
Example:
To create a window at app startup
{
"app": {
"windows": [
{ "width": 800, "height": 600 }
]
}
}
If not specified, the window’s label (its identifier) defaults to “main”, you can use this label to get the window through app.get_webview_window in Rust or WebviewWindow.getByLabel in JavaScript
When working with multiple windows, each window will need an unique label
{
"app": {
"windows": [
{ "label": "main", "width": 800, "height": 600 },
{ "label": "secondary", "width": 800, "height": 600 }
]
}
}
You can also set create to false and use this config through the Rust APIs
{
"app": {
"windows": [
{ "create": false, "width": 800, "height": 600 }
]
}
}
and use it like this
tauri::Builder::default()
.setup(|app| {
tauri::WebviewWindowBuilder::from_config(app.handle(), &app.config().app.windows[0])?.build()?;
Ok(())
});
Default: []
withGlobalTauri
boolean
Whether we should inject the Tauri API on window.__TAURI__ or not.
AppImageConfig
Configuration for AppImage bundles.
See more: <https://v2.tauri.app/reference/config/#appimageconfig>
Object Properties:
- bundleMediaFramework
- files
bundleMediaFramework
boolean
Include additional gstreamer dependencies needed for audio and video playback. This increases the bundle size by ~15-35MB depending on your build system.
files
The files to include in the Appimage Binary.
Allows additional properties: string
Default: {}
AssetProtocolConfig
Config for the asset custom protocol.
See more: <https://v2.tauri.app/reference/config/#assetprotocolconfig>
Object Properties:
- enable
- scope
enable
boolean
Enables the asset protocol.
scope
The access scope for the asset protocol.
Default: []
AssociationExt
string
An extension for a [FileAssociation].
A leading . is automatically stripped.
BackgroundThrottlingPolicy
One of the following:
"disabled"A policy where background throttling is disabled"suspend"A policy where a web view that’s not in a window fully suspends tasks. This is usually the default behavior in case no policy is set."throttle"A policy where a web view that’s not in a window limits processing, but does not fully suspend tasks.
Background throttling policy.
BeforeDevCommand
Any of the following:
stringRun the given script with the default options.- Run the given script with custom options. Object Properties: - cwd - script (required) - wait ##### cwd
string|nullThe current working directory. ##### scriptstringThe script to execute. ##### waitbooleanWhethertauri devshould wait for the command to finish or not. Defaults tofalse.
Describes the shell command to run before tauri dev.
BuildConfig
The Build configuration object.
See more: <https://v2.tauri.app/reference/config/#buildconfig>
Object Properties:
- additionalWatchFolders
- beforeBuildCommand
- beforeBundleCommand
- beforeDevCommand
- devUrl
- features
- frontendDist
- removeUnusedCommands
- runner
- windows
additionalWatchFolders
string[]
Additional paths to watch for changes when running tauri dev.
Default: []
beforeBuildCommand
HookCommand | null
A shell command to run before tauri build kicks in.
The TAURI_ENV_PLATFORM, TAURI_ENV_ARCH, TAURI_ENV_FAMILY, TAURI_ENV_PLATFORM_VERSION, TAURI_ENV_PLATFORM_TYPE and TAURI_ENV_DEBUG environment variables are set if you perform conditional compilation.
beforeBundleCommand
HookCommand | null
A shell command to run before the bundling phase in tauri build kicks in.
The TAURI_ENV_PLATFORM, TAURI_ENV_ARCH, TAURI_ENV_FAMILY, TAURI_ENV_PLATFORM_VERSION, TAURI_ENV_PLATFORM_TYPE and TAURI_ENV_DEBUG environment variables are set if you perform conditional compilation.
beforeDevCommand
BeforeDevCommand | null
A shell command to run before tauri dev kicks in.
The TAURI_ENV_PLATFORM, TAURI_ENV_ARCH, TAURI_ENV_FAMILY, TAURI_ENV_PLATFORM_VERSION, TAURI_ENV_PLATFORM_TYPE and TAURI_ENV_DEBUG environment variables are set if you perform conditional compilation.
devUrl
string | null formatted as uri
The URL to load in development.
This is usually an URL to a dev server, which serves your application assets with hot-reload and HMR. Most modern JavaScript bundlers like Vite provides a way to start a dev server by default.
If you don’t have a dev server or don’t want to use one, ignore this option and use frontendDist and point to a web assets directory, and Tauri CLI will run its built-in dev server and provide a simple hot-reload experience.
features
string[] | null
Features passed to cargo commands.
frontendDist
FrontendDist | null
The path to the application assets (usually the dist folder of your javascript bundler) or a URL that could be either a custom protocol registered in the tauri app (for example: myprotocol://) or a remote URL (for example: https://site.com/app).
When a path relative to the configuration file is provided, it is read recursively and all files are embedded in the application binary. Tauri then looks for an index.html and serves it as the default entry point for your application.
You can also provide a list of paths to be embedded, which allows granular control over what files are added to the binary. In this case, all files are added to the root and you must reference it that way in your HTML files.
When a URL is provided, the application won’t have bundled assets and the application will load that URL by default.
removeUnusedCommands
boolean
Try to remove unused commands registered from plugins base on the ACL list during tauri build, the way it works is that tauri-cli will read this and set the environment variables for the build script and macros, and they’ll try to get all the allowed commands and remove the rest
Note:
- This won’t be accounting for dynamically added ACLs when you use features from the
dynamic-acl(currently enabled by default) feature flag, so make sure to check it when using this - This feature requires tauri-plugin 2.1 and tauri 2.4
runner
RunnerConfig | null
The binary used to build and run the application.
windows
Windows-specific build configuration.
Default
{
"staticVCRuntime": true
}
BundleConfig
Configuration for tauri-bundler.
See more: <https://v2.tauri.app/reference/config/#bundleconfig>
Object Properties:
- active
- android
- category
- copyright
- createUpdaterArtifacts
- externalBin
- fileAssociations
- homepage
- icon
- iOS
- license
- licenseFile
- linux
- longDescription
- macOS
- publisher
- resources
- shortDescription
- targets
- useLocalToolsDir
- windows
active
boolean
Whether Tauri should bundle your application or just output the executable.
android
Android configuration.
Default
{
"autoIncrementVersionCode": false,
"minSdkVersion": 24
}
category
string | null
The application kind.
Should be one of the following: Business, DeveloperTool, Education, Entertainment, Finance, Game, ActionGame, AdventureGame, ArcadeGame, BoardGame, CardGame, CasinoGame, DiceGame, EducationalGame, FamilyGame, KidsGame, MusicGame, PuzzleGame, RacingGame, RolePlayingGame, SimulationGame, SportsGame, StrategyGame, TriviaGame, WordGame, GraphicsAndDesign, HealthcareAndFitness, Lifestyle, Medical, Music, News, Photography, Productivity, Reference, SocialNetworking, Sports, Travel, Utility, Video, Weather.
copyright
string | null
A copyright string associated with your application.
createUpdaterArtifacts
Produce updaters and their signatures or not
externalBin
string[] | null
A list of—either absolute or relative—paths to binaries to embed with your application.
Note that Tauri will look for system-specific binaries following the pattern “binary-name{-target-triple}{.system-extension}”.
E.g. for the external binary “my-binary”, Tauri looks for:
- “my-binary-x86_64-pc-windows-msvc.exe” for Windows
- “my-binary-x86_64-apple-darwin” for macOS
- “my-binary-x86_64-unknown-linux-gnu” for Linux
so don’t forget to provide binaries for all targeted platforms.
fileAssociations
FileAssociation[] | null
File types to associate with the application.
homepage
string | null
A url to the home page of your application. If unset, will fallback to homepage defined in Cargo.toml.
Supported bundle targets: deb, rpm, nsis and msi.
icon
string[]
The app’s icons
Default: []
iOS
iOS configuration.
Default
{
"minimumSystemVersion": "14.0"
}
license
string | null
The package’s license identifier to be included in the appropriate bundles. If not set, defaults to the license from the Cargo.toml file.
licenseFile
string | null
The path to the license file to be included in the appropriate bundles.
linux
Configuration for the Linux bundles.
Default
{
"appimage": {
"bundleMediaFramework": false,
"files": {}
},
"deb": {
"files": {}
},
"rpm": {
"epoch": 0,
"files": {},
"release": "1"
}
}
longDescription
string | null
A longer, multi-line description of the application.
macOS
Configuration for the macOS bundles.
Default
{
"dmg": {
"appPosition": {
"x": 180,
"y": 170
},
"applicationFolderPosition": {
"x": 480,
"y": 170
},
"windowSize": {
"height": 400,
"width": 660
}
},
"files": {},
"hardenedRuntime": true,
"minimumSystemVersion": "10.13"
}
publisher
string | null
The application’s publisher. Defaults to the second element in the identifier string.
Currently maps to the Manufacturer property of the Windows Installer and the Maintainer field of debian packages if the Cargo.toml does not have the authors field.
resources
BundleResources | null
App resources to bundle. Each resource is a path to a file or directory. Glob patterns are supported.
Examples
To include a list of files:
{
"bundle": {
"resources": [
"./path/to/some-file.txt",
"/absolute/path/to/textfile.txt",
"../relative/path/to/jsonfile.json",
"some-folder/",
"resources/**/*.md"
]
}
}
The bundled files will be in $RESOURCES/ with the original directory structure preserved, for example: ./path/to/some-file.txt -> $RESOURCE/path/to/some-file.txt
To fine control where the files will get copied to, use a map instead
{
"bundle": {
"resources": {
"/absolute/path/to/textfile.txt": "resources/textfile.txt",
"relative/path/to/jsonfile.json": "resources/jsonfile.json",
"resources/": "",
"docs/**/*md": "website-docs/"
}
}
}
Note that when using glob pattern in this case, the original directory structure is not preserved, everything gets copied to the target directory directly
See more: <https://v2.tauri.app/develop/resources/>
shortDescription
string | null
A short description of your application.
targets
The bundle targets, currently supports [“deb”, “rpm”, “appimage”, “nsis”, “msi”, “app”, “dmg”] or “all”.
Default: "all"
useLocalToolsDir
boolean
Whether to use the project’s target directory, for caching build tools (e.g., Wix and NSIS) when building this application. Defaults to false.
If true, tools will be cached in target/.tauri/. If false, tools will be cached in the current user’s platform-specific cache directory.
An example where it can be appropriate to set this to true is when building this application as a Windows System user (e.g., AWS EC2 workloads), because the Window system’s app data directory is restricted.
windows
Configuration for the Windows bundles.
Default
{
"allowDowngrades": true,
"bundleVCRuntime": false,
"certificateThumbprint": null,
"digestAlgorithm": null,
"minimumWebview2Version": null,
"nsis": null,
"signCommand": null,
"timestampUrl": null,
"tsp": false,
"webviewInstallMode": {
"silent": true,
"type": "downloadBootstrapper"
},
"wix": null
}
BundleResources
Any of the following:
string[] A list of paths to include.- A map of source to target paths. Allows additional properties:
string
Definition for bundle resources. Can be either a list of paths to include or a map of source to target paths.
BundleTarget
Any of the following:
"all"Bundle all targets.BundleType[] A list of bundle targets.BundleTypeA single bundle target.
Targets to bundle. Each value is case insensitive.
BundleType
One of the following:
"deb"The debian bundle (.deb)."rpm"The RPM bundle (.rpm)."appimage"The AppImage bundle (.appimage)."msi"The Microsoft Installer bundle (.msi)."nsis"The NSIS bundle (.exe)."app"The macOS application bundle (.app)."dmg"The Apple Disk Image bundle (.dmg).
A bundle referenced by tauri-bundler.
BundleTypeRole
One of the following:
"Editor"CFBundleTypeRole.Editor. Files can be read and edited."Viewer"CFBundleTypeRole.Viewer. Files can be read."Shell"CFBundleTypeRole.Shell"QLGenerator"CFBundleTypeRole.QLGenerator"None"CFBundleTypeRole.None
macOS-only. Corresponds to CFBundleTypeRole
Capability
A grouping and boundary mechanism developers can use to isolate access to the IPC layer.
It controls application windows’ and webviews’ fine grained access to the Tauri core, application, or plugin commands. If a webview or its window is not matching any capability then it has no access to the IPC layer at all.
This can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. main-window) or glob patterns like * or admin-*. A Window can have none, one, or multiple associated capabilities.
Example
{
"identifier": "main-user-files-write",
"description": "This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programmatic access to files selected by the user.",
"windows": [
"main"
],
"permissions": [
"core:default",
"dialog:open",
{
"identifier": "fs:allow-write-text-file",
"allow": [{ "path": "$HOME/test.txt" }]
},
],
"platforms": ["macOS","windows"]
}
Object Properties:
- description
- identifier (required)
- local
- permissions (required)
- platforms
- remote
- webviews
- windows
description
string
Description of what the capability is intended to allow on associated windows.
It should contain a description of what the grouped permissions should allow.
Example
This capability allows the main window access to filesystem write related commands and dialog commands to enable programmatic access to files selected by the user.
identifier
string
Identifier of the capability.
Example
main-user-files-write
local
boolean
Whether this capability is enabled for local app URLs or not. Defaults to true.
Default: true
permissions
PermissionEntry[] each item must be unique
List of permissions attached to this capability.
Must include the plugin name as prefix in the form of ${plugin-name}:${permission-name}. For commands directly implemented in the application itself only ${permission-name} is required.
Example
[
"core:default",
"shell:allow-open",
"dialog:open",
{
"identifier": "fs:allow-write-text-file",
"allow": [{ "path": "$HOME/test.txt" }]
}
]
platforms
Target[] | null
Limit which target platforms this capability applies to.
By default all platforms are targeted.
Example
["macOS","windows"]
remote
CapabilityRemote | null
Configure remote URLs that can use the capability permissions.
This setting is optional and defaults to not being set, as our default use case is that the content is served from our local application.
Caution
Make sure you understand the security implications of providing remote sources with local system access.
Example
{
"urls": ["https://*.mydomain.dev"]
}
webviews
string[]
List of webviews that are affected by this capability. Can be a glob pattern.
The capability will be enabled on all the webviews whose label matches any of the patterns in this list, regardless of whether the webview’s window label matches a pattern in [Self::windows].
Example
["sub-webview-one", "sub-webview-two"]
windows
string[]
List of windows that are affected by this capability. Can be a glob pattern.
If a window label matches any of the patterns in this list, the capability will be enabled on all the webviews of that window, regardless of the value of [Self::webviews].
On multiwebview windows, prefer specifying [Self::webviews] and omitting [Self::windows] for a fine grained access control.
Example
["main"]
CapabilityEntry
Any of the following:
CapabilityAn inlined capability.stringReference to a capability identifier.
A capability entry which can be either an inlined capability or a reference to a capability defined on its own file.
CapabilityRemote
Configuration for remote URLs that are associated with the capability.
Object Properties:
- urls (required)
urls
string[]
Remote domains this capability refers to using the URLPattern standard.
Examples
- “https://*.mydomain.dev”: allows subdomains of mydomain.dev
- “https://mydomain.dev/api/*”: allows any subpath of mydomain.dev/api
Color
Any of the following:
stringpattern of^#?([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$Color hex string, for example: #fff, #ffffff, or #ffffffff.integerformatted asuint8|integerformatted asuint8|integerformatted asuint8[] maximum of3items, minimum of3items Array of RGB colors. Each value has minimum of 0 and maximum of 255.integerformatted asuint8|integerformatted asuint8|integerformatted asuint8|integerformatted asuint8[] maximum of4items, minimum of4items Array of RGBA colors. Each value has minimum of 0 and maximum of 255.- Object of red, green, blue, alpha color values. Each value has minimum of 0 and maximum of 255. Object Properties: - alpha - blue (required) - green (required) - red (required) ##### alpha
integerformatted asuint8Default:255##### blueintegerformatted asuint8##### greenintegerformatted asuint8##### redintegerformatted asuint8
Csp
Any of the following:
stringThe entire CSP policy in a single text string.- An object mapping a directive with its sources values as a list of strings. Allows additional properties:
CspDirectiveSources
A Content-Security-Policy definition. See <https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP>.
CspDirectiveSources
Any of the following:
stringAn inline list of CSP sources. Same as [Self::List], but concatenated with a space separator.string[] A list of CSP sources. The collection will be concatenated with a space separator for the CSP string.
A Content-Security-Policy directive source list. See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/Sources#sources>.
CustomSignCommandConfig
Any of the following:
stringA string notation of the script to execute. “%1” will be replaced with the path to the binary to be signed. This is a simpler notation for the command. Tauri will split the string with' 'and use the first element as the command name and the rest as arguments. If you need to use whitespace in the command or arguments, use the object notation [Self::CommandWithOptions].- An object notation of the command. This is more complex notation for the command but this allows you to use whitespace in the command and arguments. Object Properties: - args (required) - cmd (required) ##### args
string[] The arguments to pass to the command. “%1” will be replaced with the path to the binary to be signed. ##### cmdstringThe command to run to sign the binary.
Custom Signing Command configuration.
DebConfig
Configuration for Debian (.deb) bundles.
See more: <https://v2.tauri.app/reference/config/#debconfig>
Object Properties:
- changelog
- conflicts
- depends
- desktopTemplate
- files
- postInstallScript
- postRemoveScript
- preInstallScript
- preRemoveScript
- priority
- provides
- recommends
- replaces
- section
changelog
string | null
Path of the uncompressed Changelog file, to be stored at /usr/share/doc/package-name/changelog.gz. See <https://www.debian.org/doc/debian-policy/ch-docs.html#changelog-files-and-release-notes>
conflicts
string[] | null
The list of package conflicts.
depends
string[] | null
The list of deb dependencies your application relies on.
desktopTemplate
string | null
Path to a custom desktop file Handlebars template.
Available variables: categories, comment (optional), exec, icon and name.
files
The files to include on the package.
Allows additional properties: string
Default: {}
postInstallScript
string | null
Path to script that will be executed after the package is unpacked. See <https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html>
postRemoveScript
string | null
Path to script that will be executed after the package is removed. See <https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html>
preInstallScript
string | null
Path to script that will be executed before the package is unpacked. See <https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html>
preRemoveScript
string | null
Path to script that will be executed before the package is removed. See <https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html>
priority
string | null
Change the priority of the Debian Package. By default, it is set to optional. Recognized Priorities as of now are : required, important, standard, optional, extra
provides
string[] | null
The list of dependencies the package provides.
recommends
string[] | null
The list of deb dependencies your application recommends.
replaces
string[] | null
The list of package replaces.
section
string | null
Define the section in Debian Control file. See : https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections
DisabledCspModificationKind
Any of the following:
booleanIftrue, disables all CSP modification.falseis the default value and it configures Tauri to control the CSP.string[] Disables the given list of CSP directives modifications.
The possible values for the dangerous_disable_asset_csp_modification config option.
DmgConfig
Configuration for Apple Disk Image (.dmg) bundles.
See more: <https://v2.tauri.app/reference/config/#dmgconfig>
Object Properties:
- applicationFolderPosition
- appPosition
- background
- windowPosition
- windowSize
applicationFolderPosition
Position of application folder on window.
Default
{
"x": 480,
"y": 170
}
appPosition
Position of app file on window.
Default
{
"x": 180,
"y": 170
}
background
string | null
Image to use as the background in dmg file. Accepted formats: png/jpg/gif.
windowPosition
Position | null
Position of volume window on screen.
windowSize
Size of volume window.
Default
{
"height": 400,
"width": 660
}
ExportedFileAssociation
The exported type definition. Maps to a UTExportedTypeDeclarations entry on macOS.
Object Properties:
- conformsTo
- identifier (required)
conformsTo
string[] | null
The types that this type conforms to. Maps to UTTypeConformsTo.
Examples are public.data, public.image, public.json and public.database.
identifier
string
The unique identifier for the exported type. Maps to UTTypeIdentifier.
FileAssociation
File association
Object Properties:
- androidIntentActionFilters
- contentTypes
- description
- exportedType
- ext (required)
- mimeType
- name
- rank
- role
androidIntentActionFilters
AndroidIntentAction[] | null
Intent action filters for this file association.
By default all filters are used.
contentTypes
string[] | null
Declare support to a file with the given content type. Maps to LSItemContentTypes on macOS.
This allows supporting any file format declared by another application that conforms to this type. Declaration of new types can be done with [Self::exported_type] and linking to certain content types are done via [ExportedFileAssociation::conforms_to].
description
string | null
The association description. Windows-only. It is displayed on the Type column on Windows Explorer.
exportedType
ExportedFileAssociation | null
The exported type definition. Maps to a UTExportedTypeDeclarations entry on macOS.
You should define this if the associated file is a custom file type defined by your application.
ext
File extensions to associate with this app. e.g. ‘png’
mimeType
string | null
The mime-type of the association, e.g. 'image/png' or 'text/plain'.
- Linux: written as
MimeType=in the.desktopfile. - macOS / iOS: added as
public.mime-typein theUTTypeTagSpecificationdictionary of theUTExportedTypeDeclarationsentry inInfo.plist. - Android: used as
android:mimeTypein the<data>element of an<intent-filter>inAndroidManifest.xml.
name
string | null
The name. Maps to CFBundleTypeName on macOS. Default to ext[0]
rank
The ranking of this app among apps that declare themselves as editors or viewers of the given file type. Maps to LSHandlerRank on macOS.
Default: "Default"
role
The app’s role with respect to the type. Maps to CFBundleTypeRole on macOS.
Default: "Editor"
FrontendDist
Any of the following:
stringformatted asuriAn external URL that should be used as the default application URL. No assets are embedded in the app in this case.stringPath to a directory containing the frontend dist assets.string[] An array of files to embed in the app.
Defines the URL or assets to embed in the application.
FsScope
Any of the following:
string[] A list of paths that are allowed by this scope.- A complete scope configuration. Object Properties: - allow - deny - requireLiteralLeadingDot ##### allow
string[] A list of paths that are allowed by this scope. Default:[]##### denystring[] A list of paths that are not allowed by this scope. This gets precedence over the [Self::Scope::allow] list. Default:[]##### requireLiteralLeadingDotboolean|nullWhether or not paths that contain components that start with a.will require that.appears literally in the pattern;*,?,**, or[...]will not match. This is useful because such files are conventionally considered hidden on Unix systems and it might be desirable to skip them when listing files. Defaults totrueon Unix systems andfalseon Windows
Protocol scope definition. It is a list of glob patterns that restrict the API access from the webview.
Each pattern can start with a variable that resolves to a system base directory. The variables are: $AUDIO, $CACHE, $CONFIG, $DATA, $LOCALDATA, $DESKTOP, $DOCUMENT, $DOWNLOAD, $EXE, $FONT, $HOME, $PICTURE, $PUBLIC, $RUNTIME, $TEMPLATE, $VIDEO, $RESOURCE, $TEMP, $APPCONFIG, $APPDATA, $APPLOCALDATA, $APPCACHE, $APPLOG.
HandlerRank
One of the following:
"Default"LSHandlerRank.Default. This app is an opener of files of this type; this value is also used if no rank is specified."Owner"LSHandlerRank.Owner. This app is the primary creator of files of this type."Alternate"LSHandlerRank.Alternate. This app is a secondary viewer of files of this type."None"LSHandlerRank.None. This app is never selected to open files of this type, but it accepts drops of files of this type.
Corresponds to LSHandlerRank
HeaderConfig
A struct, where the keys are some specific http header names.
If the values to those keys are defined, then they will be send as part of a response message. This does not include error messages and ipc messages
Example configuration
{
//..
app:{
//..
security: {
headers: {
"Cross-Origin-Opener-Policy": "same-origin",
"Cross-Origin-Embedder-Policy": "require-corp",
"Timing-Allow-Origin": [
"https://developer.mozilla.org",
"https://example.com",
],
"Access-Control-Expose-Headers": "Tauri-Custom-Header",
"Tauri-Custom-Header": {
"key1": "'value1' 'value2'",
"key2": "'value3'"
}
},
csp: "default-src 'self'; connect-src ipc: http://ipc.localhost",
}
//..
}
//..
}
In this example Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy are set to allow for the use of SharedArrayBuffer. The result is, that those headers are then set on every response sent via the get_response function in crates/tauri/src/protocol/tauri.rs. The Content-Security-Policy header is defined separately, because it is also handled separately.
For the helloworld example, this config translates into those response headers:
access-control-allow-origin: http://tauri.localhost
access-control-expose-headers: Tauri-Custom-Header
content-security-policy: default-src 'self'; connect-src ipc: http://ipc.localhost; script-src 'self' 'sha256-Wjjrs6qinmnr+tOry8x8PPwI77eGpUFR3EEGZktjJNs='
content-type: text/html
cross-origin-embedder-policy: require-corp
cross-origin-opener-policy: same-origin
tauri-custom-header: key1 'value1' 'value2'; key2 'value3'
timing-allow-origin: https://developer.mozilla.org, https://example.com
Since the resulting header values are always ‘string-like’. So depending on the what data type the HeaderSource is, they need to be converted.
String(JS/Rust): stay the same for the resulting header valueArray(JS)/Vec\<String\>(Rust): Item are joined by “, “ for the resulting header valueObject(JS)/Hashmap\<String,String\>(Rust): Items are composed from: key + space + value. Item are then joined by “; “ for the resulting header value
Object Properties:
- Access-Control-Allow-Credentials
- Access-Control-Allow-Headers
- Access-Control-Allow-Methods
- Access-Control-Expose-Headers
- Access-Control-Max-Age
- Cross-Origin-Embedder-Policy
- Cross-Origin-Opener-Policy
- Cross-Origin-Resource-Policy
- Permissions-Policy
- Service-Worker-Allowed
- Tauri-Custom-Header
- Timing-Allow-Origin
- X-Content-Type-Options
Access-Control-Allow-Credentials
HeaderSource | null
The Access-Control-Allow-Credentials response header tells browsers whether the server allows cross-origin HTTP requests to include credentials.
See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials>
Access-Control-Allow-Headers
HeaderSource | null
The Access-Control-Allow-Headers response header is used in response to a preflight request which includes the Access-Control-Request-Headers to indicate which HTTP headers can be used during the actual request.
This header is required if the request has an Access-Control-Request-Headers header.
See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers>
Access-Control-Allow-Methods
HeaderSource | null
The Access-Control-Allow-Methods response header specifies one or more methods allowed when accessing a resource in response to a preflight request.
See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods>
Access-Control-Expose-Headers
HeaderSource | null
The Access-Control-Expose-Headers response header allows a server to indicate which response headers should be made available to scripts running in the browser, in response to a cross-origin request.
See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers>
Access-Control-Max-Age
HeaderSource | null
The Access-Control-Max-Age response header indicates how long the results of a preflight request (that is the information contained in the Access-Control-Allow-Methods and Access-Control-Allow-Headers headers) can be cached.
See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age>
Cross-Origin-Embedder-Policy
HeaderSource | null
The HTTP Cross-Origin-Embedder-Policy (COEP) response header configures embedding cross-origin resources into the document.
See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy>
Cross-Origin-Opener-Policy
HeaderSource | null
The HTTP Cross-Origin-Opener-Policy (COOP) response header allows you to ensure a top-level document does not share a browsing context group with cross-origin documents. COOP will process-isolate your document and potential attackers can’t access your global object if they were to open it in a popup, preventing a set of cross-origin attacks dubbed XS-Leaks.
See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy>
Cross-Origin-Resource-Policy
HeaderSource | null
The HTTP Cross-Origin-Resource-Policy response header conveys a desire that the browser blocks no-cors cross-origin/cross-site requests to the given resource.
See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy>
Permissions-Policy
HeaderSource | null
The HTTP Permissions-Policy header provides a mechanism to allow and deny the use of browser features in a document or within any <iframe> elements in the document.
See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy>
Service-Worker-Allowed
HeaderSource | null
The HTTP Service-Worker-Allowed response header is used to broaden the path restriction for a service worker’s default scope.
By default, the scope for a service worker registration is the directory where the service worker script is located. For example, if the script sw.js is located in /js/sw.js, it can only control URLs under /js/ by default. Servers can use the Service-Worker-Allowed header to allow a service worker to control URLs outside of its own directory.
See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Service-Worker-Allowed>
Tauri-Custom-Header
HeaderSource | null
A custom header field Tauri-Custom-Header, don’t use it. Remember to set Access-Control-Expose-Headers accordingly
NOT INTENDED FOR PRODUCTION USE
Timing-Allow-Origin
HeaderSource | null
The Timing-Allow-Origin response header specifies origins that are allowed to see values of attributes retrieved via features of the Resource Timing API, which would otherwise be reported as zero due to cross-origin restrictions.
See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Timing-Allow-Origin>
X-Content-Type-Options
HeaderSource | null
The X-Content-Type-Options response HTTP header is a marker used by the server to indicate that the MIME types advertised in the Content-Type headers should be followed and not be changed. The header allows you to avoid MIME type sniffing by saying that the MIME types are deliberately configured.
See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options>
HeaderSource
Any of the following:
stringstring version of the header Valuestring[] list version of the header value. Item are joined by “,” for the real header value- (Rust struct | Json | JavaScript Object) equivalent of the header value. Items are composed from: key + space + value. Item are then joined by “;” for the real header value Allows additional properties:
string
definition of a header source
The header value to a header name
HookCommand
Any of the following:
stringRun the given script with the default options.- Run the given script with custom options. Object Properties: - cwd - script (required) ##### cwd
string|nullThe current working directory. ##### scriptstringThe script to execute.
Describes a shell command to be executed when a CLI hook is triggered.
Identifier
string
IosConfig
General configuration for the iOS target.
Object Properties:
- bundleVersion
- developmentTeam
- frameworks
- infoPlist
- minimumSystemVersion
- template
bundleVersion
string | null
The version of the build that identifies an iteration of the bundle.
Translates to the bundle’s CFBundleVersion property.
developmentTeam
string | null
The development team. This value is required for iOS development because code signing is enforced. The APPLE_DEVELOPMENT_TEAM environment variable can be set to overwrite it.
frameworks
string[] | null
A list of strings indicating any iOS frameworks that need to be bundled with the application.
Note that you need to recreate the iOS project for the changes to be applied.
infoPlist
string | null
Path to a Info.plist file to merge with the default Info.plist.
Note that Tauri also looks for a Info.plist and Info.ios.plist file in the same directory as the Tauri configuration file.
minimumSystemVersion
string
A version string indicating the minimum iOS version that the bundled application supports. Defaults to 13.0.
Maps to the IPHONEOS_DEPLOYMENT_TARGET value.
Default: "14.0"
template
string | null
A custom XcodeGen project.yml template to use.
LinuxConfig
Configuration for Linux bundles.
See more: <https://v2.tauri.app/reference/config/#linuxconfig>
Object Properties:
- appimage
- deb
- rpm
appimage
Configuration for the AppImage bundle.
Default
{
"bundleMediaFramework": false,
"files": {}
}
deb
Configuration for the Debian bundle.
Default
{
"files": {}
}
rpm
Configuration for the RPM bundle.
Default
{
"epoch": 0,
"files": {},
"release": "1"
}
LogicalPosition
Position coordinates struct.
Object Properties:
- x (required)
- y (required)
x
number formatted as double
X coordinate.
y
number formatted as double
Y coordinate.
MacConfig
Configuration for the macOS bundles.
See more: <https://v2.tauri.app/reference/config/#macconfig>
Object Properties:
- bundleName
- bundleVersion
- dmg
- entitlements
- exceptionDomain
- files
- frameworks
- hardenedRuntime
- infoPlist
- minimumSystemVersion
- providerShortName
- signingIdentity
bundleName
string | null
The name of the builder that built the bundle.
Translates to the bundle’s CFBundleName property.
If not set, defaults to the package’s product name.
bundleVersion
string | null
The version of the build that identifies an iteration of the bundle.
Translates to the bundle’s CFBundleVersion property.
dmg
DMG-specific settings.
Default
{
"appPosition": {
"x": 180,
"y": 170
},
"applicationFolderPosition": {
"x": 480,
"y": 170
},
"windowSize": {
"height": 400,
"width": 660
}
}
entitlements
string | null
Path to the entitlements file.
exceptionDomain
string | null
Allows your application to communicate with the outside world. It should be a lowercase, without port and protocol domain name.
files
The files to include in the application relative to the Contents directory.
Allows additional properties: string
Default: {}
frameworks
string[] | null
A list of strings indicating any macOS X frameworks that need to be bundled with the application.
If a name is used, “.framework” must be omitted and it will look for standard install locations. You may also use a path to a specific framework.
hardenedRuntime
boolean
Whether the codesign should enable hardened runtime (for executables) or not.
Default: true
infoPlist
string | null
Path to a Info.plist file to merge with the default Info.plist.
Note that Tauri also looks for a Info.plist file in the same directory as the Tauri configuration file.
minimumSystemVersion
string | null
A version string indicating the minimum macOS X version that the bundled application supports. Defaults to 10.13.
Setting it to null completely removes the LSMinimumSystemVersion field on the bundle’s Info.plist and the MACOSX_DEPLOYMENT_TARGET environment variable.
Ignored in tauri dev.
An empty string is considered an invalid value so the default value is used.
Default: "10.13"
providerShortName
string | null
Provider short name for notarization.
signingIdentity
string | null
Identity to use for code signing.
NsisCompression
One of the following:
"zlib"ZLIB uses the deflate algorithm, it is a quick and simple method. With the default compression level it uses about 300 KB of memory."bzip2"BZIP2 usually gives better compression ratios than ZLIB, but it is a bit slower and uses more memory. With the default compression level it uses about 4 MB of memory."lzma"LZMA (default) is a new compression method that gives very good compression ratios. The decompression speed is high (10-20 MB/s on a 2 GHz CPU), the compression speed is lower. The memory size that will be used for decompression is the dictionary size plus a few KBs, the default is 8 MB."none"Disable compression
Compression algorithms used in the NSIS installer.
See <https://nsis.sourceforge.io/Reference/SetCompressor>
NsisConfig
Configuration for the Installer bundle using NSIS.
Object Properties:
- compression
- customLanguageFiles
- displayLanguageSelector
- headerImage
- installerHooks
- installerIcon
- installMode
- languages
- minimumWebview2Version
- sidebarImage
- startMenuFolder
- template
- uninstallerHeaderImage
- uninstallerIcon
compression
Set the compression algorithm used to compress files in the installer.
See <https://nsis.sourceforge.io/Reference/SetCompressor>
Default: "lzma"
customLanguageFiles
| null
A key-value pair where the key is the language and the value is the path to a custom .nsh file that holds the translated text for tauri’s custom messages.
See <https://github.com/tauri-apps/tauri/blob/dev/crates/tauri-bundler/src/bundle/windows/nsis/languages/English.nsh> for an example .nsh file.
Note: the key must be a valid NSIS language and it must be added to the [Self::languages] array,
Allows additional properties: string
displayLanguageSelector
boolean
Whether to display a language selector dialog before the installer and uninstaller windows are rendered or not. By default the OS language is selected, with a fallback to the first language in the languages array.
headerImage
string | null
The path to a bitmap file to display on the header of installers pages.
The recommended dimensions are 150px x 57px.
installerHooks
string | null
A path to a .nsh file that contains special NSIS macros to be hooked into the main installer.nsi script.
Supported hooks are:
NSIS_HOOK_PREINSTALL: This hook runs before copying files, setting registry key values and creating shortcuts.NSIS_HOOK_POSTINSTALL: This hook runs after the installer has finished copying all files, setting the registry keys and created shortcuts.NSIS_HOOK_PREUNINSTALL: This hook runs before removing any files, registry keys and shortcuts.NSIS_HOOK_POSTUNINSTALL: This hook runs after files, registry keys and shortcuts have been removed.
Example
!macro NSIS_HOOK_PREINSTALL
MessageBox MB_OK "PreInstall"
!macroend
!macro NSIS_HOOK_POSTINSTALL
MessageBox MB_OK "PostInstall"
!macroend
!macro NSIS_HOOK_PREUNINSTALL
MessageBox MB_OK "PreUnInstall"
!macroend
!macro NSIS_HOOK_POSTUNINSTALL
MessageBox MB_OK "PostUninstall"
!macroend
installerIcon
string | null
The path to an icon file used as the installer icon.
installMode
Whether the installation will be for all users or just the current user.
Default: "currentUser"
languages
string[] | null
A list of installer languages. Default to ["English"] if not set.
By default the OS language is used. If the OS language is not in the list of languages, the first language will be used. To allow the user to select the language, set display_language_selector to true.
See <https://github.com/kichik/nsis/tree/9465c08046f00ccb6eda985abbdbf52c275c6c4d/Contrib/Language%20files> for the complete list of languages.
minimumWebview2Version
string | null
Deprecated: use [WindowsConfig::minimum_webview2_version] (bundle > windows > minimumWebview2Version) instead.
Try to ensure that the WebView2 version is equal to or newer than this version, if the user’s WebView2 is older than this version, the installer will try to trigger a WebView2 update.
sidebarImage
string | null
The path to a bitmap file for the Welcome page and the Finish page.
The recommended dimensions are 164px x 314px.
startMenuFolder
string | null
Set the folder name for the start menu shortcut.
Use this option if you have multiple apps and wish to group their shortcuts under one folder or if you generally prefer to set your shortcut inside a folder.
Examples:
AwesomePublisher, shortcut will be placed in%AppData%\Microsoft\Windows\Start Menu\Programs\AwesomePublisher\<your-app>.lnk- If unset, shortcut will be placed in
%AppData%\Microsoft\Windows\Start Menu\Programs\<your-app>.lnk
template
string | null
A custom .nsi template to use.
uninstallerHeaderImage
string | null
The path to a bitmap file to display on the header of uninstallers pages. Defaults to [Self::header_image]. If this is set but [Self::header_image] is not, a default image from NSIS will be applied to header_image
The recommended dimensions are 150px x 57px.
uninstallerIcon
string | null
The path to an icon file used as the uninstaller icon.
NSISInstallerMode
One of the following:
"currentUser"Default mode for the installer. Install the app by default in a directory that doesn’t require Administrator access. Installer metadata will be saved under theHKCUregistry path."perMachine"Install the app by default in theProgram Filesfolder directory requires Administrator access for the installation. Installer metadata will be saved under theHKLMregistry path."both"Combines both modes and allows the user to choose at install time whether to install for the current user or per machine. Note that this mode will require Administrator access even if the user wants to install it for the current user only. Installer metadata will be saved under theHKLMorHKCUregistry path based on the user’s choice.
Install Modes for the NSIS installer.
Number
Any of the following:
integerformatted asint64Represents an [i64].numberformatted asdoubleRepresents a [f64].
A valid ACL number.
PatternKind
One of the following:
- Brownfield pattern. Object Properties: - use (required) ##### use
"brownfield" - Isolation pattern. Recommended for security purposes. Object Properties: - options (required) - use (required) ##### options Object Properties: - dir (required) ###### dir
stringThe dir containing the index.html file that contains the secure isolation application. ##### use"isolation"
The application pattern.
PermissionEntry
Any of the following:
IdentifierReference a permission or permission set by identifier.- Reference a permission or permission set by identifier and extends its scope. Object Properties: - allow - deny - identifier (required) ##### allow
Value[] |nullData that defines what is allowed by the scope. ##### denyValue[] |nullData that defines what is denied by the scope. This should be prioritized by validation logic. ##### identifierIdentifierIdentifier of the permission or permission set.
An entry for a permission value in a [Capability] can be either a raw permission [Identifier] or an object that references a permission and extends its scope.
PluginConfig
The plugin configs holds a HashMap mapping a plugin name to its configuration object.
See more: <https://v2.tauri.app/reference/config/#pluginconfig>
Allows additional properties: true
Position
Position coordinates struct.
Object Properties:
- x (required)
- y (required)
x
integer formatted as uint32
X coordinate.
y
integer formatted as uint32
Y coordinate.
PreventOverflowConfig
Any of the following:
booleanEnable prevent overflow or notPreventOverflowMarginEnable prevent overflow with a margin so that the window’s size + this margin won’t overflow the workarea
Prevent overflow with a margin
PreventOverflowMargin
Enable prevent overflow with a margin so that the window’s size + this margin won’t overflow the workarea
Object Properties:
- height (required)
- width (required)
height
integer formatted as uint32
Vertical margin in physical pixels
width
integer formatted as uint32
Horizontal margin in physical pixels
RpmCompression
One of the following:
- Gzip compression Object Properties: - level (required) - type (required) ##### level
integerformatted asuint32Gzip compression level ##### type"gzip" - Zstd compression Object Properties: - level (required) - type (required) ##### level
integerformatted asint32Zstd compression level ##### type"zstd" - Xz compression Object Properties: - level (required) - type (required) ##### level
integerformatted asuint32Xz compression level ##### type"xz" - Bzip2 compression Object Properties: - level (required) - type (required) ##### level
integerformatted asuint32Bzip2 compression level ##### type"bzip2" - Disable compression Object Properties: - type (required) ##### type
"none"
Compression algorithms used when bundling RPM packages.
RpmConfig
Configuration for RPM bundles.
Object Properties:
- compression
- conflicts
- depends
- desktopTemplate
- epoch
- files
- obsoletes
- postInstallScript
- postRemoveScript
- preInstallScript
- preRemoveScript
- provides
- recommends
- release
compression
RpmCompression | null
Compression algorithm and level. Defaults to Gzip with level 6.
conflicts
string[] | null
The list of RPM dependencies your application conflicts with. They must not be present in order for the package to be installed.
depends
string[] | null
The list of RPM dependencies your application relies on.
desktopTemplate
string | null
Path to a custom desktop file Handlebars template.
Available variables: categories, comment (optional), exec, icon and name.
epoch
integer formatted as uint32
The RPM epoch.
files
The files to include on the package.
Allows additional properties: string
Default: {}
obsoletes
string[] | null
The list of RPM dependencies your application supersedes - if this package is installed, packages listed as “obsoletes” will be automatically removed (if they are present).
postInstallScript
string | null
Path to script that will be executed after the package is unpacked. See <http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html>
postRemoveScript
string | null
Path to script that will be executed after the package is removed. See <http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html>
preInstallScript
string | null
Path to script that will be executed before the package is unpacked. See <http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html>
preRemoveScript
string | null
Path to script that will be executed before the package is removed. See <http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html>
provides
string[] | null
The list of RPM dependencies your application provides.
recommends
string[] | null
The list of RPM dependencies your application recommends.
release
string
The RPM release tag.
Default: "1"
RunnerConfig
Any of the following:
stringA string specifying the binary to run.- An object with advanced configuration options. Object Properties: - args - cmd (required) - cwd ##### args
string[] |nullArguments to pass to the command. ##### cmdstringThe binary to run. ##### cwdstring|nullThe current working directory to run the command from.
The runner configuration.
ScrollBarStyle
One of the following:
"default"The scrollbar style to use in the webview."fluentOverlay"Fluent UI style overlay scrollbars. Windows Only Requires WebView2 Runtime version 125.0.2535.41 or higher, does nothing on older versions, see <https://learn.microsoft.com/en-us/microsoft-edge/webview2/release-notes/?tabs=dotnetcsharp#10253541>
The scrollbar style to use in the webview.
Platform-specific
- Windows: This option must be given the same value for all webviews that target the same data directory.
SecurityConfig
Security configuration.
See more: <https://v2.tauri.app/reference/config/#securityconfig>
Object Properties:
- assetProtocol
- capabilities
- csp
- dangerousDisableAssetCspModification
- devCsp
- freezePrototype
- headers
- pattern
assetProtocol
Custom protocol config.
Default
{
"enable": false,
"scope": []
}
capabilities
List of capabilities that are enabled on the application.
By default (not set or empty list), all capability files from ./capabilities/ are included, by setting values in this entry, you have fine grained control over which capabilities are included
You can either reference a capability file defined in ./capabilities/ with its identifier or inline a [Capability]
Example
{
"app": {
"capabilities": [
"main-window",
{
"identifier": "drag-window",
"permissions": ["core:window:allow-start-dragging"]
}
]
}
}
Default: []
csp
Csp | null
The Content Security Policy that will be injected on all HTML files on the built application. If dev_csp is not specified, this value is also injected on dev.
This is a really important part of the configuration since it helps you ensure your WebView is secured. See <https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP>.
dangerousDisableAssetCspModification
Disables the Tauri-injected CSP sources.
At compile time, Tauri parses all the frontend assets and changes the Content-Security-Policy to only allow loading of your own scripts and styles by injecting nonce and hash sources. This stricts your CSP, which may introduce issues when using along with other flexing sources.
This configuration option allows both a boolean and a list of strings as value. A boolean instructs Tauri to disable the injection for all CSP injections, and a list of strings indicates the CSP directives that Tauri cannot inject.
WARNING: Only disable this if you know what you are doing and have properly configured the CSP. Your application might be vulnerable to XSS attacks without this Tauri protection.
devCsp
Csp | null
The Content Security Policy that will be injected on all HTML files on development.
This is a really important part of the configuration since it helps you ensure your WebView is secured. See <https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP>.
freezePrototype
boolean
Freeze the Object.prototype when using the custom protocol.
headers
HeaderConfig | null
The headers, which are added to every http response from tauri to the web view This doesn’t include IPC Messages and error responses
pattern
The pattern to use.
Default
{
"use": "brownfield"
}
Size
Size of the window.
Object Properties:
- height (required)
- width (required)
height
integer formatted as uint32
Height of the window.
width
integer formatted as uint32
Width of the window.
Target
One of the following:
"macOS"MacOS."windows"Windows."linux"Linux."android"Android."iOS"iOS.
Platform target.
Theme
One of the following:
"Light"Light theme."Dark"Dark theme.
System theme.
TitleBarStyle
One of the following:
"Visible"A normal title bar."Transparent"Makes the title bar transparent, so the window background color is shown instead. Useful if you don’t need to have actual HTML under the title bar. This lets you avoid the caveats of usingTitleBarStyle::Overlay. Will be more useful when Tauri lets you set a custom window background color."Overlay"Shows the title bar as a transparent overlay over the window’s content. Keep in mind: - The height of the title bar is different on different OS versions, which can lead to window the controls and title not being where you don’t expect. - You need to define a custom drag region to make your window draggable, however due to a limitation you can’t drag the window when it’s not in focus <https://github.com/tauri-apps/tauri/issues/4316>. - The color of the window title depends on the system theme.
How the window title bar should be displayed on macOS.
TrayIconConfig
Configuration for application tray icon.
See more: <https://v2.tauri.app/reference/config/#trayiconconfig>
Object Properties:
- iconAsTemplate
- iconPath (required)
- id
- menuOnLeftClick
- showMenuOnLeftClick
- title
- tooltip
iconAsTemplate
boolean
A Boolean value that determines whether the image represents a template image on macOS.
iconPath
string
Path to the default icon to use for the tray icon.
Note: this stores the image in raw pixels to the final binary, so keep the icon size (width and height) small or else it’s going to bloat your final executable
id
string | null
Set an id for this tray icon so you can reference it later, defaults to main.
menuOnLeftClick
boolean
No longer works since v2.2, use [Self::show_menu_on_left_click] instead
A Boolean value that determines whether the menu should appear when the tray icon receives a left click.
Platform-specific:
- Linux: Unsupported.
Default: true
showMenuOnLeftClick
boolean
A Boolean value that determines whether the menu should appear when the tray icon receives a left click.
Platform-specific:
- Linux: Unsupported.
Default: true
title
string | null
Title for MacOS tray
tooltip
string | null
Tray icon tooltip on Windows and macOS
Updater
Any of the following:
V1CompatibleGenerates legacy zipped v1 compatible updatersbooleanProduce updaters and their signatures or not
Updater type
V1Compatible
"v1Compatible",Generates legacy zipped v1 compatible updaters
Generates legacy zipped v1 compatible updaters
Value
Any of the following:
nullRepresents a null JSON value.booleanRepresents a [bool].NumberRepresents a valid ACL [Number].stringRepresents a [String].Value[] Represents a list of other [Value]s.- Represents a map of [
String] keys to [Value]s. Allows additional properties:Value
All supported ACL values.
WebviewInstallMode
One of the following:
- Do not install the Webview2 as part of the Windows Installer. Object Properties: - type (required) ##### type
"skip" - Download the bootstrapper and run it. Requires an internet connection. Results in a smaller installer size, but is not recommended on Windows 7. Object Properties: - silent - type (required) ##### silent
booleanInstructs the installer to run the bootstrapper in silent mode. Defaults totrue. Default:true##### type"downloadBootstrapper" - Embed the bootstrapper and run it. Requires an internet connection. Increases the installer size by around 1.8MB, but offers better support on Windows 7. Object Properties: - silent - type (required) ##### silent
booleanInstructs the installer to run the bootstrapper in silent mode. Defaults totrue. Default:true##### type"embedBootstrapper" - Embed the offline installer and run it. Does not require an internet connection. Increases the installer size by around 127MB. Object Properties: - silent - type (required) ##### silent
booleanInstructs the installer to run the installer in silent mode. Defaults totrue. Default:true##### type"offlineInstaller" - Embed a fixed webview2 version and use it at runtime. Increases the installer size by around 180MB. Object Properties: - path (required) - type (required) ##### path
stringThe path to the fixed runtime to use. The fixed version can be downloaded on the official website. The.cabfile must be extracted to a folder and this folder path must be defined on this field. ##### type"fixedRuntime"
Install modes for the Webview2 runtime. Note that for the updater bundle [Self::DownloadBootstrapper] is used.
For more information see <https://v2.tauri.app/distribute/windows-installer/#webview2-installation-options>.
WebviewUrl
Any of the following:
stringformatted asuriAn external URL. Must use either thehttporhttpsschemes.stringThe path portion of an app URL. For instance, to loadtauri://localhost/users/john, you can simply provideusers/johnin this configuration.stringformatted asuriA custom protocol url, for example,doom://index.html
An URL to open on a Tauri webview window.
WindowConfig
The window configuration object.
See more: <https://v2.tauri.app/reference/config/#windowconfig>
Object Properties:
- acceptFirstMouse
- activityName
- additionalBrowserArgs
- allowLinkPreview
- alwaysOnBottom
- alwaysOnTop
- backgroundColor
- backgroundThrottling
- browserExtensionsEnabled
- center
- closable
- contentProtected
- create
- createdByActivityName
- dataDirectory
- dataStoreIdentifier
- decorations
- devtools
- disableInputAccessoryView
- dragDropEnabled
- focus
- focusable
- fullscreen
- generalAutofillEnabled
- height
- hiddenTitle
- incognito
- javascriptDisabled
- label
- limitNavigationsToAppBoundDomains
- maxHeight
- maximizable
- maximized
- maxWidth
- minHeight
- minimizable
- minWidth
- noRedirectionBitmap
- parent
- preventOverflow
- proxyUrl
- requestedBySceneIdentifier
- resizable
- scrollBarStyle
- shadow
- skipTaskbar
- tabbingIdentifier
- theme
- title
- titleBarStyle
- trafficLightPosition
- transparent
- url
- useHttpsScheme
- userAgent
- visible
- visibleOnAllWorkspaces
- width
- windowClassname
- windowEffects
- x
- y
- zoomHotkeysEnabled
acceptFirstMouse
boolean
Whether clicking an inactive window also clicks through to the webview on macOS.
activityName
string | null
The name of the Android activity to create for this window.
additionalBrowserArgs
string | null
Defines additional browser arguments on Windows.
Warning
Webview instances with different browser arguments must also have different data directories.
By default wry passes --disable-features=msWebOOUI,msPdfOOUI,msSmartScreenProtection so if you set this, you also need to disable these components by yourself if you want.
allowLinkPreview
boolean
on macOS and iOS there is a link preview on long pressing links, this is enabled by default. see https://docs.rs/objc2-web-kit/latest/objc2_web_kit/struct.WKWebView.html#method.allowsLinkPreview
Default: true
alwaysOnBottom
boolean
Whether the window should always be below other windows.
alwaysOnTop
boolean
Whether the window should always be on top of other windows.
backgroundColor
Color | null
Set the window and webview background color.
Platform-specific:
- Windows: alpha channel is ignored for the window layer.
- Windows: On Windows 7, alpha channel is ignored for the webview layer.
- Windows: On Windows 8 and newer, if alpha channel is not
0, it will be ignored for the webview layer.
backgroundThrottling
BackgroundThrottlingPolicy | null
Change the default background throttling behaviour.
By default, browsers use a suspend policy that will throttle timers and even unload the whole tab (view) to free resources after roughly 5 minutes when a view became minimized or hidden. This will pause all tasks until the documents visibility state changes back from hidden to visible by bringing the view back to the foreground.
Platform-specific
- Linux / Windows / Android: Unsupported. Workarounds like a pending WebLock transaction might suffice.
- iOS: Supported since version 17.0+.
- macOS: Supported since version 14.0+.
see <https://github.com/tauri-apps/tauri/issues/5250#issuecomment-2569380578>
browserExtensionsEnabled
boolean
Whether browser extensions can be installed for the webview process
Platform-specific:
- Windows: Enables the WebView2 environment’s
AreBrowserExtensionsEnabled - MacOS / Linux / iOS / Android - Unsupported.
center
boolean
Whether or not the window starts centered or not.
closable
boolean
Whether the window’s native close button is enabled or not.
Platform-specific
- Linux: “GTK+ will do its best to convince the window manager not to show a close button. Depending on the system, this function may not have any effect when called on a window that is already visible”
- iOS / Android: Unsupported.
Default: true
contentProtected
boolean
Prevents the window contents from being captured by other apps.
create
boolean
Whether Tauri should create this window at app startup or not.
When this is set to false you must manually grab the config object via app.config().app.windows and create it with WebviewWindowBuilder::from_config.
Example:
tauri::Builder::default()
.setup(|app| {
tauri::WebviewWindowBuilder::from_config(app.handle(), &app.config().app.windows[0])?.build()?;
Ok(())
});
Default: true
createdByActivityName
string | null
The name of the Android activity that is creating this webview window.
This is important to determine which stack the activity will belong to.
dataDirectory
string | null
Set a custom path for the webview’s data directory (localStorage, cache, etc.) relative to [appDataDir()]/${label}.
To set absolute paths, use WebviewWindowBuilder::data_directory
Platform-specific:
- Windows: WebViews with different values for settings like
additionalBrowserArgs,browserExtensionsEnabledorscrollBarStylemust have different data directories. - macOS / iOS: Unsupported, use
dataStoreIdentifierinstead. - Android: Unsupported.
dataStoreIdentifier
integer formatted as uint8[] | null maximum of 16 items, minimum of 16 items
Initialize the WebView with a custom data store identifier. This can be seen as a replacement for dataDirectory which is unavailable in WKWebView. See https://developer.apple.com/documentation/webkit/wkwebsitedatastore/init(foridentifier:)?language=objc
The array must contain 16 u8 numbers.
Platform-specific:
- iOS: Supported since version 17.0+.
- macOS: Supported since version 14.0+.
- Windows / Linux / Android: Unsupported.
decorations
boolean
Whether the window should have borders and bars.
Default: true
devtools
boolean | null
Enable web inspector which is usually called browser devtools. Enabled by default.
This API works in debug builds, but requires devtools feature flag to enable it in release builds.
Platform-specific
- macOS: This will call private functions on macOS.
- Android: Open
chrome://inspect/#devicesin Chrome to get the devtools window. Wry’sWebViewdevtools API isn’t supported on Android. - iOS: Open Safari > Develop > [Your Device Name] > [Your WebView] to get the devtools window.
disableInputAccessoryView
boolean
Allows disabling the input accessory view on iOS.
The accessory view is the view that appears above the keyboard when a text input element is focused. It usually displays a view with “Done”, “Next” buttons.
dragDropEnabled
boolean
Whether the drag and drop handlers used internally to generate DragDropEvents are enabled on the webview. By default it is enabled.
Disabling it is required to use HTML5 drag and drop on the frontend on Windows since we replace the drag drop handler of WebView2.
Note: this setting maps to WebviewBuilder::disable_drag_drop_handler, not WindowBuilder::drag_and_drop.
Default: true
focus
boolean
Whether the window will be initially focused or not.
Default: true
focusable
boolean
Whether the window will be focusable or not.
Default: true
fullscreen
boolean
Whether the window starts as fullscreen or not.
generalAutofillEnabled
boolean
Controls the WebView’s browser-level general autofill behavior.
This option does not disable password or credit card autofill.
When set to false, the WebView will not automatically populate general form fields using previously stored data such as addresses or contact information.
If not specified, this is true by default.
Platform-specific
- Windows: Supported. WebView2’s autofill feature (called “Suggestions”) may not honor
autocomplete="off"on input elements in some cases. - Linux / Android / iOS / macOS: Unsupported and performs no operation.
Default: true
height
number formatted as double
The window height in logical pixels.
Default: 600
hiddenTitle
boolean
If true, sets the window title to be hidden on macOS.
incognito
boolean
Whether or not the webview should be launched in incognito mode.
Platform-specific:
- Android: Unsupported.
javascriptDisabled
boolean
Whether we should disable JavaScript code execution on the webview or not.
label
string
The window identifier. It must be alphanumeric.
Default: "main"
limitNavigationsToAppBoundDomains
boolean
Whether to limit navigations to App-Bound Domains. This is necessary to enable Service Workers on iOS according to StackOverflow.
Default is false.
Note: If you set this to true make sure to add localhost and any registrable domains used in this webview to tauri-src/Info.ios.plist:
<plist>
<dict>
<key>WKAppBoundDomains</key>
<array>
<string>localhost</string>
<string>aregistrabledomain.example</string>
</array>
</dict>
</plist>
You must add localhost if any webview with this set to true opens a local webpage, makes any localhost calls, or uses the isolation pattern because Tauri uses the localhost domain for hosting the application webpage, the IPC protocol, and the isolation pattern’s iframe.
Requests served through custom uri schemes are allowed so long as they use a registrable domain specified in the WKAppBoundDomains array for all the requests from the app, including requests for the localhost domain.
In theory, you can whitelist an entire uri scheme by including the protocol name followed by a colon. For example, to allow all requests using a custom “stream” uri scheme (see this tauri example), you could add stream: to the AppBoundDomains array. That said, I’m not sure whether Apple would let your app through app review if you do whitelist an entire protocol because this feature is not mentioned in their blog post on App-Bound Domains.
See https://webkit.org/blog/10882/app-bound-domains/ and https://developer.apple.com/documentation/webkit/wkwebviewconfiguration/limitsnavigationstoappbounddomains for the official documentation on App-Bound Domains.
Platform-specific
- iOS: Supported since version 14.0+.
- Linux / Windows / Android / MacOS: Unsupported.
maxHeight
number | null formatted as double
The max window height in logical pixels.
maximizable
boolean
Whether the window’s native maximize button is enabled or not. If resizable is set to false, this setting is ignored.
Platform-specific
- macOS: Disables the “zoom” button in the window titlebar, which is also used to enter fullscreen mode.
- Linux / iOS / Android: Unsupported.
Default: true
maximized
boolean
Whether the window is maximized or not.
maxWidth
number | null formatted as double
The max window width in logical pixels.
minHeight
number | null formatted as double
The min window height in logical pixels.
minimizable
boolean
Whether the window’s native minimize button is enabled or not.
Platform-specific
- Linux / iOS / Android: Unsupported.
Default: true
minWidth
number | null formatted as double
The min window width in logical pixels.
noRedirectionBitmap
boolean
This sets WS_EX_NOREDIRECTIONBITMAP.
This can avoid the white flash that may appear before the webview content is rendered when using a transparent window. Windows only.
parent
string | null
Sets the window associated with this label to be the parent of the window to be created.
Platform-specific
-
Windows: This sets the passed parent as an owner window to the window to be created. From MSDN owned windows docs:
- An owned window is always above its owner in the z-order.
- The system automatically destroys an owned window when its owner is destroyed.
- An owned window is hidden when its owner is minimized.
-
Linux: This makes the new window transient for parent, see <https://docs.gtk.org/gtk3/method.Window.set_transient_for.html>
-
macOS: This adds the window as a child of parent, see <https://developer.apple.com/documentation/appkit/nswindow/1419152-addchildwindow?language=objc>
preventOverflow
PreventOverflowConfig | null
Whether or not to prevent the window from overflowing the workarea
Platform-specific
- iOS / Android: Unsupported.
proxyUrl
string | null formatted as uri
The proxy URL for the WebView for all network requests.
Must be either a http:// or a socks5:// URL.
Platform-specific
- macOS: Requires the
macos-proxyfeature flag and only compiles for macOS 14+.
requestedBySceneIdentifier
string | null
Sets the identifier of the scene that is requesting the new scene, establishing a relationship between the two scenes.
By default the system uses the foreground scene.
resizable
boolean
Whether the window is resizable or not. When resizable is set to false, native window’s maximize button is automatically disabled.
Default: true
scrollBarStyle
Specifies the native scrollbar style to use with the webview. CSS styles that modify the scrollbar are applied on top of the native appearance configured here.
Defaults to default, which is the browser default.
Platform-specific
-
Windows:
fluentOverlayrequires WebView2 Runtime version 125.0.2535.41 or higher, and does nothing on older versions.- This option must be given the same value for all webviews that target the same data directory.
-
Linux / Android / iOS / macOS: Unsupported. Only supports
Defaultand performs no operation.
Default: "default"
shadow
boolean
Whether or not the window has shadow.
Platform-specific
-
Windows:
falsehas no effect on decorated window, shadow are always ON.truewill make undecorated window have a 1px white border, and on Windows 11, it will have a rounded corners.
-
Linux: Unsupported.
Default: true
skipTaskbar
boolean
If true, hides the window icon from the taskbar on Windows and Linux.
tabbingIdentifier
string | null
Defines the window tabbing identifier for macOS.
Windows with matching tabbing identifiers will be grouped together. If the tabbing identifier is not set, automatic tabbing will be disabled.
theme
Theme | null
The initial window theme. Defaults to the system theme. Only implemented on Windows and macOS 10.14+.
title
string
The window title.
Default: "Tauri App"
titleBarStyle
The style of the macOS title bar.
Default: "Visible"
trafficLightPosition
LogicalPosition | null
The position of the window controls on macOS.
Requires titleBarStyle: Overlay and decorations: true.
transparent
boolean
Whether the window is transparent or not.
Note that on macOS this requires the macos-private-api feature flag, enabled under tauri > macOSPrivateApi. WARNING: Using private APIs on macOS prevents your application from being accepted to the App Store.
On Windows, using noRedirectionBitmap can help avoid a white flash when creating a transparent window.
url
The window webview URL.
Default: "index.html"
useHttpsScheme
boolean
Sets whether the custom protocols should use https://<scheme>.localhost instead of the default http://<scheme>.localhost on Windows and Android. Defaults to false.
Note
Using a https scheme will NOT allow mixed content when trying to fetch http endpoints and therefore will not match the behavior of the <scheme>://localhost protocols used on macOS and Linux.
Warning
Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access the old data.
userAgent
string | null
The user agent for the webview
visible
boolean
Whether the window is visible or not.
Default: true
visibleOnAllWorkspaces
boolean
Whether the window should be visible on all workspaces or virtual desktops.
Platform-specific
- Windows / iOS / Android: Unsupported.
width
number formatted as double
The window width in logical pixels.
Default: 800
windowClassname
string | null
The name of the window class created on Windows to create the window. Windows only.
windowEffects
WindowEffectsConfig | null
Window effects.
Requires the window to be transparent.
Platform-specific:
- Windows: If using decorations or shadows, you may want to try this workaround <https://github.com/tauri-apps/tao/issues/72#issuecomment-975607891>
- Linux: Unsupported
x
number | null formatted as double
The horizontal position of the window’s top left corner in logical pixels
y
number | null formatted as double
The vertical position of the window’s top left corner in logical pixels
zoomHotkeysEnabled
boolean
Whether page zooming by hotkeys is enabled
Platform-specific:
-
Windows: Controls WebView2’s
IsZoomControlEnabledsetting. -
MacOS / Linux: Injects a polyfill that zooms in and out with
ctrl/command+-/=, 20% in each step, ranging from 20% to 1000%. Requireswebview:allow-set-webview-zoompermission -
Android / iOS: Unsupported.
WindowEffect
One of the following:
"appearanceBased"A default material appropriate for the view’s effectiveAppearance. macOS 10.14-"light"macOS 10.14-"dark"macOS 10.14-"mediumLight"macOS 10.14-"ultraDark"macOS 10.14-"titlebar"macOS 10.10+"selection"macOS 10.10+"menu"macOS 10.11+"popover"macOS 10.11+"sidebar"macOS 10.11+"headerView"macOS 10.14+"sheet"macOS 10.14+"windowBackground"macOS 10.14+"hudWindow"macOS 10.14+"fullScreenUI"macOS 10.14+"tooltip"macOS 10.14+"contentBackground"macOS 10.14+"underWindowBackground"macOS 10.14+"underPageBackground"macOS 10.14+"mica"Mica effect that matches the system dark preference Windows 11 Only"micaDark"Mica effect with dark mode but only if dark mode is enabled on the system Windows 11 Only"micaLight"Mica effect with light mode Windows 11 Only"tabbed"Tabbed effect that matches the system dark preference Windows 11 Only"tabbedDark"Tabbed effect with dark mode but only if dark mode is enabled on the system Windows 11 Only"tabbedLight"Tabbed effect with light mode Windows 11 Only"blur"Windows 7/10/11(22H1) Only ##### Notes This effect has bad performance when resizing/dragging the window on Windows 11 build 22621."acrylic"Windows 10/11 Only ##### Notes This effect has bad performance when resizing/dragging the window on Windows 10 v1903+ and Windows 11 build 22000.
Platform-specific window effects
WindowEffectsConfig
The window effects configuration object
Object Properties:
- color
- effects (required)
- radius
- state
color
Color | null
Window effect color. Affects [WindowEffect::Blur] and [WindowEffect::Acrylic] only on Windows 10 v1903+. Doesn’t have any effect on Windows 7 or Windows 11.
effects
List of Window effects to apply to the Window. Conflicting effects will apply the first one and ignore the rest.
radius
number | null formatted as double
Window effect corner radius macOS Only
state
WindowEffectState | null
Window effect state macOS Only
WindowEffectState
One of the following:
"followsWindowActiveState"Make window effect state follow the window’s active state"active"Make window effect state always active"inactive"Make window effect state always inactive
Window effect state macOS only
<https://developer.apple.com/documentation/appkit/nsvisualeffectview/state>
WindowsBuildConfig
Windows-specific build configuration.
Object Properties:
- staticVCRuntime
staticVCRuntime
boolean
Whether to statically link the Visual C++ runtime into the application binary on Windows MSVC targets.
Default: true
WindowsConfig
Windows bundler configuration.
See more: <https://v2.tauri.app/reference/config/#windowsconfig>
Object Properties:
- allowDowngrades
- bundleVCRuntime
- certificateThumbprint
- digestAlgorithm
- minimumWebview2Version
- nsis
- signCommand
- timestampUrl
- tsp
- webviewInstallMode
- wix
allowDowngrades
boolean
Validates a second app installation, blocking the user from installing an older version if set to false.
For instance, if 1.2.1 is installed, the user won’t be able to install app version 1.2.0 or 1.1.5.
The default value of this flag is true.
Default: true
bundleVCRuntime
boolean
Whether to bundle the Visual C++ runtime DLLs alongside the application.
This can be particularly useful when your application includes sidecars or DLLs that do not statically link the Visual C++ runtime and require the runtime DLLs at runtime, and you do not want to require users to install the Visual C++ Redistributable. This can also be useful when build > windows > staticVCRuntime is set to false.
certificateThumbprint
string | null
Specifies the SHA1 hash of the signing certificate.
digestAlgorithm
string | null
Specifies the file digest algorithm to use for creating file signatures. Required for code signing. SHA-256 is recommended.
minimumWebview2Version
string | null
Try to ensure that the WebView2 version is equal to or newer than this version, if the user’s WebView2 is older than this version, the installer will try to trigger a WebView2 update.
nsis
NsisConfig | null
Configuration for the installer generated with NSIS.
signCommand
CustomSignCommandConfig | null
Specify a custom command to sign the binaries. This command needs to have a %1 in args which is just a placeholder for the binary path, which we will detect and replace before calling the command.
By Default we use signtool.exe which can be found only on Windows so if you are on another platform and want to cross-compile and sign you will need to use another tool like osslsigncode.
timestampUrl
string | null
Server to use during timestamping.
tsp
boolean
Whether to use Time-Stamp Protocol (TSP, a.k.a. RFC 3161) for the timestamp server. Your code signing provider may use a TSP timestamp server, like e.g. SSL.com does. If so, enable TSP by setting to true.
webviewInstallMode
The installation mode for the Webview2 runtime.
Default
{
"silent": true,
"type": "downloadBootstrapper"
}
wix
WixConfig | null
Configuration for the MSI generated with WiX.
WixConfig
Configuration for the MSI bundle using WiX.
See more: <https://v2.tauri.app/reference/config/#wixconfig>
Object Properties:
- bannerPath
- componentGroupRefs
- componentRefs
- dialogImagePath
- enableElevatedUpdateTask
- featureGroupRefs
- featureRefs
- fipsCompliant
- fragmentPaths
- language
- mergeRefs
- template
- upgradeCode
- version
bannerPath
string | null
Path to a bitmap file to use as the installation user interface banner. This bitmap will appear at the top of all but the first page of the installer.
The required dimensions are 493px × 58px.
componentGroupRefs
string[]
The ComponentGroup element ids you want to reference from the fragments.
Default: []
componentRefs
string[]
The Component element ids you want to reference from the fragments.
Default: []
dialogImagePath
string | null
Path to a bitmap file to use on the installation user interface dialogs. It is used on the welcome and completion dialogs.
The required dimensions are 493px × 312px.
enableElevatedUpdateTask
boolean
Create an elevated update task within Windows Task Scheduler.
featureGroupRefs
string[]
The FeatureGroup element ids you want to reference from the fragments.
Default: []
featureRefs
string[]
The Feature element ids you want to reference from the fragments.
Default: []
fipsCompliant
boolean
Enables FIPS compliant algorithms. Can also be enabled via the TAURI_BUNDLER_WIX_FIPS_COMPLIANT env var.
fragmentPaths
string[]
A list of paths to .wxs files with WiX fragments to use.
Default: []
language
The installer languages to build. See <https://docs.microsoft.com/en-us/windows/win32/msi/localizing-the-error-and-actiontext-tables>.
Default: "en-US"
mergeRefs
string[]
The Merge element ids you want to reference from the fragments.
Default: []
template
string | null
A custom .wxs template to use.
upgradeCode
string | null formatted as uuid
A GUID upgrade code for MSI installer. This code must stay the same across all of your updates, otherwise, Windows will treat your update as a different app and your users will have duplicate versions of your app.
By default, tauri generates this code by generating a Uuid v5 using the string <productName>.exe.app.x64 in the DNS namespace. You can use Tauri’s CLI to generate and print this code for you, run tauri inspect wix-upgrade-code.
It is recommended that you set this value in your tauri config file to avoid accidental changes in your upgrade code whenever you want to change your product name.
version
string | null
MSI installer version in the format major.minor.patch.build (build is optional).
Because a valid version is required for MSI installer, it will be derived from [Config::version] if this field is not set.
The first field is the major version and has a maximum value of 255. The second field is the minor version and has a maximum value of 255. The third and fourth fields have a maximum value of 65,535.
See <https://learn.microsoft.com/en-us/windows/win32/msi/productversion> for more info.
WixLanguage
Any of the following:
stringA single language to build, without configuration.string[] A list of languages to build, without configuration.- A map of languages and its configuration. Allows additional properties:
WixLanguageConfig
The languages to build using WiX.
WixLanguageConfig
Configuration for a target language for the WiX build.
See more: <https://v2.tauri.app/reference/config/#wixlanguageconfig>
Object Properties:
- localePath
localePath
string | null
The path to a locale (.wxl) file. See <https://wixtoolset.org/documentation/manual/v3/howtos/ui_and_localization/build_a_localized_version.html>.
Environment Variables
This is a documentation of all environment variables used by tauri core crates and tauri CLI.
Tauri CLI
These environment variables are inputs to the CLI which may have an equivalent CLI flag.
Environment Variable Priority
If both environment variable and CLI flag are used, the CLI flag will have priority.
CI— If set, the CLI will run in CI mode and won’t require any user interaction.TAURI_CLI_CONFIG_DEPTH— Number of levels to traverse and find tauri configuration file.TAURI_CLI_PORT— Port to use for the CLI built-in dev server.TAURI_CLI_WATCHER_IGNORE_FILENAME— Name of a.gitignore-style file to control which files should be watched by the CLI indevcommand. The CLI will look for this file name in each directory.TAURI_CLI_NO_DEV_SERVER_WAIT— Skip waiting for the frontend dev server to start before building the tauri application.TAURI_LINUX_AYATANA_APPINDICATOR— Set this var totrueor1to force usage oflibayatana-appindicatorfor system tray on Linux.TAURI_BUNDLER_WIX_FIPS_COMPLIANT— Specify the bundler’s WiXFipsCompliantoption.TAURI_BUNDLER_TOOLS_GITHUB_MIRROR- Specify a GitHub mirror to download files and tools used by tauri bundler.TAURI_BUNDLER_TOOLS_GITHUB_MIRROR_TEMPLATE- Specify a GitHub mirror template to download files and tools used by tauri bundler, for example:https://mirror.example.com/<owner>/<repo>/releases/download/<version>/<asset>.TAURI_SKIP_SIDECAR_SIGNATURE_CHECK- Skip signing sidecars.TAURI_SIGNING_PRIVATE_KEY— Private key used to sign your app bundles, can be either a string or a path to the file.TAURI_SIGNING_PRIVATE_KEY_PASSWORD— The signing private key password, seeTAURI_SIGNING_PRIVATE_KEY.TAURI_SIGNING_RPM_KEY— The private GPG key used to sign the RPM bundle, exported to its ASCII-armored format.TAURI_SIGNING_RPM_KEY_PASSPHRASE— The GPG key passphrase forTAURI_SIGNING_RPM_KEY, if needed.TAURI_WINDOWS_SIGNTOOL_PATH— Specify a path tosigntool.exeused for code signing the application on Windows.APPLE_CERTIFICATE— Base64 encoded of the.p12certificate for code signing. To get this value, runopenssl base64 -A -in MyCertificate.p12 -out MyCertificate-base64.txt.APPLE_CERTIFICATE_PASSWORD— The password you used to export the certificate.APPLE_ID— The Apple ID used to notarize the application. If this environment variable is provided,APPLE_PASSWORDandAPPLE_TEAM_IDmust also be set. Alternatively,APPLE_API_KEYandAPPLE_API_ISSUERcan be used to authenticate.APPLE_PASSWORD— The Apple password used to authenticate for application notarization. Required ifAPPLE_IDis specified. An app-specific password can be used. Alternatively to entering the password in plaintext, it may also be specified using a ‘@keychain:’ or ‘@env:’ prefix followed by a keychain password item name or environment variable name.APPLE_TEAM_ID: Developer team ID. To find your Team ID, go to the Account page on the Apple Developer website, and check your membership details.APPLE_API_KEY— Alternative toAPPLE_IDandAPPLE_PASSWORDfor notarization authentication using JWT. Also an option to allow automated iOS certificate and provisioning profile management.- See creating API keys for more information.
API_PRIVATE_KEYS_DIR— Specify the directory where your AuthKey file is located. SeeAPPLE_API_KEY.APPLE_API_ISSUER— Issuer ID. Required ifAPPLE_API_KEYis specified.APPLE_API_KEY_PATH- path to the API key.p8file. If not specified, for macOS apps the bundler searches the following directories in sequence for a private key file with the name of ‘AuthKey_<api_key>.p8’: ‘./private_keys’, ‘/private_keys’, ‘/.private_keys’, and ‘~/.appstoreconnect/private_keys’. For iOS this variable is required.APPLE_SIGNING_IDENTITY— The identity used to code sign. Overwritestauri.conf.json > bundle > macOS > signingIdentity. If neither are set, it is inferred fromAPPLE_CERTIFICATEwhen provided.APPLE_PROVIDER_SHORT_NAME— If your Apple ID is connected to multiple teams, you have to specify the provider short name of the team you want to use to notarize your app. Overwritestauri.conf.json > bundle > macOS > providerShortName.APPLE_DEVELOPMENT_TEAM— The team ID used to code sign on iOS. Overwritestauri.conf.json > bundle > iOS > developmentTeam. Can be found in https://developer.apple.com/account#MembershipDetailsCard.TAURI_WEBVIEW_AUTOMATION— Enables webview automation (Linux Only).TAURI_ANDROID_PROJECT_PATH— Path of the tauri android project, usually will be<project>/src-tauri/gen/android.TAURI_IOS_PROJECT_PATH— Path of the tauri iOS project, usually will be<project>/src-tauri/gen/ios.
Tauri CLI Hook Commands
These environment variables are set for each hook command (beforeDevCommand, beforeBuildCommand, …etc) which could be useful to conditionally build your frontend or execute a specific action.
TAURI_ENV_DEBUG—truefordevcommand orbuild --debug,falseotherwise.TAURI_ENV_TARGET_TRIPLE— Target triple the CLI is building.TAURI_ENV_ARCH— Target arch,x86_64,aarch64…etc.TAURI_ENV_PLATFORM— Target platform,windows,darwin,linux…etc.TAURI_ENV_PLATFORM_VERSION— Build platform versionTAURI_ENV_FAMILY— Target platform familyunixorwindows.
@tauri-apps/api
The Tauri API allows you to interface with the backend layer.
This module exposes all other modules as an object where the key is the module name, and the value is the module exports.
Examples
import { event, window, path } from '@tauri-apps/api'
Vanilla JS API
The above import syntax is for JavaScript/TypeScript with a bundler. If you’re using vanilla JavaScript, you can use the global window.__TAURI__ object instead. It requires app.withGlobalTauri configuration option enabled.
const { event, window: tauriWindow, path } = window.__TAURI__;
Namespaces
app
Enumerations
BundleType
Bundle type of the current application.
Enumeration Members
App
App: "app";
macOS app bundle
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L48
AppImage
AppImage: "appimage";
Linux AppImage
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L46
Deb
Deb: "deb";
Linux Debian package
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L42
Msi
Msi: "msi";
Windows MSI
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L40
Nsis
Nsis: "nsis";
Windows NSIS
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L38
Rpm
Rpm: "rpm";
Linux RPM
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L44
Type Aliases
DataStoreIdentifier
type DataStoreIdentifier: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number];
Identifier type used for data stores on macOS and iOS.
Represents a 128-bit identifier, commonly expressed as a 16-byte UUID.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L14
OnBackButtonPressPayload
type OnBackButtonPressPayload: object;
Payload for the onBackButtonPress event.
Type declaration
| Name | Type | Description | Defined in |
|---|---|---|---|
canGoBack |
boolean |
Whether the webview canGoBack property is true. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L260 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L258
Functions
defaultWindowIcon()
function defaultWindowIcon(): Promise<Image | null>
Gets the default window icon.
Returns
Example
import { defaultWindowIcon } from '@tauri-apps/api/app';
const icon = await defaultWindowIcon();
Since
2.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L197
fetchDataStoreIdentifiers()
function fetchDataStoreIdentifiers(): Promise<DataStoreIdentifier[]>
Fetches the data store identifiers on macOS and iOS.
See https://developer.apple.com/documentation/webkit/wkwebsitedatastore for more information.
Returns
Promise<DataStoreIdentifier[]>
Example
import { fetchDataStoreIdentifiers } from '@tauri-apps/api/app';
const ids = await fetchDataStoreIdentifiers();
Since
2.4.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L160
getBundleType()
function getBundleType(): Promise<BundleType>
Gets the application bundle type.
Returns
Example
import { getBundleType } from '@tauri-apps/api/app';
const type = await getBundleType();
Since
2.5.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L251
getIdentifier()
function getIdentifier(): Promise<string>
Gets the application identifier.
Returns
Promise<string>
The application identifier as configured in tauri.conf.json.
Example
import { getIdentifier } from '@tauri-apps/api/app';
const identifier = await getIdentifier();
Since
2.4.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L112
getName()
function getName(): Promise<string>
Gets the application name.
Returns
Promise<string>
Example
import { getName } from '@tauri-apps/api/app';
const appName = await getName();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L81
getTauriVersion()
function getTauriVersion(): Promise<string>
Gets the Tauri framework version used by this application.
Returns
Promise<string>
Example
import { getTauriVersion } from '@tauri-apps/api/app';
const tauriVersion = await getTauriVersion();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L96
getVersion()
function getVersion(): Promise<string>
Gets the application version.
Returns
Promise<string>
Example
import { getVersion } from '@tauri-apps/api/app';
const appVersion = await getVersion();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L67
hide()
function hide(): Promise<void>
Hides the application on macOS.
Returns
Promise<void>
Example
import { hide } from '@tauri-apps/api/app';
await hide();
Since
1.2.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L143
onBackButtonPress()
function onBackButtonPress(handler): Promise<PluginListener>
Listens to the backButton event on Android.
Parameters
| Parameter | Type | Description |
|---|---|---|
handler |
(payload) => void |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L267
removeDataStore()
function removeDataStore(uuid): Promise<void>
Removes the data store with the given identifier.
Note that any webview using this data store should be closed before running this API.
See https://developer.apple.com/documentation/webkit/wkwebsitedatastore for more information.
Parameters
| Parameter | Type |
|---|---|
uuid |
DataStoreIdentifier |
Returns
Promise<void>
Example
import { fetchDataStoreIdentifiers, removeDataStore } from '@tauri-apps/api/app';
for (const id of (await fetchDataStoreIdentifiers())) {
await removeDataStore(id);
}
Since
2.4.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L181
setDockVisibility()
function setDockVisibility(visible): Promise<void>
Sets the dock visibility for the application on macOS.
Parameters
| Parameter | Type | Description |
|---|---|---|
visible |
boolean |
Whether the dock should be visible or not. |
Returns
Promise<void>
Example
import { setDockVisibility } from '@tauri-apps/api/app';
await setDockVisibility(false);
Since
2.5.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L236
setTheme()
function setTheme(theme?): Promise<void>
Sets the application’s theme. Pass in null or undefined to follow the system theme.
Parameters
| Parameter | Type |
|---|---|
theme? |
null | Theme |
Returns
Promise<void>
Example
import { setTheme } from '@tauri-apps/api/app';
await setTheme('dark');
Platform-specific
- iOS / Android: Unsupported.
Since
2.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L219
show()
function show(): Promise<void>
Shows the application on macOS. This function does not automatically focus any specific app window.
Returns
Promise<void>
Example
import { show } from '@tauri-apps/api/app';
await show();
Since
1.2.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L128
supportsMultipleWindows()
function supportsMultipleWindows(): Promise<boolean>
Returns
Promise<boolean>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/app.ts#L277
core
Invoke your custom commands.
This package is also accessible with window.__TAURI__.core when app.withGlobalTauri in tauri.conf.json is set to true.
Classes
Channel<T>
Type Parameters
| Type Parameter | Default type |
|---|---|
T |
unknown |
Constructors
new Channel()
new Channel<T>(onmessage?): Channel<T>
Parameters
| Parameter | Type |
|---|---|
onmessage? |
(response) => void |
Returns
Channel<T>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L87
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
id |
number |
The callback id returned from transformCallback |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L79 |
Accessors
onmessage
get onmessage(): (response) => void
set onmessage(handler): void
Parameters
| Parameter | Type |
|---|---|
handler |
(response) => void |
Returns
Function
Parameters
| Parameter | Type |
|---|---|
response |
T |
Returns
void
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L142
Methods
__TAURI_TO_IPC_KEY__()
__TAURI_TO_IPC_KEY__(): string
Returns
string
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L146
toJSON()
toJSON(): string
Returns
string
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L150
PluginListener
Constructors
new PluginListener()
new PluginListener(
plugin,
event,
channelId): PluginListener
Parameters
| Parameter | Type |
|---|---|
plugin |
string |
event |
string |
channelId |
number |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L161
Properties
| Property | Type | Defined in |
|---|---|---|
channelId |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L159 |
event |
string |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L158 |
plugin |
string |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L157 |
Methods
unregister()
unregister(): Promise<void>
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L167
Resource
A rust-backed resource stored through tauri::Manager::resources_table API.
The resource lives in the main process and does not exist in the Javascript world, and thus will not be cleaned up automatically except on application exit. If you want to clean it up early, call Resource.close
Example
import { Resource, invoke } from '@tauri-apps/api/core';
export class DatabaseHandle extends Resource {
static async open(path: string): Promise<DatabaseHandle> {
const rid: number = await invoke('open_db', { path });
return new DatabaseHandle(rid);
}
async execute(sql: string): Promise<void> {
await invoke('execute_sql', { rid: this.rid, sql });
}
}
Extended by
Constructors
new Resource()
new Resource(rid): Resource
Parameters
| Parameter | Type |
|---|---|
rid |
number |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L322
Accessors
rid
get rid(): number
Returns
number
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L318
Methods
close()
close(): Promise<void>
Destroys and cleans up this resource from memory. You should not call any method on this object anymore and should drop any reference to it.
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L330
Interfaces
InvokeOptions
Since
2.0.0
Properties
| Property | Type | Defined in |
|---|---|---|
headers |
HeadersInit |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L233 |
Type Aliases
InvokeArgs
type InvokeArgs: Record<string, unknown> | number[] | ArrayBuffer | Uint8Array;
Command arguments.
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L227
PermissionState
type PermissionState: "granted" | "denied" | "prompt" | "prompt-with-rationale";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L202
Variables
SERIALIZE_TO_IPC_FN
const SERIALIZE_TO_IPC_FN: "__TAURI_TO_IPC_KEY__" = '__TAURI_TO_IPC_KEY__';
A key to be used to implement a special function on your types that define how your type should be serialized when passing across the IPC.
Example
Given a type in Rust that looks like this
#[derive(serde::Serialize, serde::Deserialize)
enum UserId {
String(String),
Number(u32),
}
UserId::String("id") would be serialized into { String: "id" } and so we need to pass the same structure back to Rust
import { SERIALIZE_TO_IPC_FN } from "@tauri-apps/api/core"
class UserIdString {
id
constructor(id) {
this.id = id
}
[SERIALIZE_TO_IPC_FN]() {
return { String: this.id }
}
}
class UserIdNumber {
id
constructor(id) {
this.id = id
}
[SERIALIZE_TO_IPC_FN]() {
return { Number: this.id }
}
}
type UserId = UserIdString | UserIdNumber
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L59
Functions
addPluginListener()
function addPluginListener<T>(
plugin,
event,
cb): Promise<PluginListener>
Adds a listener to a plugin event.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type |
|---|---|
plugin |
string |
event |
string |
cb |
(payload) => void |
Returns
The listener object to stop listening to the events.
Since
2.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L182
checkPermissions()
function checkPermissions<T>(plugin): Promise<T>
Get permission state for a plugin.
This should be used by plugin authors to wrap their actual implementation.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type |
|---|---|
plugin |
string |
Returns
Promise<T>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L209
convertFileSrc()
function convertFileSrc(filePath, protocol): string
Convert a device file path to an URL that can be loaded by the webview. Note that asset: and http://asset.localhost must be added to app.security.csp in tauri.conf.json. Example CSP value: "csp": "default-src 'self' ipc: http://ipc.localhost; img-src 'self' asset: http://asset.localhost" to use the asset protocol on image sources.
Additionally, "enable" : "true" must be added to app.security.assetProtocol in tauri.conf.json and its access scope must be defined on the scope array on the same assetProtocol object.
Parameters
| Parameter | Type | Default value | Description |
|---|---|---|---|
filePath |
string |
undefined |
The file path. |
protocol |
string |
'asset' |
The protocol to use. Defaults to asset. You only need to set this when using a custom protocol. |
Returns
string
the URL that can be used as source on the webview.
Example
import { appDataDir, join } from '@tauri-apps/api/path';
import { convertFileSrc } from '@tauri-apps/api/core';
const appDataDirPath = await appDataDir();
const filePath = await join(appDataDirPath, 'assets/video.mp4');
const assetUrl = convertFileSrc(filePath);
const video = document.getElementById('my-video');
const source = document.createElement('source');
source.type = 'video/mp4';
source.src = assetUrl;
video.appendChild(source);
video.load();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L289
invoke()
function invoke<T>(
cmd,
args,
options?): Promise<T>
Sends a message to the backend.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
cmd |
string |
The command name. |
args |
InvokeArgs |
The optional arguments to pass to the command. |
options? |
InvokeOptions |
The request options. |
Returns
Promise<T>
A promise resolving or rejecting to the backend response.
Example
import { invoke } from '@tauri-apps/api/core';
await invoke('login', { user: 'tauri', password: 'poiwe3h4r5ip3yrhtew9ty' });
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L251
isTauri()
function isTauri(): boolean
Returns
boolean
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L337
requestPermissions()
function requestPermissions<T>(plugin): Promise<T>
Request permissions.
This should be used by plugin authors to wrap their actual implementation.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type |
|---|---|
plugin |
string |
Returns
Promise<T>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L218
transformCallback()
function transformCallback<T>(callback?, once?): number
Stores the callback in a known location, and returns an identifier that can be passed to the backend. The backend uses the identifier to eval() the callback.
Type Parameters
| Type Parameter | Default type |
|---|---|
T |
unknown |
Parameters
| Parameter | Type | Default value |
|---|---|---|
callback? |
(response) => void |
undefined |
once? |
boolean |
false |
Returns
number
An unique identifier associated with the callback function.
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L69
dpi
Classes
LogicalPosition
A position represented in logical pixels. For an explanation of what logical pixels are, see description of LogicalSize.
Since
2.0.0
Constructors
new LogicalPosition()
new LogicalPosition(x, y): LogicalPosition
Parameters
| Parameter | Type |
|---|---|
x |
number |
y |
number |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L219
new LogicalPosition()
new LogicalPosition(object): LogicalPosition
Parameters
| Parameter | Type |
|---|---|
object |
object |
object.Logical |
object |
object.Logical.x |
number |
object.Logical.y |
number |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L220
new LogicalPosition()
new LogicalPosition(object): LogicalPosition
Parameters
| Parameter | Type |
|---|---|
object |
object |
object.x |
number |
object.y |
number |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L221
Properties
| Property | Modifier | Type | Default value | Defined in |
|---|---|---|---|---|
type |
readonly |
"Logical" |
'Logical' |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L215 |
x |
public |
number |
undefined |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L216 |
y |
public |
number |
undefined |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L217 |
Methods
__TAURI_TO_IPC_KEY__()
__TAURI_TO_IPC_KEY__(): object
Returns
object
| Name | Type | Defined in |
|---|---|---|
x |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L263 |
y |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L264 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L261
toJSON()
toJSON(): object
Returns
object
| Name | Type | Defined in |
|---|---|---|
x |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L263 |
y |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L264 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L268
toPhysical()
toPhysical(scaleFactor): PhysicalPosition
Converts the logical position to a physical one.
Parameters
| Parameter | Type |
|---|---|
scaleFactor |
number |
Returns
Example
import { LogicalPosition } from '@tauri-apps/api/dpi';
import { getCurrentWindow } from '@tauri-apps/api/window';
const appWindow = getCurrentWindow();
const factor = await appWindow.scaleFactor();
const position = new LogicalPosition(400, 500);
const physical = position.toPhysical(factor);
Since
2.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L257
LogicalSize
A size represented in logical pixels. Logical pixels are scaled according to the window’s DPI scale. Most browser APIs (i.e. MouseEvent’s clientX) will return logical pixels.
For logical-pixel-based position, see LogicalPosition.
Since
2.0.0
Constructors
new LogicalSize()
new LogicalSize(width, height): LogicalSize
Parameters
| Parameter | Type |
|---|---|
width |
number |
height |
number |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L21
new LogicalSize()
new LogicalSize(object): LogicalSize
Parameters
| Parameter | Type |
|---|---|
object |
object |
object.Logical |
object |
object.Logical.height |
number |
object.Logical.width |
number |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L22
new LogicalSize()
new LogicalSize(object): LogicalSize
Parameters
| Parameter | Type |
|---|---|
object |
object |
object.height |
number |
object.width |
number |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L23
Properties
| Property | Modifier | Type | Default value | Defined in |
|---|---|---|---|---|
height |
public |
number |
undefined |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L19 |
type |
readonly |
"Logical" |
'Logical' |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L17 |
width |
public |
number |
undefined |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L18 |
Methods
__TAURI_TO_IPC_KEY__()
__TAURI_TO_IPC_KEY__(): object
Returns
object
| Name | Type | Defined in |
|---|---|---|
height |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L66 |
width |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L65 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L63
toJSON()
toJSON(): object
Returns
object
| Name | Type | Defined in |
|---|---|---|
height |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L66 |
width |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L65 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L70
toPhysical()
toPhysical(scaleFactor): PhysicalSize
Converts the logical size to a physical one.
Parameters
| Parameter | Type |
|---|---|
scaleFactor |
number |
Returns
Example
import { LogicalSize } from '@tauri-apps/api/dpi';
import { getCurrentWindow } from '@tauri-apps/api/window';
const appWindow = getCurrentWindow();
const factor = await appWindow.scaleFactor();
const size = new LogicalSize(400, 500);
const physical = size.toPhysical(factor);
Since
2.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L59
PhysicalPosition
A position represented in physical pixels.
For an explanation of what physical pixels are, see description of PhysicalSize.
Since
2.0.0
Constructors
new PhysicalPosition()
new PhysicalPosition(x, y): PhysicalPosition
Parameters
| Parameter | Type |
|---|---|
x |
number |
y |
number |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L286
new PhysicalPosition()
new PhysicalPosition(object): PhysicalPosition
Parameters
| Parameter | Type |
|---|---|
object |
object |
object.Physical |
object |
object.Physical.x |
number |
object.Physical.y |
number |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L287
new PhysicalPosition()
new PhysicalPosition(object): PhysicalPosition
Parameters
| Parameter | Type |
|---|---|
object |
object |
object.x |
number |
object.y |
number |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L288
Properties
| Property | Modifier | Type | Default value | Defined in |
|---|---|---|---|---|
type |
readonly |
"Physical" |
'Physical' |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L282 |
x |
public |
number |
undefined |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L283 |
y |
public |
number |
undefined |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L284 |
Methods
__TAURI_TO_IPC_KEY__()
__TAURI_TO_IPC_KEY__(): object
Returns
object
| Name | Type | Defined in |
|---|---|---|
x |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L330 |
y |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L331 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L328
toJSON()
toJSON(): object
Returns
object
| Name | Type | Defined in |
|---|---|---|
x |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L330 |
y |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L331 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L335
toLogical()
toLogical(scaleFactor): LogicalPosition
Converts the physical position to a logical one.
Parameters
| Parameter | Type |
|---|---|
scaleFactor |
number |
Returns
Example
import { PhysicalPosition } from '@tauri-apps/api/dpi';
import { getCurrentWindow } from '@tauri-apps/api/window';
const appWindow = getCurrentWindow();
const factor = await appWindow.scaleFactor();
const position = new PhysicalPosition(400, 500);
const physical = position.toLogical(factor);
Since
2.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L324
PhysicalSize
A size represented in physical pixels.
Physical pixels represent actual screen pixels, and are DPI-independent. For high-DPI windows, this means that any point in the window on the screen will have a different position in logical pixels LogicalSize.
For physical-pixel-based position, see PhysicalPosition.
Since
2.0.0
Constructors
new PhysicalSize()
new PhysicalSize(width, height): PhysicalSize
Parameters
| Parameter | Type |
|---|---|
width |
number |
height |
number |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L92
new PhysicalSize()
new PhysicalSize(object): PhysicalSize
Parameters
| Parameter | Type |
|---|---|
object |
object |
object.Physical |
object |
object.Physical.height |
number |
object.Physical.width |
number |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L93
new PhysicalSize()
new PhysicalSize(object): PhysicalSize
Parameters
| Parameter | Type |
|---|---|
object |
object |
object.height |
number |
object.width |
number |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L94
Properties
| Property | Modifier | Type | Default value | Defined in |
|---|---|---|---|---|
height |
public |
number |
undefined |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L90 |
type |
readonly |
"Physical" |
'Physical' |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L88 |
width |
public |
number |
undefined |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L89 |
Methods
__TAURI_TO_IPC_KEY__()
__TAURI_TO_IPC_KEY__(): object
Returns
object
| Name | Type | Defined in |
|---|---|---|
height |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L133 |
width |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L132 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L130
toJSON()
toJSON(): object
Returns
object
| Name | Type | Defined in |
|---|---|---|
height |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L133 |
width |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L132 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L137
toLogical()
toLogical(scaleFactor): LogicalSize
Converts the physical size to a logical one.
Parameters
| Parameter | Type |
|---|---|
scaleFactor |
number |
Returns
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const appWindow = getCurrentWindow();
const factor = await appWindow.scaleFactor();
const size = await appWindow.innerSize(); // PhysicalSize
const logical = size.toLogical(factor);
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L126
Position
A position represented either in physical or in logical pixels.
This type is basically a union type of LogicalSize and PhysicalSize but comes in handy when using tauri::Position in Rust as an argument to a command, as this class automatically serializes into a valid format so it can be deserialized correctly into tauri::Position
So instead of
import { invoke } from '@tauri-apps/api/core';
import { LogicalPosition, PhysicalPosition } from '@tauri-apps/api/dpi';
const position: LogicalPosition | PhysicalPosition = someFunction(); // where someFunction returns either LogicalPosition or PhysicalPosition
const validPosition = position instanceof LogicalPosition
? { Logical: { x: position.x, y: position.y } }
: { Physical: { x: position.x, y: position.y } }
await invoke("do_something_with_position", { position: validPosition });
You can just use Position
import { invoke } from '@tauri-apps/api/core';
import { LogicalPosition, PhysicalPosition, Position } from '@tauri-apps/api/dpi';
const position: LogicalPosition | PhysicalPosition = someFunction(); // where someFunction returns either LogicalPosition or PhysicalPosition
const validPosition = new Position(position);
await invoke("do_something_with_position", { position: validPosition });
Since
2.1.0
Constructors
new Position()
new Position(position): Position
Parameters
| Parameter | Type |
|---|---|
position |
LogicalPosition | PhysicalPosition |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L375
Properties
| Property | Type | Defined in |
|---|---|---|
position |
LogicalPosition | PhysicalPosition |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L373 |
Methods
__TAURI_TO_IPC_KEY__()
__TAURI_TO_IPC_KEY__(): object
Returns
object
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L391
toJSON()
toJSON(): object
Returns
object
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L400
toLogical()
toLogical(scaleFactor): LogicalPosition
Parameters
| Parameter | Type |
|---|---|
scaleFactor |
number |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L379
toPhysical()
toPhysical(scaleFactor): PhysicalPosition
Parameters
| Parameter | Type |
|---|---|
scaleFactor |
number |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L385
Size
A size represented either in physical or in logical pixels.
This type is basically a union type of LogicalSize and PhysicalSize but comes in handy when using tauri::Size in Rust as an argument to a command, as this class automatically serializes into a valid format so it can be deserialized correctly into tauri::Size
So instead of
import { invoke } from '@tauri-apps/api/core';
import { LogicalSize, PhysicalSize } from '@tauri-apps/api/dpi';
const size: LogicalSize | PhysicalSize = someFunction(); // where someFunction returns either LogicalSize or PhysicalSize
const validSize = size instanceof LogicalSize
? { Logical: { width: size.width, height: size.height } }
: { Physical: { width: size.width, height: size.height } }
await invoke("do_something_with_size", { size: validSize });
You can just use Size
import { invoke } from '@tauri-apps/api/core';
import { LogicalSize, PhysicalSize, Size } from '@tauri-apps/api/dpi';
const size: LogicalSize | PhysicalSize = someFunction(); // where someFunction returns either LogicalSize or PhysicalSize
const validSize = new Size(size);
await invoke("do_something_with_size", { size: validSize });
Since
2.1.0
Constructors
new Size()
new Size(size): Size
Parameters
| Parameter | Type |
|---|---|
size |
LogicalSize | PhysicalSize |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L177
Properties
| Property | Type | Defined in |
|---|---|---|
size |
LogicalSize | PhysicalSize |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L175 |
Methods
__TAURI_TO_IPC_KEY__()
__TAURI_TO_IPC_KEY__(): object
Returns
object
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L193
toJSON()
toJSON(): object
Returns
object
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L202
toLogical()
toLogical(scaleFactor): LogicalSize
Parameters
| Parameter | Type |
|---|---|
scaleFactor |
number |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L181
toPhysical()
toPhysical(scaleFactor): PhysicalSize
Parameters
| Parameter | Type |
|---|---|
scaleFactor |
number |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/dpi.ts#L187
event
The event system allows you to emit events to the backend and listen to events from it.
This package is also accessible with window.__TAURI__.event when app.withGlobalTauri in tauri.conf.json is set to true.
Enumerations
TauriEvent
Since
1.1.0
Enumeration Members
DRAG_DROP
DRAG_DROP: "tauri://drag-drop";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L73
DRAG_ENTER
DRAG_ENTER: "tauri://drag-enter";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L71
DRAG_LEAVE
DRAG_LEAVE: "tauri://drag-leave";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L74
DRAG_OVER
DRAG_OVER: "tauri://drag-over";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L72
WEBVIEW_CREATED
WEBVIEW_CREATED: "tauri://webview-created";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L70
WINDOW_BLUR
WINDOW_BLUR: "tauri://blur";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L64
WINDOW_CLOSE_REQUESTED
WINDOW_CLOSE_REQUESTED: "tauri://close-requested";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L61
WINDOW_CREATED
WINDOW_CREATED: "tauri://window-created";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L67
WINDOW_DESTROYED
WINDOW_DESTROYED: "tauri://destroyed";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L62
WINDOW_FOCUS
WINDOW_FOCUS: "tauri://focus";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L63
WINDOW_MOVED
WINDOW_MOVED: "tauri://move";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L60
WINDOW_RESIZED
WINDOW_RESIZED: "tauri://resize";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L59
WINDOW_RESUMED
WINDOW_RESUMED: "tauri://resumed";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L69
WINDOW_SCALE_FACTOR_CHANGED
WINDOW_SCALE_FACTOR_CHANGED: "tauri://scale-change";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L65
WINDOW_SUSPENDED
WINDOW_SUSPENDED: "tauri://suspended";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L68
WINDOW_THEME_CHANGED
WINDOW_THEME_CHANGED: "tauri://theme-changed";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L66
Interfaces
Event<T>
Type Parameters
| Type Parameter |
|---|
T |
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
event |
EventName |
Event name | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L32 |
id |
number |
Event identifier used to unlisten | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L34 |
payload |
T |
Event payload | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L36 |
Options
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
target? |
string | EventTarget |
The event target to listen to, defaults to { kind: 'Any' }, see EventTarget. If a string is provided, EventTarget.AnyLabel is used. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L52 |
Type Aliases
EventCallback()<T>
type EventCallback<T>: (event) => void;
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type |
|---|---|
event |
Event<T> |
Returns
void
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L39
EventName
type EventName: `${TauriEvent}` | string & Record<never, never>;
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L44
EventTarget
type EventTarget:
| object
| object
| object
| object
| object
| object;
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L22
UnlistenFn()
type UnlistenFn: () => void;
Returns
void
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L42
Functions
emit()
function emit<T>(event, payload?): Promise<void>
Emits an event to all targets.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
event |
string |
Event name. Must include only alphanumeric characters, -, /, : and _. |
payload? |
T |
Event payload. |
Returns
Promise<void>
Example
import { emit } from '@tauri-apps/api/event';
await emit('frontend-loaded', { loggedIn: true, token: 'authToken' });
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L188
emitTo()
function emitTo<T>(
target,
event,
payload?): Promise<void>
Emits an event to all targets matching the given target.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
target |
string | EventTarget |
Label of the target Window/Webview/WebviewWindow or raw EventTarget object. |
event |
string |
Event name. Must include only alphanumeric characters, -, /, : and _. |
payload? |
T |
Event payload. |
Returns
Promise<void>
Example
import { emitTo } from '@tauri-apps/api/event';
await emitTo('main', 'frontend-loaded', { loggedIn: true, token: 'authToken' });
Since
2.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L210
listen()
function listen<T>(
event,
handler,
options?): Promise<UnlistenFn>
Listen to an emitted event to any target.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
event |
EventName |
Event name. Must include only alphanumeric characters, -, /, : and _. |
handler |
EventCallback<T> |
Event handler callback. |
options? |
Options |
Event listening options. |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { listen } from '@tauri-apps/api/event';
const unlisten = await listen<string>('error', (event) => {
console.log(`Got error, payload: ${event.payload}`);
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L115
once()
function once<T>(
event,
handler,
options?): Promise<UnlistenFn>
Listens once to an emitted event to any target.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
event |
EventName |
Event name. Must include only alphanumeric characters, -, /, : and _. |
handler |
EventCallback<T> |
Event handler callback. |
options? |
Options |
Event listening options. |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { once } from '@tauri-apps/api/event';
interface LoadedPayload {
loggedIn: boolean,
token: string
}
const unlisten = await once<LoadedPayload>('loaded', (event) => {
console.log(`App is loaded, loggedIn: ${event.payload.loggedIn}, token: ${event.payload.token}`);
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/event.ts#L159
image
Classes
Image
An RGBA Image in row-major order from top to bottom.
Extends
Accessors
rid
get rid(): number
Returns
number
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L318
Methods
close()
close(): Promise<void>
Destroys and cleans up this resource from memory. You should not call any method on this object anymore and should drop any reference to it.
Returns
Promise<void>
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L330
rgba()
rgba(): Promise<Uint8Array>
Returns the RGBA data for this image, in row-major order from top to bottom.
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/image.ts#L89
size()
size(): Promise<ImageSize>
Returns the size of this image.
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/image.ts#L96
fromBytes()
static fromBytes(bytes): Promise<Image>
Creates a new image using the provided bytes by inferring the file format. If the format is known, prefer [@link Image.fromPngBytes] or [@link Image.fromIcoBytes].
Only ico and png are supported (based on activated feature flag).
Note that you need the image-ico or image-png Cargo features to use this API. To enable it, change your Cargo.toml file:
[dependencies]
tauri = { version = "...", features = ["...", "image-png"] }
Parameters
| Parameter | Type |
|---|---|
bytes |
Uint8Array | number[] | ArrayBuffer |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/image.ts#L62
fromPath()
static fromPath(path): Promise<Image>
Creates a new image using the provided path.
Only ico and png are supported (based on activated feature flag).
Note that you need the image-ico or image-png Cargo features to use this API. To enable it, change your Cargo.toml file:
[dependencies]
tauri = { version = "...", features = ["...", "image-png"] }
Parameters
| Parameter | Type |
|---|---|
path |
string |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/image.ts#L82
new()
static new(
rgba,
width,
height): Promise<Image>
Creates a new Image using RGBA data, in row-major order from top to bottom, and with specified width and height.
Parameters
| Parameter | Type |
|---|---|
rgba |
Uint8Array | number[] | ArrayBuffer |
width |
number |
height |
number |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/image.ts#L37
Interfaces
ImageSize
Properties
| Property | Type | Defined in |
|---|---|---|
height |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/image.ts#L13 |
width |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/image.ts#L11 |
Type Aliases
MenuIcon
type MenuIcon:
| NativeIcon
| string
| Image
| Uint8Array
| ArrayBuffer
| number[];
A type that represents an icon that can be used in menu items.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/image.ts#L17
Functions
transformImage()
function transformImage<T>(image): T
Transforms image from various types into a type acceptable by Rust.
See tauri::image::JsImage for more information. Note the API signature is not stable and might change.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type |
|---|---|
image |
| null | string | Uint8Array | number[] | ArrayBuffer | Image |
Returns
T
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/image.ts#L107
menu
Enumerations
NativeIcon
A native Icon to be used for the menu item
Platform-specific:
- Windows / Linux: Unsupported.
Enumeration Members
Add
Add: "Add";
An add item template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L19
Advanced
Advanced: "Advanced";
Advanced preferences toolbar icon for the preferences window.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L21
Bluetooth
Bluetooth: "Bluetooth";
A Bluetooth template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L23
Bookmarks
Bookmarks: "Bookmarks";
Bookmarks image suitable for a template.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L25
Caution
Caution: "Caution";
A caution image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L27
ColorPanel
ColorPanel: "ColorPanel";
A color panel toolbar icon.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L29
ColumnView
ColumnView: "ColumnView";
A column view mode template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L31
Computer
Computer: "Computer";
A computer icon.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L33
EnterFullScreen
EnterFullScreen: "EnterFullScreen";
An enter full-screen mode template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L35
Everyone
Everyone: "Everyone";
Permissions for all users.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L37
ExitFullScreen
ExitFullScreen: "ExitFullScreen";
An exit full-screen mode template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L39
FlowView
FlowView: "FlowView";
A cover flow view mode template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L41
Folder
Folder: "Folder";
A folder image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L43
FolderBurnable
FolderBurnable: "FolderBurnable";
A burnable folder icon.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L45
FolderSmart
FolderSmart: "FolderSmart";
A smart folder icon.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L47
FollowLinkFreestanding
FollowLinkFreestanding: "FollowLinkFreestanding";
A link template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L49
FontPanel
FontPanel: "FontPanel";
A font panel toolbar icon.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L51
GoLeft
GoLeft: "GoLeft";
A go back template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L53
GoRight
GoRight: "GoRight";
A go forward template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L55
Home
Home: "Home";
Home image suitable for a template.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L57
IChatTheater
IChatTheater: "IChatTheater";
An iChat Theater template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L59
IconView
IconView: "IconView";
An icon view mode template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L61
Info
Info: "Info";
An information toolbar icon.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L63
InvalidDataFreestanding
InvalidDataFreestanding: "InvalidDataFreestanding";
A template image used to denote invalid data.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L65
LeftFacingTriangle
LeftFacingTriangle: "LeftFacingTriangle";
A generic left-facing triangle template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L67
ListView
ListView: "ListView";
A list view mode template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L69
LockLocked
LockLocked: "LockLocked";
A locked padlock template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L71
LockUnlocked
LockUnlocked: "LockUnlocked";
An unlocked padlock template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L73
MenuMixedState
MenuMixedState: "MenuMixedState";
A horizontal dash, for use in menus.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L75
MenuOnState
MenuOnState: "MenuOnState";
A check mark template image, for use in menus.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L77
MobileMe
MobileMe: "MobileMe";
A MobileMe icon.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L79
MultipleDocuments
MultipleDocuments: "MultipleDocuments";
A drag image for multiple items.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L81
Network
Network: "Network";
A network icon.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L83
Path
Path: "Path";
A path button template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L85
PreferencesGeneral
PreferencesGeneral: "PreferencesGeneral";
General preferences toolbar icon for the preferences window.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L87
QuickLook
QuickLook: "QuickLook";
A Quick Look template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L89
Refresh
Refresh: "Refresh";
A refresh template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L93
RefreshFreestanding
RefreshFreestanding: "RefreshFreestanding";
A refresh template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L91
Remove
Remove: "Remove";
A remove item template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L95
RevealFreestanding
RevealFreestanding: "RevealFreestanding";
A reveal contents template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L97
RightFacingTriangle
RightFacingTriangle: "RightFacingTriangle";
A generic right-facing triangle template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L99
Share
Share: "Share";
A share view template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L101
Slideshow
Slideshow: "Slideshow";
A slideshow template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L103
SmartBadge
SmartBadge: "SmartBadge";
A badge for a smart item.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L105
StatusAvailable
StatusAvailable: "StatusAvailable";
Small green indicator, similar to iChat’s available image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L107
StatusNone
StatusNone: "StatusNone";
Small clear indicator.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L109
StatusPartiallyAvailable
StatusPartiallyAvailable: "StatusPartiallyAvailable";
Small yellow indicator, similar to iChat’s idle image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L111
StatusUnavailable
StatusUnavailable: "StatusUnavailable";
Small red indicator, similar to iChat’s unavailable image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L113
StopProgress
StopProgress: "StopProgress";
A stop progress button template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L117
StopProgressFreestanding
StopProgressFreestanding: "StopProgressFreestanding";
A stop progress template image.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L115
TrashEmpty
TrashEmpty: "TrashEmpty";
An image of the empty trash can.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L119
TrashFull
TrashFull: "TrashFull";
An image of the full trash can.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L121
User
User: "User";
Permissions for a single user.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L123
UserAccounts
UserAccounts: "UserAccounts";
User account toolbar icon for the preferences window.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L125
UserGroup
UserGroup: "UserGroup";
Permissions for a group of users.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L127
UserGuest
UserGuest: "UserGuest";
Permissions for guests.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L129
Classes
CheckMenuItem
A check menu item inside a Menu or Submenu and usually contains a text and a check mark or a similar toggle that corresponds to a checked and unchecked states.
Extends
MenuItemBase
Accessors
id
get id(): string
The id of this item.
Returns
string
Inherited from
MenuItemBase.id
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/base.ts#L128
rid
get rid(): number
Returns
number
Inherited from
MenuItemBase.rid
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L318
Methods
close()
close(): Promise<void>
Destroys and cleans up this resource from memory. You should not call any method on this object anymore and should drop any reference to it.
Returns
Promise<void>
Inherited from
MenuItemBase.close
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L330
isChecked()
isChecked(): Promise<boolean>
Returns whether this check menu item is checked or not.
Returns
Promise<boolean>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/checkMenuItem.ts#L71
isEnabled()
isEnabled(): Promise<boolean>
Returns whether this check menu item is enabled or not.
Returns
Promise<boolean>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/checkMenuItem.ts#L48
setAccelerator()
setAccelerator(accelerator): Promise<void>
Sets the accelerator for this check menu item.
Parameters
| Parameter | Type |
|---|---|
accelerator |
null | string |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/checkMenuItem.ts#L62
setChecked()
setChecked(checked): Promise<void>
Sets whether this check menu item is checked or not.
Parameters
| Parameter | Type |
|---|---|
checked |
boolean |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/checkMenuItem.ts#L76
setEnabled()
setEnabled(enabled): Promise<void>
Sets whether this check menu item is enabled or not.
Parameters
| Parameter | Type |
|---|---|
enabled |
boolean |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/checkMenuItem.ts#L53
setText()
setText(text): Promise<void>
Sets the text for this check menu item.
Parameters
| Parameter | Type |
|---|---|
text |
string |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/checkMenuItem.ts#L39
text()
text(): Promise<string>
Returns the text of this check menu item.
Returns
Promise<string>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/checkMenuItem.ts#L34
new()
static new(opts): Promise<CheckMenuItem>
Create a new check menu item.
Parameters
| Parameter | Type |
|---|---|
opts |
CheckMenuItemOptions |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/checkMenuItem.ts#L27
IconMenuItem
An icon menu item inside a Menu or Submenu and usually contains an icon and a text.
Extends
MenuItemBase
Accessors
id
get id(): string
The id of this item.
Returns
string
Inherited from
MenuItemBase.id
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/base.ts#L128
rid
get rid(): number
Returns
number
Inherited from
MenuItemBase.rid
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L318
Methods
close()
close(): Promise<void>
Destroys and cleans up this resource from memory. You should not call any method on this object anymore and should drop any reference to it.
Returns
Promise<void>
Inherited from
MenuItemBase.close
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L330
isEnabled()
isEnabled(): Promise<boolean>
Returns whether this icon menu item is enabled or not.
Returns
Promise<boolean>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L177
setAccelerator()
setAccelerator(accelerator): Promise<void>
Sets the accelerator for this icon menu item.
Parameters
| Parameter | Type |
|---|---|
accelerator |
null | string |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L191
setEnabled()
setEnabled(enabled): Promise<void>
Sets whether this icon menu item is enabled or not.
Parameters
| Parameter | Type |
|---|---|
enabled |
boolean |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L182
setIcon()
setIcon(icon): Promise<void>
Sets an icon for this icon menu item
Parameters
| Parameter | Type |
|---|---|
icon |
null | MenuIcon |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L200
setText()
setText(text): Promise<void>
Sets the text for this icon menu item.
Parameters
| Parameter | Type |
|---|---|
text |
string |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L168
text()
text(): Promise<string>
Returns the text of this icon menu item.
Returns
Promise<string>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L163
new()
static new(opts): Promise<IconMenuItem>
Create a new icon menu item.
Parameters
| Parameter | Type |
|---|---|
opts |
IconMenuItemOptions |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L158
Menu
A type that is either a menu bar on the window on Windows and Linux or as a global menu in the menubar on macOS.
Platform-specific:
Extends
MenuItemBase
Accessors
id
get id(): string
The id of this item.
Returns
string
Inherited from
MenuItemBase.id
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/base.ts#L128
rid
get rid(): number
Returns
number
Inherited from
MenuItemBase.rid
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L318
Methods
append()
append<T>(items): Promise<void>
Add a menu item to the end of this menu.
Platform-specific:
Type Parameters
| Type Parameter |
|---|
T extends | MenuItemOptions | MenuItem | SubmenuOptions | PredefinedMenuItemOptions | CheckMenuItemOptions | IconMenuItemOptions | PredefinedMenuItem | Submenu | CheckMenuItem | IconMenuItem |
Parameters
| Parameter | Type |
|---|---|
items |
T | T[] |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menu.ts#L73
close()
close(): Promise<void>
Destroys and cleans up this resource from memory. You should not call any method on this object anymore and should drop any reference to it.
Returns
Promise<void>
Inherited from
MenuItemBase.close
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L330
get()
get(id): Promise<
| null
| MenuItem
| PredefinedMenuItem
| Submenu
| CheckMenuItem
| IconMenuItem>
Retrieves the menu item matching the given identifier.
Parameters
| Parameter | Type |
|---|---|
id |
string |
Returns
Promise< | null | MenuItem | PredefinedMenuItem | Submenu | CheckMenuItem | IconMenuItem>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menu.ts#L196
insert()
insert<T>(items, position): Promise<void>
Add a menu item to the specified position in this menu.
Platform-specific:
Type Parameters
| Type Parameter |
|---|
T extends | MenuItemOptions | MenuItem | SubmenuOptions | PredefinedMenuItemOptions | CheckMenuItemOptions | IconMenuItemOptions | PredefinedMenuItem | Submenu | CheckMenuItem | IconMenuItem |
Parameters
| Parameter | Type |
|---|---|
items |
T | T[] |
position |
number |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menu.ts#L131
items()
items(): Promise<(
| MenuItem
| PredefinedMenuItem
| Submenu
| CheckMenuItem
| IconMenuItem)[]>
Returns a list of menu items that has been added to this menu.
Returns
Promise<( | MenuItem | PredefinedMenuItem | Submenu | CheckMenuItem | IconMenuItem)[]>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menu.ts#L184
popup()
popup(at?, window?): Promise<void>
Popup this menu as a context menu on the specified window.
Parameters
| Parameter | Type | Description |
|---|---|---|
at? |
LogicalPosition | PhysicalPosition | Position |
If a position is provided, it is relative to the window’s top-left corner. If there isn’t one provided, the menu will pop up at the current location of the mouse. |
window? |
Window |
- |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menu.ts#L219
prepend()
prepend<T>(items): Promise<void>
Add a menu item to the beginning of this menu.
Platform-specific:
Type Parameters
| Type Parameter |
|---|
T extends | MenuItemOptions | MenuItem | SubmenuOptions | PredefinedMenuItemOptions | CheckMenuItemOptions | IconMenuItemOptions | PredefinedMenuItem | Submenu | CheckMenuItem | IconMenuItem |
Parameters
| Parameter | Type |
|---|---|
items |
T | T[] |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menu.ts#L102
remove()
remove(item): Promise<void>
Remove a menu item from this menu.
Parameters
| Parameter | Type |
|---|---|
item |
| MenuItem | PredefinedMenuItem | Submenu | CheckMenuItem | IconMenuItem |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menu.ts#L155
removeAt()
removeAt(position): Promise<
| null
| MenuItem
| PredefinedMenuItem
| Submenu
| CheckMenuItem
| IconMenuItem>
Remove a menu item from this menu at the specified position.
Parameters
| Parameter | Type |
|---|---|
position |
number |
Returns
Promise< | null | MenuItem | PredefinedMenuItem | Submenu | CheckMenuItem | IconMenuItem>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menu.ts#L166
setAsAppMenu()
setAsAppMenu(): Promise<null | Menu>
Sets the app-wide menu and returns the previous one.
If a window was not created with an explicit menu or had one set explicitly, this menu will be assigned to it.
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menu.ts#L237
setAsWindowMenu()
setAsWindowMenu(window?): Promise<null | Menu>
Sets the window menu and returns the previous one.
Platform-specific:
- macOS: Unsupported. The menu on macOS is app-wide and not specific to one window, if you need to set it, use
Menu.setAsAppMenuinstead.
Parameters
| Parameter | Type |
|---|---|
window? |
Window |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menu.ts#L251
default()
static default(): Promise<Menu>
Create a default menu.
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menu.ts#L60
new()
static new(opts?): Promise<Menu>
Create a new menu.
Parameters
| Parameter | Type |
|---|---|
opts? |
MenuOptions |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menu.ts#L55
MenuItem
A menu item inside a Menu or Submenu and contains only text.
Extends
MenuItemBase
Accessors
id
get id(): string
The id of this item.
Returns
string
Inherited from
MenuItemBase.id
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/base.ts#L128
rid
get rid(): number
Returns
number
Inherited from
MenuItemBase.rid
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L318
Methods
close()
close(): Promise<void>
Destroys and cleans up this resource from memory. You should not call any method on this object anymore and should drop any reference to it.
Returns
Promise<void>
Inherited from
MenuItemBase.close
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L330
isEnabled()
isEnabled(): Promise<boolean>
Returns whether this menu item is enabled or not.
Returns
Promise<boolean>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menuItem.ts#L49
setAccelerator()
setAccelerator(accelerator): Promise<void>
Sets the accelerator for this menu item.
Parameters
| Parameter | Type |
|---|---|
accelerator |
null | string |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menuItem.ts#L63
setEnabled()
setEnabled(enabled): Promise<void>
Sets whether this menu item is enabled or not.
Parameters
| Parameter | Type |
|---|---|
enabled |
boolean |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menuItem.ts#L54
setText()
setText(text): Promise<void>
Sets the text for this menu item.
Parameters
| Parameter | Type |
|---|---|
text |
string |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menuItem.ts#L40
text()
text(): Promise<string>
Returns the text of this menu item.
Returns
Promise<string>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menuItem.ts#L35
new()
static new(opts): Promise<MenuItem>
Create a new menu item.
Parameters
| Parameter | Type |
|---|---|
opts |
MenuItemOptions |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menuItem.ts#L30
PredefinedMenuItem
A predefined (native) menu item which has a predefined behavior by the OS or by tauri.
Extends
MenuItemBase
Accessors
id
get id(): string
The id of this item.
Returns
string
Inherited from
MenuItemBase.id
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/base.ts#L128
rid
get rid(): number
Returns
number
Inherited from
MenuItemBase.rid
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L318
Methods
close()
close(): Promise<void>
Destroys and cleans up this resource from memory. You should not call any method on this object anymore and should drop any reference to it.
Returns
Promise<void>
Inherited from
MenuItemBase.close
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L330
setText()
setText(text): Promise<void>
Sets the text for this predefined menu item.
Parameters
| Parameter | Type |
|---|---|
text |
string |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/predefinedMenuItem.ts#L133
text()
text(): Promise<string>
Returns the text of this predefined menu item.
Returns
Promise<string>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/predefinedMenuItem.ts#L128
new()
static new(opts?): Promise<PredefinedMenuItem>
Create a new predefined menu item.
Parameters
| Parameter | Type |
|---|---|
opts? |
PredefinedMenuItemOptions |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/predefinedMenuItem.ts#L119
Submenu
A type that is a submenu inside a Menu or Submenu.
Extends
MenuItemBase
Accessors
id
get id(): string
The id of this item.
Returns
string
Inherited from
MenuItemBase.id
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/base.ts#L128
rid
get rid(): number
Returns
number
Inherited from
MenuItemBase.rid
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L318
Methods
append()
append<T>(items): Promise<void>
Add a menu item to the end of this submenu.
Platform-specific:
Type Parameters
| Type Parameter |
|---|
T extends | MenuItemOptions | MenuItem | SubmenuOptions | PredefinedMenuItemOptions | CheckMenuItemOptions | IconMenuItemOptions | PredefinedMenuItem | Submenu | CheckMenuItem | IconMenuItem |
Parameters
| Parameter | Type |
|---|---|
items |
T | T[] |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/submenu.ts#L106
close()
close(): Promise<void>
Destroys and cleans up this resource from memory. You should not call any method on this object anymore and should drop any reference to it.
Returns
Promise<void>
Inherited from
MenuItemBase.close
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L330
get()
get(id): Promise<
| null
| MenuItem
| PredefinedMenuItem
| Submenu
| CheckMenuItem
| IconMenuItem>
Retrieves the menu item matching the given identifier.
Parameters
| Parameter | Type |
|---|---|
id |
string |
Returns
Promise< | null | MenuItem | PredefinedMenuItem | Submenu | CheckMenuItem | IconMenuItem>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/submenu.ts#L229
insert()
insert<T>(items, position): Promise<void>
Add a menu item to the specified position in this submenu.
Platform-specific:
Type Parameters
| Type Parameter |
|---|
T extends | MenuItemOptions | MenuItem | SubmenuOptions | PredefinedMenuItemOptions | CheckMenuItemOptions | IconMenuItemOptions | PredefinedMenuItem | Submenu | CheckMenuItem | IconMenuItem |
Parameters
| Parameter | Type |
|---|---|
items |
T | T[] |
position |
number |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/submenu.ts#L164
isEnabled()
isEnabled(): Promise<boolean>
Returns whether this submenu is enabled or not.
Returns
Promise<boolean>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/submenu.ts#L86
items()
items(): Promise<(
| MenuItem
| PredefinedMenuItem
| Submenu
| CheckMenuItem
| IconMenuItem)[]>
Returns a list of menu items that has been added to this submenu.
Returns
Promise<( | MenuItem | PredefinedMenuItem | Submenu | CheckMenuItem | IconMenuItem)[]>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/submenu.ts#L217
popup()
popup(at?, window?): Promise<void>
Popup this submenu as a context menu on the specified window.
If the position, is provided, it is relative to the window’s top-left corner.
Parameters
| Parameter | Type |
|---|---|
at? |
LogicalPosition | PhysicalPosition |
window? |
Window |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/submenu.ts#L251
prepend()
prepend<T>(items): Promise<void>
Add a menu item to the beginning of this submenu.
Platform-specific:
Type Parameters
| Type Parameter |
|---|
T extends | MenuItemOptions | MenuItem | SubmenuOptions | PredefinedMenuItemOptions | CheckMenuItemOptions | IconMenuItemOptions | PredefinedMenuItem | Submenu | CheckMenuItem | IconMenuItem |
Parameters
| Parameter | Type |
|---|---|
items |
T | T[] |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/submenu.ts#L135
remove()
remove(item): Promise<void>
Remove a menu item from this submenu.
Parameters
| Parameter | Type |
|---|---|
item |
| MenuItem | PredefinedMenuItem | Submenu | CheckMenuItem | IconMenuItem |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/submenu.ts#L188
removeAt()
removeAt(position): Promise<
| null
| MenuItem
| PredefinedMenuItem
| Submenu
| CheckMenuItem
| IconMenuItem>
Remove a menu item from this submenu at the specified position.
Parameters
| Parameter | Type |
|---|---|
position |
number |
Returns
Promise< | null | MenuItem | PredefinedMenuItem | Submenu | CheckMenuItem | IconMenuItem>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/submenu.ts#L199
setAsHelpMenuForNSApp()
setAsHelpMenuForNSApp(): Promise<void>
Set this submenu as the Help menu for the application on macOS.
This will cause macOS to automatically add a search box to the menu.
If no menu is set as the Help menu, macOS will automatically use any menu which has a title matching the localized word “Help”.
Platform-specific:
- Windows / Linux: Unsupported.
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/submenu.ts#L291
setAsWindowsMenuForNSApp()
setAsWindowsMenuForNSApp(): Promise<void>
Set this submenu as the Window menu for the application on macOS.
This will cause macOS to automatically add window-switching items and certain other items to the menu.
Platform-specific:
- Windows / Linux: Unsupported.
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/submenu.ts#L273
setEnabled()
setEnabled(enabled): Promise<void>
Sets whether this submenu is enabled or not.
Parameters
| Parameter | Type |
|---|---|
enabled |
boolean |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/submenu.ts#L91
setIcon()
setIcon(icon): Promise<void>
Sets an icon for this submenu
Parameters
| Parameter | Type |
|---|---|
icon |
null | MenuIcon |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/submenu.ts#L298
setText()
setText(text): Promise<void>
Sets the text for this submenu.
Parameters
| Parameter | Type |
|---|---|
text |
string |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/submenu.ts#L77
text()
text(): Promise<string>
Returns the text of this submenu.
Returns
Promise<string>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/submenu.ts#L72
new()
static new(opts): Promise<Submenu>
Create a new submenu.
Parameters
| Parameter | Type |
|---|---|
opts |
SubmenuOptions |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/submenu.ts#L67
Interfaces
AboutMetadata
A metadata for the about predefined menu item.
Properties
CheckMenuItemOptions
Options for creating a new check menu item.
Extends
Properties
IconMenuItemOptions
Options for creating a new icon menu item.
Extends
Properties
| Property | Type | Description | Inherited from | Defined in |
|---|---|---|---|---|
accelerator? |
string |
Specify an accelerator for the new menu item. | MenuItemOptions.accelerator |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menuItem.ts#L17 |
action? |
(id: string) => void |
Specify a handler to be called when this menu item is activated. | MenuItemOptions.action |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menuItem.ts#L19 |
enabled? |
boolean |
Whether the new menu item is enabled or not. | MenuItemOptions.enabled |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menuItem.ts#L15 |
icon? |
MenuIcon |
Icon to be used for the new icon menu item. Note that you may need the image-ico or image-png Cargo features to use this API. To enable it, change your Cargo.toml file: [dependencies] tauri = { version = "...", features = ["...", "image-png"] } |
- | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts#L144 |
id? |
string |
Specify an id to use for the new menu item. | MenuItemOptions.id |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menuItem.ts#L11 |
text |
string |
The text of the new menu item. | MenuItemOptions.text |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menuItem.ts#L13 |
MenuItemOptions
Options for creating a new menu item.
Extended by
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
accelerator? |
string |
Specify an accelerator for the new menu item. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menuItem.ts#L17 |
action? |
(id: string) => void |
Specify a handler to be called when this menu item is activated. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menuItem.ts#L19 |
enabled? |
boolean |
Whether the new menu item is enabled or not. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menuItem.ts#L15 |
id? |
string |
Specify an id to use for the new menu item. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menuItem.ts#L11 |
text |
string |
The text of the new menu item. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menuItem.ts#L13 |
MenuOptions
Options for creating a new menu.
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
id? |
string |
Specify an id to use for the new menu. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menu.ts#L25 |
items? |
( | MenuItemOptions | MenuItem | SubmenuOptions | PredefinedMenuItemOptions | CheckMenuItemOptions | IconMenuItemOptions | PredefinedMenuItem | Submenu | CheckMenuItem | IconMenuItem)[] |
List of items to add to the new menu. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/menu.ts#L27 |
PredefinedMenuItemOptions
Options for creating a new predefined menu item.
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
item |
| object | "Separator" | "Copy" | "Cut" | "Paste" | "SelectAll" | "Undo" | "Redo" | "Minimize" | "Maximize" | "Fullscreen" | "Hide" | "HideOthers" | "ShowAll" | "CloseWindow" | "Quit" | "Services" | "BringAllToFront" |
The predefined item type | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/predefinedMenuItem.ts#L88 |
text? |
string |
The text of the new predefined menu item. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/predefinedMenuItem.ts#L86 |
Type Aliases
SubmenuOptions
type SubmenuOptions: Omit<MenuItemOptions, "accelerator" | "action"> & MenuOptions & object;
Type declaration
| Name | Type | Description | Defined in |
|---|---|---|---|
icon |
MenuIcon |
Icon to be used for the submenu. Note: you may need the image-ico or image-png Cargo features to use this API. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/submenu.ts#L56 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/submenu.ts#L50
mocks
Interfaces
MockIPCOptions
Options for mockIPC.
Options
shouldMockEvents: If true, the listen and emit functions will be mocked, allowing you to test event handling without a real backend. This will consume any events emitted with the plugin:event prefix.
Since
2.7.0
Properties
| Property | Type | Defined in |
|---|---|---|
shouldMockEvents? |
boolean |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/mocks.ts#L24 |
Functions
clearMocks()
function clearMocks(): void
Clears mocked functions/data injected by the other functions in this module. When using a test runner that doesn’t provide a fresh window object for each test, calling this function will reset tauri specific properties.
Example
import { mockWindows, clearMocks } from "@tauri-apps/api/mocks"
afterEach(() => {
clearMocks()
})
test("mocked windows", () => {
mockWindows("main", "second", "third");
expect(window.__TAURI_INTERNALS__).toHaveProperty("metadata")
})
test("no mocked windows", () => {
expect(window.__TAURI_INTERNALS__).not.toHaveProperty("metadata")
})
Returns
void
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/mocks.ts#L316
mockConvertFileSrc()
function mockConvertFileSrc(osName): void
Mock convertFileSrc function
Parameters
| Parameter | Type | Description |
|---|---|---|
osName |
string |
The operating system to mock, can be one of linux, macos, or windows |
Returns
void
Example
import { mockConvertFileSrc } from "@tauri-apps/api/mocks";
import { convertFileSrc } from "@tauri-apps/api/core";
mockConvertFileSrc("windows")
const url = convertFileSrc("C:\\Users\\user\\file.txt")
Since
1.6.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/mocks.ts#L277
mockIPC()
function mockIPC(cb, options?): void
Intercepts all IPC requests with the given mock handler.
This function can be used when testing tauri frontend applications or when running the frontend in a Node.js context during static site generation.
Examples
Testing setup using Vitest:
import { mockIPC, clearMocks } from "@tauri-apps/api/mocks"
import { invoke } from "@tauri-apps/api/core"
afterEach(() => {
clearMocks()
})
test("mocked command", () => {
mockIPC((cmd, payload) => {
switch (cmd) {
case "add":
return (payload.a as number) + (payload.b as number);
default:
break;
}
});
expect(invoke('add', { a: 12, b: 15 })).resolves.toBe(27);
})
The callback function can also return a Promise:
import { mockIPC, clearMocks } from "@tauri-apps/api/mocks"
import { invoke } from "@tauri-apps/api/core"
afterEach(() => {
clearMocks()
})
test("mocked command", () => {
mockIPC((cmd, payload) => {
if(cmd === "get_data") {
return fetch("https://example.com/data.json")
.then((response) => response.json())
}
});
expect(invoke('get_data')).resolves.toBe({ foo: 'bar' });
})
listen can also be mocked with direct calls to the emit function. This functionality is opt-in via the shouldMockEvents option:
import { mockIPC, clearMocks } from "@tauri-apps/api/mocks"
import { emit, listen } from "@tauri-apps/api/event"
afterEach(() => {
clearMocks()
})
test("mocked event", () => {
mockIPC(() => {}, { shouldMockEvents: true }); // enable event mocking
const eventHandler = vi.fn();
listen('test-event', eventHandler); // typically in component setup or similar
emit('test-event', { foo: 'bar' });
expect(eventHandler).toHaveBeenCalledWith({
event: 'test-event',
payload: { foo: 'bar' }
});
})
emitTo is currently not supported by this mock implementation.
Parameters
| Parameter | Type |
|---|---|
cb |
(cmd, payload?) => unknown |
options? |
MockIPCOptions |
Returns
void
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/mocks.ts#L104
mockWindows()
function mockWindows(current, ..._additionalWindows): void
Mocks one or many window labels. In non-tauri context it is required to call this function before using the @tauri-apps/api/window module.
This function only mocks the presence of windows, window properties (e.g. width and height) can be mocked like regular IPC calls using the mockIPC function.
Examples
import { mockWindows } from "@tauri-apps/api/mocks";
import { getCurrentWindow } from "@tauri-apps/api/window";
mockWindows("main", "second", "third");
const win = getCurrentWindow();
win.label // "main"
import { mockWindows } from "@tauri-apps/api/mocks";
mockWindows("main", "second", "third");
mockIPC((cmd, args) => {
if (cmd === "plugin:event|emit") {
console.log('emit event', args?.event, args?.payload);
}
});
const { emit } = await import("@tauri-apps/api/event");
await emit('loaded'); // this will cause the mocked IPC handler to log to the console.
Parameters
| Parameter | Type | Description |
|---|---|---|
current |
string |
Label of window this JavaScript context is running in. |
…_additionalWindows |
string[] |
- |
Returns
void
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/mocks.ts#L248
path
The path module provides utilities for working with file and directory paths.
This package is also accessible with window.__TAURI__.path when app.withGlobalTauri in tauri.conf.json is set to true.
It is recommended to allowlist only the APIs you use for optimal bundle size and security.
Enumerations
BaseDirectory
Since
2.0.0
Enumeration Members
AppCache
AppCache: 16;
See
appCacheDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L83
AppConfig
AppConfig: 13;
See
appConfigDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L71
AppData
AppData: 14;
See
appDataDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L75
AppLocalData
AppLocalData: 15;
See
appLocalDataDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L79
AppLog
AppLog: 17;
See
appLogDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L87
Audio
Audio: 1;
See
audioDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L23
Cache
Cache: 2;
See
cacheDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L27
Config
Config: 3;
See
configDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L31
Data
Data: 4;
See
dataDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L35
Desktop
Desktop: 18;
See
desktopDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L91
Document
Document: 6;
See
documentDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L43
Download
Download: 7;
See
downloadDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L47
Executable
Executable: 19;
See
executableDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L95
Font
Font: 20;
See
fontDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L99
Home
Home: 21;
See
homeDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L103
LocalData
LocalData: 5;
See
localDataDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L39
Picture
Picture: 8;
See
pictureDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L51
Public
Public: 9;
See
publicDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L55
Resource
Resource: 11;
See
resourceDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L63
Runtime
Runtime: 22;
See
runtimeDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L107
Temp
Temp: 12;
See
tempDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L67
Template
Template: 23;
See
templateDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L111
Video
Video: 10;
See
videoDir for more information.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L59
Functions
appCacheDir()
function appCacheDir(): Promise<string>
Returns the path to the suggested directory for your app’s cache files. Resolves to ${cacheDir}/${bundleIdentifier}, where bundleIdentifier is the identifier value configured in tauri.conf.json.
Returns
Promise<string>
Example
import { appCacheDir } from '@tauri-apps/api/path';
const appCacheDirPath = await appCacheDir();
Since
1.2.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L176
appConfigDir()
function appConfigDir(): Promise<string>
Returns the path to the suggested directory for your app’s config files. Resolves to ${configDir}/${bundleIdentifier}, where bundleIdentifier is the identifier value configured in tauri.conf.json.
Returns
Promise<string>
Example
import { appConfigDir } from '@tauri-apps/api/path';
const appConfigDirPath = await appConfigDir();
Since
1.2.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L125
appDataDir()
function appDataDir(): Promise<string>
Returns the path to the suggested directory for your app’s data files. Resolves to ${dataDir}/${bundleIdentifier}, where bundleIdentifier is the identifier value configured in tauri.conf.json.
Returns
Promise<string>
Example
import { appDataDir } from '@tauri-apps/api/path';
const appDataDirPath = await appDataDir();
Since
1.2.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L142
appLocalDataDir()
function appLocalDataDir(): Promise<string>
Returns the path to the suggested directory for your app’s local data files. Resolves to ${localDataDir}/${bundleIdentifier}, where bundleIdentifier is the identifier value configured in tauri.conf.json.
Returns
Promise<string>
Example
import { appLocalDataDir } from '@tauri-apps/api/path';
const appLocalDataDirPath = await appLocalDataDir();
Since
1.2.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L159
appLogDir()
function appLogDir(): Promise<string>
Returns the path to the suggested directory for your app’s log files.
Platform-specific
- Linux: Resolves to
${configDir}/${bundleIdentifier}/logs. - macOS: Resolves to
${homeDir}/Library/Logs/{bundleIdentifier} - Windows: Resolves to
${configDir}/${bundleIdentifier}/logs.
Returns
Promise<string>
Example
import { appLogDir } from '@tauri-apps/api/path';
const appLogDirPath = await appLogDir();
Since
1.2.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L604
audioDir()
function audioDir(): Promise<string>
Returns the path to the user’s audio directory.
Platform-specific
- Linux: Resolves to
xdg-user-dirs’XDG_MUSIC_DIR. - macOS: Resolves to
$HOME/Music. - Windows: Resolves to
{FOLDERID_Music}.
Returns
Promise<string>
Example
import { audioDir } from '@tauri-apps/api/path';
const audioDirPath = await audioDir();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L198
basename()
function basename(path, ext?): Promise<string>
Returns the last portion of a path. Trailing directory separators are ignored.
Parameters
| Parameter | Type | Description |
|---|---|---|
path |
string |
- |
ext? |
string |
An optional file extension to be removed from the returned path. |
Returns
Promise<string>
Example
import { basename } from '@tauri-apps/api/path';
const base = await basename('path/to/app.conf');
assert(base === 'app.conf');
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L734
cacheDir()
function cacheDir(): Promise<string>
Returns the path to the user’s cache directory.
Platform-specific
- Linux: Resolves to
$XDG_CACHE_HOMEor$HOME/.cache. - macOS: Resolves to
$HOME/Library/Caches. - Windows: Resolves to
{FOLDERID_LocalAppData}.
Returns
Promise<string>
Example
import { cacheDir } from '@tauri-apps/api/path';
const cacheDirPath = await cacheDir();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L220
configDir()
function configDir(): Promise<string>
Returns the path to the user’s config directory.
Platform-specific
- Linux: Resolves to
$XDG_CONFIG_HOMEor$HOME/.config. - macOS: Resolves to
$HOME/Library/Application Support. - Windows: Resolves to
{FOLDERID_RoamingAppData}.
Returns
Promise<string>
Example
import { configDir } from '@tauri-apps/api/path';
const configDirPath = await configDir();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L242
dataDir()
function dataDir(): Promise<string>
Returns the path to the user’s data directory.
Platform-specific
- Linux: Resolves to
$XDG_DATA_HOMEor$HOME/.local/share. - macOS: Resolves to
$HOME/Library/Application Support. - Windows: Resolves to
{FOLDERID_RoamingAppData}.
Returns
Promise<string>
Example
import { dataDir } from '@tauri-apps/api/path';
const dataDirPath = await dataDir();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L264
delimiter()
function delimiter(): string
Returns the platform-specific path segment delimiter:
;on Windows:on POSIX
Returns
string
Since
2.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L644
desktopDir()
function desktopDir(): Promise<string>
Returns the path to the user’s desktop directory.
Platform-specific
- Linux: Resolves to
xdg-user-dirs’XDG_DESKTOP_DIR. - macOS: Resolves to
$HOME/Desktop. - Windows: Resolves to
{FOLDERID_Desktop}.
Returns
Promise<string>
Example
import { desktopDir } from '@tauri-apps/api/path';
const desktopPath = await desktopDir();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L286
dirname()
function dirname(path): Promise<string>
Returns the parent directory of a given path. Trailing directory separators are ignored.
Parameters
| Parameter | Type |
|---|---|
path |
string |
Returns
Promise<string>
Example
import { dirname } from '@tauri-apps/api/path';
const dir = await dirname('/path/to/somedir/');
assert(dir === '/path/to');
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L703
documentDir()
function documentDir(): Promise<string>
Returns the path to the user’s document directory.
Returns
Promise<string>
Example
import { documentDir } from '@tauri-apps/api/path';
const documentDirPath = await documentDir();
Platform-specific
- Linux: Resolves to
xdg-user-dirs’XDG_DOCUMENTS_DIR. - macOS: Resolves to
$HOME/Documents. - Windows: Resolves to
{FOLDERID_Documents}.
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L308
downloadDir()
function downloadDir(): Promise<string>
Returns the path to the user’s download directory.
Platform-specific
- Linux: Resolves to
xdg-user-dirs’XDG_DOWNLOAD_DIR. - macOS: Resolves to
$HOME/Downloads. - Windows: Resolves to
{FOLDERID_Downloads}.
Returns
Promise<string>
Example
import { downloadDir } from '@tauri-apps/api/path';
const downloadDirPath = await downloadDir();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L330
executableDir()
function executableDir(): Promise<string>
Returns the path to the user’s executable directory.
Platform-specific
- Linux: Resolves to
$XDG_BIN_HOME/../binor$XDG_DATA_HOME/../binor$HOME/.local/bin. - macOS: Not supported.
- Windows: Not supported.
Returns
Promise<string>
Example
import { executableDir } from '@tauri-apps/api/path';
const executableDirPath = await executableDir();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L352
extname()
function extname(path): Promise<string>
Returns the extension of the path.
Parameters
| Parameter | Type |
|---|---|
path |
string |
Returns
Promise<string>
Example
import { extname } from '@tauri-apps/api/path';
const ext = await extname('/path/to/file.html');
assert(ext === 'html');
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L718
fontDir()
function fontDir(): Promise<string>
Returns the path to the user’s font directory.
Platform-specific
- Linux: Resolves to
$XDG_DATA_HOME/fontsor$HOME/.local/share/fonts. - macOS: Resolves to
$HOME/Library/Fonts. - Windows: Not supported.
Returns
Promise<string>
Example
import { fontDir } from '@tauri-apps/api/path';
const fontDirPath = await fontDir();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L374
homeDir()
function homeDir(): Promise<string>
Returns the path to the user’s home directory.
Platform-specific
- Linux: Resolves to
$HOME. - macOS: Resolves to
$HOME. - Windows: Resolves to
{FOLDERID_Profile}.
Returns
Promise<string>
Example
import { homeDir } from '@tauri-apps/api/path';
const homeDirPath = await homeDir();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L396
isAbsolute()
function isAbsolute(path): Promise<boolean>
Returns whether the path is absolute or not.
Parameters
| Parameter | Type |
|---|---|
path |
string |
Returns
Promise<boolean>
Example
import { isAbsolute } from '@tauri-apps/api/path';
assert(await isAbsolute('/home/tauri'));
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L748
join()
function join(...paths): Promise<string>
Joins all given path segments together using the platform-specific separator as a delimiter, then normalizes the resulting path.
Parameters
| Parameter | Type |
|---|---|
…paths |
string[] |
Returns
Promise<string>
Example
import { join, appDataDir } from '@tauri-apps/api/path';
const appDataDirPath = await appDataDir();
const path = await join(appDataDirPath, 'users', 'tauri', 'avatar.png');
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L688
localDataDir()
function localDataDir(): Promise<string>
Returns the path to the user’s local data directory.
Platform-specific
- Linux: Resolves to
$XDG_DATA_HOMEor$HOME/.local/share. - macOS: Resolves to
$HOME/Library/Application Support. - Windows: Resolves to
{FOLDERID_LocalAppData}.
Returns
Promise<string>
Example
import { localDataDir } from '@tauri-apps/api/path';
const localDataDirPath = await localDataDir();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L418
normalize()
function normalize(path): Promise<string>
Normalizes the given path, resolving '..' and '.' segments and resolve symbolic links.
Parameters
| Parameter | Type |
|---|---|
path |
string |
Returns
Promise<string>
Example
import { normalize, appDataDir } from '@tauri-apps/api/path';
const appDataDirPath = await appDataDir();
const path = await normalize(`${appDataDirPath}/../users/tauri/avatar.png`);
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L673
pictureDir()
function pictureDir(): Promise<string>
Returns the path to the user’s picture directory.
Platform-specific
- Linux: Resolves to
xdg-user-dirs’XDG_PICTURES_DIR. - macOS: Resolves to
$HOME/Pictures. - Windows: Resolves to
{FOLDERID_Pictures}.
Returns
Promise<string>
Example
import { pictureDir } from '@tauri-apps/api/path';
const pictureDirPath = await pictureDir();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L440
publicDir()
function publicDir(): Promise<string>
Returns the path to the user’s public directory.
Platform-specific
- Linux: Resolves to
xdg-user-dirs’XDG_PUBLICSHARE_DIR. - macOS: Resolves to
$HOME/Public. - Windows: Resolves to
{FOLDERID_Public}.
Returns
Promise<string>
Example
import { publicDir } from '@tauri-apps/api/path';
const publicDirPath = await publicDir();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L462
resolve()
function resolve(...paths): Promise<string>
Resolves a sequence of paths or path segments into an absolute path.
Parameters
| Parameter | Type |
|---|---|
…paths |
string[] |
Returns
Promise<string>
Example
import { resolve, appDataDir } from '@tauri-apps/api/path';
const appDataDirPath = await appDataDir();
const path = await resolve(appDataDirPath, '..', 'users', 'tauri', 'avatar.png');
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L658
resolveResource()
function resolveResource(resourcePath): Promise<string>
Resolve the path to a resource file.
Parameters
| Parameter | Type | Description |
|---|---|---|
resourcePath |
string |
The path to the resource. Must follow the same syntax as defined in tauri.conf.json > bundle > resources, i.e. keeping subfolders and parent dir components (../). |
Returns
Promise<string>
The full path to the resource.
Example
import { resolveResource } from '@tauri-apps/api/path';
const resourcePath = await resolveResource('script.sh');
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L515
resourceDir()
function resourceDir(): Promise<string>
Returns the path to the application’s resource directory. To resolve a resource path, see resolveResource.
Platform-specific
Although we provide the exact path where this function resolves to, this is not a contract and things might change in the future
- Windows: Resolves to the directory that contains the main executable.
- Linux: When running in an AppImage, the
APPDIRvariable will be set to the mounted location of the app, and the resource dir will be${APPDIR}/usr/lib/${exe_name}. If not running in an AppImage, the path is/usr/lib/${exe_name}. When running the app fromsrc-tauri/target/(debug|release)/, the path is${exe_dir}/../lib/${exe_name}. - macOS: Resolves to
${exe_dir}/../Resources(inside .app). - iOS: Resolves to
${exe_dir}/assets. - Android: Currently the resources are stored in the APK as assets so it’s not a normal file system path, we return a special URI prefix
asset://localhost/here that can be used with the file system plugin,
Returns
Promise<string>
Example
import { resourceDir } from '@tauri-apps/api/path';
const resourceDirPath = await resourceDir();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L495
runtimeDir()
function runtimeDir(): Promise<string>
Returns the path to the user’s runtime directory.
Platform-specific
- Linux: Resolves to
$XDG_RUNTIME_DIR. - macOS: Not supported.
- Windows: Not supported.
Returns
Promise<string>
Example
import { runtimeDir } from '@tauri-apps/api/path';
const runtimeDirPath = await runtimeDir();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L538
sep()
function sep(): string
Returns the platform-specific path segment separator:
\on Windows/on POSIX
Returns
string
Since
2.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L633
tempDir()
function tempDir(): Promise<string>
Returns a temporary directory.
Returns
Promise<string>
Example
import { tempDir } from '@tauri-apps/api/path';
const temp = await tempDir();
Since
2.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L620
templateDir()
function templateDir(): Promise<string>
Returns the path to the user’s template directory.
Platform-specific
- Linux: Resolves to
xdg-user-dirs’XDG_TEMPLATES_DIR. - macOS: Not supported.
- Windows: Resolves to
{FOLDERID_Templates}.
Returns
Promise<string>
Example
import { templateDir } from '@tauri-apps/api/path';
const templateDirPath = await templateDir();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L560
videoDir()
function videoDir(): Promise<string>
Returns the path to the user’s video directory.
Platform-specific
- Linux: Resolves to
xdg-user-dirs’XDG_VIDEOS_DIR. - macOS: Resolves to
$HOME/Movies. - Windows: Resolves to
{FOLDERID_Videos}.
Returns
Promise<string>
Example
import { videoDir } from '@tauri-apps/api/path';
const videoDirPath = await videoDir();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/path.ts#L582
tray
Classes
TrayIcon
Tray icon class and associated methods. This type constructor is private, instead, you should use the static method TrayIcon.new.
Warning
Unlike Rust, javascript does not have any way to run cleanup code when an object is being removed by garbage collection, but this tray icon will be cleaned up when the tauri app exists, however if you want to cleanup this object early, you need to call TrayIcon.close.
Example
import { TrayIcon } from '@tauri-apps/api/tray';
const tray = await TrayIcon.new({ tooltip: 'awesome tray tooltip' });
tray.set_tooltip('new tooltip');
Extends
Properties
| Property | Modifier | Type | Description | Defined in |
|---|---|---|---|---|
id |
public |
string |
The id associated with this tray icon. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L160 |
Accessors
rid
get rid(): number
Returns
number
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L318
Methods
close()
close(): Promise<void>
Destroys and cleans up this resource from memory. You should not call any method on this object anymore and should drop any reference to it.
Returns
Promise<void>
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/core.ts#L330
setIcon()
setIcon(icon): Promise<void>
Sets a new tray icon. If null is provided, it will remove the icon.
Note that you may need the image-ico or image-png Cargo features to use this API. To enable it, change your Cargo.toml file:
[dependencies]
tauri = { version = "...", features = ["...", "image-png"] }
Parameters
| Parameter | Type |
|---|---|
icon |
| null | string | Uint8Array | number[] | ArrayBuffer | Image |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L224
setIconAsTemplate()
setIconAsTemplate(asTemplate): Promise<void>
Sets the current icon as a template. macOS only
Parameters
| Parameter | Type |
|---|---|
asTemplate |
boolean |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L292
setIconWithAsTemplate()
setIconWithAsTemplate(icon, asTemplate): Promise<void>
Sets a new tray icon and template status atomically. macOS only.
Note that you may need the image-ico or image-png Cargo features to use this API. To enable it, change your Cargo.toml file:
[dependencies]
tauri = { version = "...", features = ["...", "image-png"] }
Parameters
| Parameter | Type |
|---|---|
icon |
| null | string | Uint8Array | number[] | ArrayBuffer | Image |
asTemplate |
boolean |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L309
setMenu()
setMenu(menu): Promise<void>
Sets a new tray menu.
Platform-specific:
- Linux: once a menu is set it cannot be removed so
nullhas no effect
Parameters
| Parameter | Type |
|---|---|
menu |
null | Submenu | Menu |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L241
setMenuOnLeftClick()
setMenuOnLeftClick(onLeft): Promise<void>
Disable or enable showing the tray menu on left click.
Platform-specific:
- Linux: Unsupported.
Parameters
| Parameter | Type |
|---|---|
onLeft |
boolean |
Returns
Promise<void>
Deprecated
use TrayIcon.setShowMenuOnLeftClick instead.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L333
setShowMenuOnLeftClick()
setShowMenuOnLeftClick(onLeft): Promise<void>
Disable or enable showing the tray menu on left click.
Platform-specific:
- Linux: Unsupported.
Parameters
| Parameter | Type |
|---|---|
onLeft |
boolean |
Returns
Promise<void>
Since
2.2.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L349
setTempDirPath()
setTempDirPath(path): Promise<void>
Sets the tray icon temp dir path. Linux only.
On Linux, we need to write the icon to the disk and usually it will be $XDG_RUNTIME_DIR/tray-icon or $TEMP/tray-icon.
Parameters
| Parameter | Type |
|---|---|
path |
null | string |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L287
setTitle()
setTitle(title): Promise<void>
Sets the tooltip for this tray icon.
Platform-specific:
- Linux: The title will not be shown unless there is an icon as well. The title is useful for numerical and other frequently updated information. In general, it shouldn’t be shown unless a user requests it as it can take up a significant amount of space on the user’s panel. This may not be shown in all visualizations.
- Windows: Unsupported
Parameters
| Parameter | Type |
|---|---|
title |
null | string |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L272
setTooltip()
setTooltip(tooltip): Promise<void>
Sets the tooltip for this tray icon.
Platform-specific:
- Linux: Unsupported
Parameters
| Parameter | Type |
|---|---|
tooltip |
null | string |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L256
setVisible()
setVisible(visible): Promise<void>
Show or hide this tray icon.
Parameters
| Parameter | Type |
|---|---|
visible |
boolean |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L277
getById()
static getById(id): Promise<null | TrayIcon>
Gets a tray icon using the provided id.
Parameters
| Parameter | Type |
|---|---|
id |
string |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L168
new()
static new(options?): Promise<TrayIcon>
Creates a new TrayIcon
Platform-specific:
- Linux: Sometimes the icon won’t be visible unless a menu is set. Setting an empty
Menuis enough.
Parameters
| Parameter | Type |
|---|---|
options? |
TrayIconOptions |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L192
removeById()
static removeById(id): Promise<void>
Removes a tray icon using the provided id from tauri’s internal state.
Note that this may cause the tray icon to disappear if it wasn’t cloned somewhere else or referenced by JS.
Parameters
| Parameter | Type |
|---|---|
id |
string |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L180
Interfaces
TrayIconOptions
TrayIcon creation options
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
action? |
(event: TrayIconEvent) => void |
A handler for an event on the tray icon. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L137 |
icon? |
| string | Uint8Array | number[] | ArrayBuffer | Image |
The tray icon which could be icon bytes or path to the icon file. Note that you may need the image-ico or image-png Cargo features to use this API. To enable it, change your Cargo.toml file: [dependencies] tauri = { version = "...", features = ["...", "image-png"] } |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L89 |
iconAsTemplate? |
boolean |
Use the icon as a template. macOS only. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L115 |
id? |
string |
The tray icon id. If undefined, a random one will be assigned | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L76 |
menu? |
Submenu | Menu |
The tray icon menu | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L78 |
menuOnLeftClick? |
boolean |
Whether to show the tray menu on left click or not, default is true. Platform-specific: - Linux: Unsupported. Deprecated use TrayIconOptions.showMenuOnLeftClick instead. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L125 |
showMenuOnLeftClick? |
boolean |
Whether to show the tray menu on left click or not, default is true. Platform-specific: - Linux: Unsupported. Since 2.2.0 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L135 |
tempDirPath? |
string |
The tray icon temp dir path. Linux only. On Linux, we need to write the icon to the disk and usually it will be $XDG_RUNTIME_DIR/tray-icon or $TEMP/tray-icon. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L111 |
title? |
string |
The tray title Platform-specific - Linux: The title will not be shown unless there is an icon as well. The title is useful for numerical and other frequently updated information. In general, it shouldn’t be shown unless a user requests it as it can take up a significant amount of space on the user’s panel. This may not be shown in all visualizations. - Windows: Unsupported. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L104 |
tooltip? |
string |
The tray icon tooltip | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L91 |
Type Aliases
MouseButton
type MouseButton: "Left" | "Right" | "Middle";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L11
MouseButtonState
type MouseButtonState: "Up" | "Down";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L10
TrayIconClickEvent
type TrayIconClickEvent: object;
Type declaration
| Name | Type | Description | Defined in |
|---|---|---|---|
button |
MouseButton |
Mouse button that triggered this event. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L35 |
buttonState |
MouseButtonState |
Mouse button state when this event was triggered. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L37 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L33
TrayIconEvent
type TrayIconEvent:
| TrayIconEventBase<"Click"> & TrayIconClickEvent
| TrayIconEventBase<"DoubleClick"> & Omit<TrayIconClickEvent, "buttonState">
| TrayIconEventBase<"Enter">
| TrayIconEventBase<"Move">
| TrayIconEventBase<"Leave">;
Describes a tray icon event.
Platform-specific:
- Linux: Unsupported. The event is not emitted even though the icon is shown, the icon will still show a context menu on right click.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L48
TrayIconEventBase<T>
type TrayIconEventBase<T>: object;
Type Parameters
| Type Parameter |
|---|
T extends TrayIconEventType |
Type declaration
| Name | Type | Description | Defined in |
|---|---|---|---|
id |
string |
Id of the tray icon which triggered this event. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L23 |
position |
PhysicalPosition |
Physical position of the click the triggered this event. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L25 |
rect |
object |
Position and size of the tray icon. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L27 |
rect.position |
PhysicalPosition |
- | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L28 |
rect.size |
PhysicalSize |
- | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L29 |
type |
T |
The tray icon event type | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L21 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L19
TrayIconEventType
type TrayIconEventType:
| "Click"
| "DoubleClick"
| "Enter"
| "Move"
| "Leave";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/tray.ts#L12
webview
Provides APIs to create webviews, communicate with other webviews and manipulate the current webview.
Webview events
Events can be listened to using Webview.listen:
import { getCurrentWebview } from "@tauri-apps/api/webview";
getCurrentWebview().listen("my-webview-event", ({ event, payload }) => { });
Classes
Webview
Create new webview or get a handle to an existing one.
Webviews are identified by a label a unique identifier that can be used to reference it later. It may only contain alphanumeric characters a-zA-Z plus the following special characters -, /, : and _.
Example
import { Window } from "@tauri-apps/api/window"
import { Webview } from "@tauri-apps/api/webview"
const appWindow = new Window('uniqueLabel');
appWindow.once('tauri://created', async function () {
// `new Webview` Should be called after the window is successfully created,
// or webview may not be attached to the window since window is not created yet.
// loading embedded asset:
const webview = new Webview(appWindow, 'theUniqueLabel', {
url: 'path/to/page.html',
// create a webview with specific logical position and size
x: 0,
y: 0,
width: 800,
height: 600,
});
// alternatively, load a remote URL:
const webview = new Webview(appWindow, 'theUniqueLabel', {
url: 'https://github.com/tauri-apps/tauri',
// create a webview with specific logical position and size
x: 0,
y: 0,
width: 800,
height: 600,
});
webview.once('tauri://created', function () {
// webview successfully created
});
webview.once('tauri://error', function (e) {
// an error happened creating the webview
});
// emit an event to the backend
await webview.emit("some-event", "data");
// listen to an event from the backend
const unlisten = await webview.listen("event-name", e => { });
unlisten();
});
Since
2.0.0
Extended by
Constructors
new Webview()
new Webview(
window,
label,
options): Webview
Creates a new Webview.
Parameters
| Parameter | Type | Description |
|---|---|---|
window |
Window |
the window to add this webview to. |
label |
string |
The unique webview label. Must be alphanumeric: a-zA-Z-/:_. |
options |
WebviewOptions |
- |
Returns
The Webview instance to communicate with the webview.
Example
import { Window } from '@tauri-apps/api/window'
import { Webview } from '@tauri-apps/api/webview'
const appWindow = new Window('my-label')
appWindow.once('tauri://created', async function() {
const webview = new Webview(appWindow, 'my-label', {
url: 'https://github.com/tauri-apps/tauri',
// create a webview with specific logical position and size
x: 0,
y: 0,
width: 800,
height: 600,
});
webview.once('tauri://created', function () {
// webview successfully created
});
webview.once('tauri://error', function (e) {
// an error happened creating the webview
});
});
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L194
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
label |
string |
The webview label. It is a unique identifier for the webview, can be used to reference it later. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L155 |
listeners |
Record<string, EventCallback<any>[]> |
Local event listeners. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L160 |
window |
Window |
The window hosting this webview. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L157 |
Methods
clearAllBrowsingData()
clearAllBrowsingData(): Promise<void>
Clears all browsing data for this webview.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
await getCurrentWebview().clearAllBrowsingData();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L589
close()
close(): Promise<void>
Closes the webview.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
await getCurrentWebview().close();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L436
emit()
emit<T>(event, payload?): Promise<void>
Emits an event to all targets.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
event |
string |
Event name. Must include only alphanumeric characters, -, /, : and _. |
payload? |
T |
Event payload. |
Returns
Promise<void>
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
await getCurrentWebview().emit('webview-loaded', { loggedIn: true, token: 'authToken' });
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L325
emitTo()
emitTo<T>(
target,
event,
payload?): Promise<void>
Emits an event to all targets matching the given target.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
target |
string | EventTarget |
Label of the target Window/Webview/WebviewWindow or raw EventTarget object. |
event |
string |
Event name. Must include only alphanumeric characters, -, /, : and _. |
payload? |
T |
Event payload. |
Returns
Promise<void>
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
await getCurrentWebview().emitTo('main', 'webview-loaded', { loggedIn: true, token: 'authToken' });
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L353
hide()
hide(): Promise<void>
Hide the webview.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
await getCurrentWebview().hide();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L523
listen()
listen<T>(event, handler): Promise<UnlistenFn>
Listen to an emitted event on this webview.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
event |
EventName |
Event name. Must include only alphanumeric characters, -, /, : and _. |
handler |
EventCallback<T> |
Event handler. |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
const unlisten = await getCurrentWebview().listen<string>('state-changed', (event) => {
console.log(`Got error: ${payload}`);
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L262
onDragDropEvent()
onDragDropEvent(handler): Promise<UnlistenFn>
Listen to a file drop event. The listener is triggered when the user hovers the selected files on the webview, drops the files or cancels the operation.
Parameters
| Parameter | Type |
|---|---|
handler |
EventCallback<DragDropEvent> |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { getCurrentWebview } from "@tauri-apps/api/webview";
const unlisten = await getCurrentWebview().onDragDropEvent((event) => {
if (event.payload.type === 'over') {
console.log('User hovering', event.payload.position);
} else if (event.payload.type === 'drop') {
console.log('User dropped', event.payload.paths);
} else {
console.log('File drop cancelled');
}
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
When the debugger panel is open, the drop position of this event may be inaccurate due to a known limitation. To retrieve the correct drop position, please detach the debugger.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L641
once()
once<T>(event, handler): Promise<UnlistenFn>
Listen to an emitted event on this webview only once.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
event |
EventName |
Event name. Must include only alphanumeric characters, -, /, : and _. |
handler |
EventCallback<T> |
Event handler. |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
const unlisten = await getCurrent().once<null>('initialized', (event) => {
console.log(`Webview initialized!`);
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L297
position()
position(): Promise<PhysicalPosition>
The position of the top-left hand corner of the webview’s client area relative to the top-left hand corner of the desktop.
Returns
The webview’s position.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
const position = await getCurrentWebview().position();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L398
reparent()
reparent(window): Promise<void>
Moves this webview to the given label.
Parameters
| Parameter | Type |
|---|---|
window |
string | Window | WebviewWindow |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
await getCurrentWebview().reparent('other-window');
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L572
setAutoResize()
setAutoResize(autoResize): Promise<void>
Sets whether the webview should automatically grow and shrink its size and position when the parent window resizes.
Parameters
| Parameter | Type |
|---|---|
autoResize |
boolean |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
await getCurrentWebview().setAutoResize(true);
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L506
setBackgroundColor()
setBackgroundColor(color): Promise<void>
Specify the webview background color.
Platform-specific:
-
macOS / iOS: Not implemented.
-
Windows:
- On Windows 7, transparency is not supported and the alpha value will be ignored.
- On Windows higher than 7: translucent colors are not supported so any alpha value other than
0will be replaced by255
Parameters
| Parameter | Type |
|---|---|
color |
null | Color |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Since
2.1.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L607
setFocus()
setFocus(): Promise<void>
Bring the webview to front and focus.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
await getCurrentWebview().setFocus();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L490
setPosition()
setPosition(position): Promise<void>
Sets the webview position.
Parameters
| Parameter | Type | Description |
|---|---|---|
position |
LogicalPosition | PhysicalPosition | Position |
The new position, in logical or physical pixels. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrent, LogicalPosition } from '@tauri-apps/api/webview';
await getCurrentWebview().setPosition(new LogicalPosition(600, 500));
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L471
setSize()
setSize(size): Promise<void>
Resizes the webview.
Parameters
| Parameter | Type | Description |
|---|---|---|
size |
LogicalSize | PhysicalSize | Size |
The logical or physical size. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrent, LogicalSize } from '@tauri-apps/api/webview';
await getCurrentWebview().setSize(new LogicalSize(600, 500));
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L453
setZoom()
setZoom(scaleFactor): Promise<void>
Set webview zoom level.
Parameters
| Parameter | Type |
|---|---|
scaleFactor |
number |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
await getCurrentWebview().setZoom(1.5);
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L555
show()
show(): Promise<void>
Show the webview.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
await getCurrentWebview().show();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L539
size()
size(): Promise<PhysicalSize>
The physical size of the webview’s client area. The client area is the content of the webview, excluding the title bar and borders.
Returns
The webview’s size.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
const size = await getCurrentWebview().size();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L415
getAll()
static getAll(): Promise<Webview[]>
Gets a list of instances of Webview for all available webviews.
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L239
getByLabel()
static getByLabel(label): Promise<null | Webview>
Gets the Webview for the webview associated with the given label.
Parameters
| Parameter | Type | Description |
|---|---|---|
label |
string |
The webview label. |
Returns
The Webview instance to communicate with the webview or null if the webview doesn’t exist.
Example
import { Webview } from '@tauri-apps/api/webview';
const mainWebview = Webview.getByLabel('main');
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L225
getCurrent()
static getCurrent(): Webview
Get an instance of Webview for the current webview.
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L232
Interfaces
WebviewOptions
Configuration for the webview to create.
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
acceptFirstMouse? |
boolean |
Whether clicking an inactive webview also clicks through to the webview on macOS. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L746 |
allowLinkPreview? |
boolean |
on macOS and iOS there is a link preview on long pressing links, this is enabled by default. see https://docs.rs/objc2-web-kit/latest/objc2_web_kit/struct.WKWebView.html#method.allowsLinkPreview | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L850 |
backgroundColor? |
Color |
Set the window and webview background color. Platform-specific: - macOS / iOS: Not implemented. - Windows: - On Windows 7, alpha channel is ignored. - On Windows 8 and newer, if alpha channel is not 0, it will be ignored. Since 2.1.0 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L822 |
backgroundThrottling? |
BackgroundThrottlingPolicy |
Change the default background throttling behaviour. By default, browsers use a suspend policy that will throttle timers and even unload the whole tab (view) to free resources after roughly 5 minutes when a view became minimized or hidden. This will pause all tasks until the documents visibility state changes back from hidden to visible by bringing the view back to the foreground. ## Platform-specific - Linux / Windows / Android: Unsupported. Workarounds like a pending WebLock transaction might suffice. - iOS: Supported since version 17.0+. - macOS: Supported since version 14.0+. see https://github.com/tauri-apps/tauri/issues/5250#issuecomment-2569380578 Since 2.3.0 | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L841 |
dataDirectory? |
string |
Set a custom path for the webview’s data directory (localStorage, cache, etc.) relative to [appDataDir()]/${label}. For security reasons, paths outside of that location can only be configured on the Rust side. Platform-specific: - Windows: WebViews with different values for settings like additionalBrowserArgs, browserExtensionsEnabled or scrollBarStyle must have different data directories. - macOS / iOS: Unsupported, use dataStoreIdentifier instead. - Android: Unsupported. Since 2.9.0 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L870 |
dataStoreIdentifier? |
number[] |
Initialize the WebView with a custom data store identifier. This can be seen as a replacement for dataDirectory which is unavailable in WKWebView. See https://developer.apple.com/documentation/webkit/wkwebsitedatastore/init(foridentifier:)?language=objc The array must contain 16 u8 numbers. Platform-specific: - macOS / iOS: Available on macOS >= 14 and iOS >= 17 - Windows / Linux / Android: Unsupported. Since 2.9.0 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L884 |
devtools? |
boolean |
Whether web inspector, which is usually called browser devtools, is enabled or not. Enabled by default. This API works in debug builds, but requires devtools feature flag to enable it in release builds. Platform-specific - macOS: This will call private functions on macOS. - Android: Open chrome://inspect/#devices in Chrome to get the devtools window. Wry’s WebView devtools API isn’t supported on Android. - iOS: Open Safari > Develop > [Your Device Name] > [Your WebView] to get the devtools window. Since 2.1.0 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L809 |
disableInputAccessoryView? |
boolean |
Allows disabling the input accessory view on iOS. The accessory view is the view that appears above the keyboard when a text input element is focused. It usually displays a view with “Done”, “Next” buttons. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L857 |
dragDropEnabled? |
boolean |
Whether the drag and drop is enabled or not on the webview. By default it is enabled. Disabling it is required to use HTML5 drag and drop on the frontend on Windows. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L742 |
focus? |
boolean |
Whether the webview should have focus or not Since 2.1.0 | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L736 |
generalAutofillEnabled? |
boolean |
Controls the WebView’s browser-level general autofill behavior. This option does not disable password or credit card autofill. When set to false, the WebView will not automatically populate general form fields using previously stored data such as addresses or contact information. If not specified, this is true by default. ## Platform-specific - Windows: Supported. WebView2’s autofill feature (called “Suggestions”) may not honor autocomplete="off" on input elements in some cases. - Linux / Android / iOS / macOS: Unsupported and performs no operation. Since 2.11.0 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L918 |
height |
number |
The initial height in logical pixels. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L724 |
incognito? |
boolean |
Whether or not the webview should be launched in incognito mode. Platform-specific - Android: Unsupported. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L758 |
javascriptDisabled? |
boolean |
Whether we should disable JavaScript code execution on the webview or not. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L845 |
proxyUrl? |
string |
The proxy URL for the WebView for all network requests. Must be either a http:// or a socks5:// URL. Platform-specific - macOS: Requires the macos-proxy feature flag and only compiles for macOS 14+. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L768 |
scrollBarStyle? |
ScrollBarStyle |
Specifies the native scrollbar style to use with the webview. CSS styles that modify the scrollbar are applied on top of the native appearance configured here. Defaults to default, which is the browser default. ## Platform-specific - Windows: - fluentOverlay requires WebView2 Runtime version 125.0.2535.41 or higher, and does nothing on older versions. - This option must be given the same value for all webviews. - Linux / Android / iOS / macOS: Unsupported. Only supports Default and performs no operation. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L899 |
transparent? |
boolean |
Whether the webview is transparent or not. Note that on macOS this requires the macos-private-api feature flag, enabled under tauri.conf.json > app > macOSPrivateApi. WARNING: Using private APIs on macOS prevents your application from being accepted to the App Store. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L730 |
url? |
string |
Remote URL or local file path to open. - URL such as https://github.com/tauri-apps is opened directly on a Tauri webview. - data: URL such as data:text/html,<html>... is only supported with the webview-data-url Cargo feature for the tauri dependency. - local file path or route such as /path/to/page.html or /users is appended to the application URL (the devServer URL on development, or tauri://localhost/ and https://tauri.localhost/ on production). |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L716 |
useHttpsScheme? |
boolean |
Sets whether the custom protocols should use https://<scheme>.localhost instead of the default http://<scheme>.localhost on Windows and Android. Defaults to false. #### Note Using a https scheme will NOT allow mixed content when trying to fetch http endpoints and therefore will not match the behavior of the <scheme>://localhost protocols used on macOS and Linux. #### Warning Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access them. Since 2.1.0 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L795 |
userAgent? |
string |
The user agent for the webview. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L750 |
width |
number |
The initial width in logical pixels. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L722 |
x |
number |
The initial vertical position in logical pixels. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L718 |
y |
number |
The initial horizontal position in logical pixels. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L720 |
zoomHotkeysEnabled? |
boolean |
Whether page zooming by hotkeys is enabled Platform-specific: - Windows: Controls WebView2’s IsZoomControlEnabled setting. - MacOS / Linux: Injects a polyfill that zooms in and out with ctrl/command + -/=, 20% in each step, ranging from 20% to 1000%. Requires webview:allow-set-webview-zoom permission - Android / iOS: Unsupported. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L780 |
Type Aliases
Color
type Color: [number, number, number] | [number, number, number, number] | object | string;
An RGBA color. Each value has minimum of 0 and maximum of 255.
It can be either a string #ffffff, an array of 3 or 4 elements or an object.
Since
2.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2121
DragDropEvent
type DragDropEvent: object | object | object | object;
The drag and drop event types.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L43
Functions
getAllWebviews()
function getAllWebviews(): Promise<Webview[]>
Gets a list of instances of Webview for all available webviews.
Returns
Since
2.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L70
getCurrentWebview()
function getCurrentWebview(): Webview
Get an instance of Webview for the current webview.
Returns
Since
2.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L54
webviewWindow
References
Color
Re-exports Color
DragDropEvent
Re-exports DragDropEvent
Classes
WebviewWindow
Create new webview or get a handle to an existing one.
Webviews are identified by a label a unique identifier that can be used to reference it later. It may only contain alphanumeric characters a-zA-Z plus the following special characters -, /, : and _.
Example
import { Window } from "@tauri-apps/api/window"
import { Webview } from "@tauri-apps/api/webview"
const appWindow = new Window('uniqueLabel');
appWindow.once('tauri://created', async function () {
// `new Webview` Should be called after the window is successfully created,
// or webview may not be attached to the window since window is not created yet.
// loading embedded asset:
const webview = new Webview(appWindow, 'theUniqueLabel', {
url: 'path/to/page.html',
// create a webview with specific logical position and size
x: 0,
y: 0,
width: 800,
height: 600,
});
// alternatively, load a remote URL:
const webview = new Webview(appWindow, 'theUniqueLabel', {
url: 'https://github.com/tauri-apps/tauri',
// create a webview with specific logical position and size
x: 0,
y: 0,
width: 800,
height: 600,
});
webview.once('tauri://created', function () {
// webview successfully created
});
webview.once('tauri://error', function (e) {
// an error happened creating the webview
});
// emit an event to the backend
await webview.emit("some-event", "data");
// listen to an event from the backend
const unlisten = await webview.listen("event-name", e => { });
unlisten();
});
Since
2.0.0
Extends
Constructors
new WebviewWindow()
new WebviewWindow(label, options): WebviewWindow
Creates a new Window hosting a Webview.
Parameters
| Parameter | Type | Description |
|---|---|---|
label |
string |
The unique webview label. Must be alphanumeric: a-zA-Z-/:_. |
options |
Omit<WebviewOptions, "x" | "y" | "width" | "height"> & WindowOptions |
- |
Returns
The WebviewWindow instance to communicate with the window and webview.
Example
import { WebviewWindow } from '@tauri-apps/api/webviewWindow'
const webview = new WebviewWindow('my-label', {
url: 'https://github.com/tauri-apps/tauri'
});
webview.once('tauri://created', function () {
// webview successfully created
});
webview.once('tauri://error', function (e) {
// an error happened creating the webview
});
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webviewWindow.ts#L75
Properties
| Property | Type | Description | Inherited from | Defined in |
|---|---|---|---|---|
label |
string |
The webview label. It is a unique identifier for the webview, can be used to reference it later. | Window.label |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webviewWindow.ts#L51 |
listeners |
Record<string, EventCallback<any>[]> |
Local event listeners. | Window.listeners |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webviewWindow.ts#L54 |
window |
Window |
The window hosting this webview. | Webview.window |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L157 |
Methods
activityName()
activityName(): Promise<string>
Returns
Promise<string>
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L853
center()
center(): Promise<void>
Centers the window.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().center();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L877
clearAllBrowsingData()
clearAllBrowsingData(): Promise<void>
Clears all browsing data for this webview.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
await getCurrentWebview().clearAllBrowsingData();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L589
clearEffects()
clearEffects(): Promise<void>
Clear any applied effects if possible.
Returns
Promise<void>
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1265
close()
close(): Promise<void>
Closes the webview.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
await getCurrentWebview().close();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L436
destroy()
destroy(): Promise<void>
Destroys the window. Behaves like Window.close but forces the window close instead of emitting a closeRequested event.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().destroy();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1202
emit()
emit<T>(event, payload?): Promise<void>
Emits an event to all targets.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
event |
string |
Event name. Must include only alphanumeric characters, -, /, : and _. |
payload? |
T |
Event payload. |
Returns
Promise<void>
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
await getCurrentWebview().emit('webview-loaded', { loggedIn: true, token: 'authToken' });
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L325
emitTo()
emitTo<T>(
target,
event,
payload?): Promise<void>
Emits an event to all targets matching the given target.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
target |
string | EventTarget |
Label of the target Window/Webview/WebviewWindow or raw EventTarget object. |
event |
string |
Event name. Must include only alphanumeric characters, -, /, : and _. |
payload? |
T |
Event payload. |
Returns
Promise<void>
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
await getCurrentWebview().emitTo('main', 'webview-loaded', { loggedIn: true, token: 'authToken' });
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L353
hide()
hide(): Promise<void>
Hide the webview.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
await getCurrentWebview().hide();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L523
innerPosition()
innerPosition(): Promise<PhysicalPosition>
The position of the top-left hand corner of the window’s client area relative to the top-left hand corner of the desktop.
Returns
The window’s inner position.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const position = await getCurrentWindow().innerPosition();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L567
innerSize()
innerSize(): Promise<PhysicalSize>
The physical size of the window’s client area. The client area is the content of the window, excluding the title bar and borders.
Returns
The window’s inner size.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const size = await getCurrentWindow().innerSize();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L600
isAlwaysOnTop()
isAlwaysOnTop(): Promise<boolean>
Whether the window is configured to be always on top of other windows or not.
Returns
Promise<boolean>
Whether the window is visible or not.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const alwaysOnTop = await getCurrentWindow().isAlwaysOnTop();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L847
isClosable()
isClosable(): Promise<boolean>
Gets the window’s native close button state.
Platform-specific
- iOS / Android: Unsupported.
Returns
Promise<boolean>
Whether the window’s native close button is enabled or not.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const closable = await getCurrentWindow().isClosable();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L780
isDecorated()
isDecorated(): Promise<boolean>
Gets the window’s current decorated state.
Returns
Promise<boolean>
Whether the window is decorated or not.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const decorated = await getCurrentWindow().isDecorated();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L701
isEnabled()
isEnabled(): Promise<boolean>
Whether the window is enabled or disabled.
Returns
Promise<boolean>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setEnabled(false);
Since
2.0.0
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L969
isFocused()
isFocused(): Promise<boolean>
Gets the window’s current focus state.
Returns
Promise<boolean>
Whether the window is focused or not.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const focused = await getCurrentWindow().isFocused();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L685
isFullscreen()
isFullscreen(): Promise<boolean>
Gets the window’s current fullscreen state.
Returns
Promise<boolean>
Whether the window is in fullscreen mode or not.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const fullscreen = await getCurrentWindow().isFullscreen();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L639
isMaximizable()
isMaximizable(): Promise<boolean>
Gets the window’s native maximize button state.
Platform-specific
- Linux / iOS / Android: Unsupported.
Returns
Promise<boolean>
Whether the window’s native maximize button is enabled or not.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const maximizable = await getCurrentWindow().isMaximizable();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L738
isMaximized()
isMaximized(): Promise<boolean>
Gets the window’s current maximized state.
Returns
Promise<boolean>
Whether the window is maximized or not.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const maximized = await getCurrentWindow().isMaximized();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L669
isMinimizable()
isMinimizable(): Promise<boolean>
Gets the window’s native minimize button state.
Platform-specific
- Linux / iOS / Android: Unsupported.
Returns
Promise<boolean>
Whether the window’s native minimize button is enabled or not.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const minimizable = await getCurrentWindow().isMinimizable();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L759
isMinimized()
isMinimized(): Promise<boolean>
Gets the window’s current minimized state.
Returns
Promise<boolean>
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const minimized = await getCurrentWindow().isMinimized();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L653
isResizable()
isResizable(): Promise<boolean>
Gets the window’s current resizable state.
Returns
Promise<boolean>
Whether the window is resizable or not.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const resizable = await getCurrentWindow().isResizable();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L717
isVisible()
isVisible(): Promise<boolean>
Gets the window’s current visible state.
Returns
Promise<boolean>
Whether the window is visible or not.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const visible = await getCurrentWindow().isVisible();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L796
listen()
listen<T>(event, handler): Promise<UnlistenFn>
Listen to an emitted event on this webview window.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
event |
EventName |
Event name. Must include only alphanumeric characters, -, /, : and _. |
handler |
EventCallback<T> |
Event handler. |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { WebviewWindow } from '@tauri-apps/api/webviewWindow';
const unlisten = await WebviewWindow.getCurrent().listen<string>('state-changed', (event) => {
console.log(`Got error: ${payload}`);
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webviewWindow.ts#L155
maximize()
maximize(): Promise<void>
Maximizes the window.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().maximize();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1072
minimize()
minimize(): Promise<void>
Minimizes the window.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().minimize();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1120
onCloseRequested()
onCloseRequested(handler): Promise<UnlistenFn>
Listen to window close requested. Emitted when the user requests to closes the window.
Parameters
| Parameter | Type |
|---|---|
handler |
(event) => void | Promise<void> |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { getCurrentWindow } from "@tauri-apps/api/window";
import { confirm } from '@tauri-apps/api/dialog';
const unlisten = await getCurrentWindow().onCloseRequested(async (event) => {
const confirmed = await confirm('Are you sure?');
if (!confirmed) {
// user did not confirm closing the window; let's prevent it
event.preventDefault();
}
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1927
onDragDropEvent()
onDragDropEvent(handler): Promise<UnlistenFn>
Listen to a file drop event. The listener is triggered when the user hovers the selected files on the webview, drops the files or cancels the operation.
Parameters
| Parameter | Type |
|---|---|
handler |
EventCallback<DragDropEvent> |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { getCurrentWebview } from "@tauri-apps/api/webview";
const unlisten = await getCurrentWebview().onDragDropEvent((event) => {
if (event.payload.type === 'over') {
console.log('User hovering', event.payload.position);
} else if (event.payload.type === 'drop') {
console.log('User dropped', event.payload.paths);
} else {
console.log('File drop cancelled');
}
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
When the debugger panel is open, the drop position of this event may be inaccurate due to a known limitation. To retrieve the correct drop position, please detach the debugger.
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L641
onFocusChanged()
onFocusChanged(handler): Promise<UnlistenFn>
Listen to window focus change.
Parameters
| Parameter | Type |
|---|---|
handler |
EventCallback<boolean> |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { getCurrentWindow } from "@tauri-apps/api/window";
const unlisten = await getCurrentWindow().onFocusChanged(({ payload: focused }) => {
console.log('Focus changed, window is focused? ' + focused);
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2043
onMoved()
onMoved(handler): Promise<UnlistenFn>
Listen to window move.
Parameters
| Parameter | Type |
|---|---|
handler |
EventCallback<PhysicalPosition> |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { getCurrentWindow } from "@tauri-apps/api/window";
const unlisten = await getCurrentWindow().onMoved(({ payload: position }) => {
console.log('Window moved', position);
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1898
onResized()
onResized(handler): Promise<UnlistenFn>
Listen to window resize.
Parameters
| Parameter | Type |
|---|---|
handler |
EventCallback<PhysicalSize> |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { getCurrentWindow } from "@tauri-apps/api/window";
const unlisten = await getCurrentWindow().onResized(({ payload: size }) => {
console.log('Window resized', size);
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1874
onScaleChanged()
onScaleChanged(handler): Promise<UnlistenFn>
Listen to window scale change. Emitted when the window’s scale factor has changed. The following user actions can cause DPI changes:
- Changing the display’s resolution.
- Changing the display’s scale factor (e.g. in Control Panel on Windows).
- Moving the window to a display with a different scale factor.
Parameters
| Parameter | Type |
|---|---|
handler |
EventCallback<ScaleFactorChanged> |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { getCurrentWindow } from "@tauri-apps/api/window";
const unlisten = await getCurrentWindow().onScaleChanged(({ payload }) => {
console.log('Scale changed', payload.scaleFactor, payload.size);
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2083
onThemeChanged()
onThemeChanged(handler): Promise<UnlistenFn>
Listen to the system theme change.
Parameters
| Parameter | Type |
|---|---|
handler |
EventCallback<Theme> |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { getCurrentWindow } from "@tauri-apps/api/window";
const unlisten = await getCurrentWindow().onThemeChanged(({ payload: theme }) => {
console.log('New theme: ' + theme);
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2109
once()
once<T>(event, handler): Promise<UnlistenFn>
Listen to an emitted event on this webview window only once.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
event |
EventName |
Event name. Must include only alphanumeric characters, -, /, : and _. |
handler |
EventCallback<T> |
Event handler. |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { WebviewWindow } from '@tauri-apps/api/webviewWindow';
const unlisten = await WebviewWindow.getCurrent().once<null>('initialized', (event) => {
console.log(`Webview initialized!`);
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webviewWindow.ts#L190
outerPosition()
outerPosition(): Promise<PhysicalPosition>
The position of the top-left hand corner of the window relative to the top-left hand corner of the desktop.
Returns
The window’s outer position.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const position = await getCurrentWindow().outerPosition();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L583
outerSize()
outerSize(): Promise<PhysicalSize>
The physical size of the entire window. These dimensions include the title bar and borders. If you don’t want that (and you usually don’t), use inner_size instead.
Returns
The window’s outer size.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const size = await getCurrentWindow().outerSize();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L620
position()
position(): Promise<PhysicalPosition>
The position of the top-left hand corner of the webview’s client area relative to the top-left hand corner of the desktop.
Returns
The webview’s position.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
const position = await getCurrentWebview().position();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L398
reparent()
reparent(window): Promise<void>
Moves this webview to the given label.
Parameters
| Parameter | Type |
|---|---|
window |
string | Window | WebviewWindow |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
await getCurrentWebview().reparent('other-window');
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L572
requestUserAttention()
requestUserAttention(requestType): Promise<void>
Requests user attention to the window, this has no effect if the application is already focused. How requesting for user attention manifests is platform dependent, see UserAttentionType for details.
Providing null will unset the request for user attention. Unsetting the request for user attention might not be done automatically by the WM when the window receives input.
Platform-specific
- macOS:
nullhas no effect. - Linux: Urgency levels have the same effect.
Parameters
| Parameter | Type |
|---|---|
requestType |
null | UserAttentionType |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().requestUserAttention();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L903
scaleFactor()
scaleFactor(): Promise<number>
The scale factor that can be used to map physical pixels to logical pixels.
Returns
Promise<number>
The window’s monitor scale factor.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const factor = await getCurrentWindow().scaleFactor();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L551
sceneIdentifier()
sceneIdentifier(): Promise<string>
Returns
Promise<string>
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L859
setAlwaysOnBottom()
setAlwaysOnBottom(alwaysOnBottom): Promise<void>
Whether the window should always be below other windows.
Parameters
| Parameter | Type | Description |
|---|---|---|
alwaysOnBottom |
boolean |
Whether the window should always be below other windows or not. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setAlwaysOnBottom(true);
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1301
setAlwaysOnTop()
setAlwaysOnTop(alwaysOnTop): Promise<void>
Whether the window should always be on top of other windows.
Parameters
| Parameter | Type | Description |
|---|---|---|
alwaysOnTop |
boolean |
Whether the window should always be on top of other windows or not. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setAlwaysOnTop(true);
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1283
setAutoResize()
setAutoResize(autoResize): Promise<void>
Sets whether the webview should automatically grow and shrink its size and position when the parent window resizes.
Parameters
| Parameter | Type |
|---|---|
autoResize |
boolean |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
await getCurrentWebview().setAutoResize(true);
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L506
setBackgroundColor()
setBackgroundColor(color): Promise<void>
Set the window and webview background color.
Platform-specific:
-
Android / iOS: Unsupported for the window layer.
-
macOS / iOS: Not implemented for the webview layer.
-
Windows:
- alpha channel is ignored for the window layer.
- On Windows 7, alpha channel is ignored for the webview layer.
- On Windows 8 and newer, if alpha channel is not
0, it will be ignored.
Parameters
| Parameter | Type |
|---|---|
color |
Color |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Since
2.1.0
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webviewWindow.ts#L222
setBadgeCount()
setBadgeCount(count?): Promise<void>
Sets the badge count. It is app wide and not specific to this window.
Platform-specific
- Windows: Unsupported. Use @{linkcode Window.setOverlayIcon} instead.
Parameters
| Parameter | Type | Description |
|---|---|---|
count? |
number |
The badge count. Use undefined to remove the badge. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setBadgeCount(5);
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1727
setBadgeLabel()
setBadgeLabel(label?): Promise<void>
Sets the badge cont macOS only.
Parameters
| Parameter | Type | Description |
|---|---|---|
label? |
string |
The badge label. Use undefined to remove the badge. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setBadgeLabel("Hello");
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1746
setClosable()
setClosable(closable): Promise<void>
Sets whether the window’s native close button is enabled or not.
Platform-specific
- Linux: GTK+ will do its best to convince the window manager not to show a close button. Depending on the system, this function may not have any effect when called on a window that is already visible
- iOS / Android: Unsupported.
Parameters
| Parameter | Type |
|---|---|
closable |
boolean |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setClosable(false);
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1037
setContentProtected()
setContentProtected(protected_): Promise<void>
Prevents the window contents from being captured by other apps.
Parameters
| Parameter | Type |
|---|---|
protected_ |
boolean |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setContentProtected(true);
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1318
setCursorGrab()
setCursorGrab(grab): Promise<void>
Grabs the cursor, preventing it from leaving the window.
There’s no guarantee that the cursor will be hidden. You should hide it by yourself if you want so.
Platform-specific
- Linux: Unsupported.
- macOS: This locks the cursor in a fixed location, which looks visually awkward.
Parameters
| Parameter | Type | Description |
|---|---|---|
grab |
boolean |
true to grab the cursor icon, false to release it. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setCursorGrab(true);
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1574
setCursorIcon()
setCursorIcon(icon): Promise<void>
Modifies the cursor icon of the window.
Parameters
| Parameter | Type | Description |
|---|---|---|
icon |
CursorIcon |
The new cursor icon. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setCursorIcon('help');
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1616
setCursorPosition()
setCursorPosition(position): Promise<void>
Changes the position of the cursor in window coordinates.
Parameters
| Parameter | Type | Description |
|---|---|---|
position |
LogicalPosition | PhysicalPosition | Position |
The new cursor position. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow, LogicalPosition } from '@tauri-apps/api/window';
await getCurrentWindow().setCursorPosition(new LogicalPosition(600, 300));
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1650
setCursorVisible()
setCursorVisible(visible): Promise<void>
Modifies the cursor’s visibility.
Platform-specific
- Windows: The cursor is only hidden within the confines of the window.
- macOS: The cursor is hidden as long as the window has input focus, even if the cursor is outside of the window.
Parameters
| Parameter | Type | Description |
|---|---|---|
visible |
boolean |
If false, this will hide the cursor. If true, this will show the cursor. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setCursorVisible(false);
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1598
setDecorations()
setDecorations(decorations): Promise<void>
Whether the window should have borders and bars.
Parameters
| Parameter | Type | Description |
|---|---|---|
decorations |
boolean |
Whether the window should have borders and bars. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setDecorations(false);
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1219
setEffects()
setEffects(effects): Promise<void>
Set window effects.
Parameters
| Parameter | Type |
|---|---|
effects |
Effects |
Returns
Promise<void>
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1255
setEnabled()
setEnabled(enabled): Promise<void>
Enable or disable the window.
Parameters
| Parameter | Type |
|---|---|
enabled |
boolean |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setEnabled(false);
Since
2.0.0
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L950
setFocus()
setFocus(): Promise<void>
Bring the webview to front and focus.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
await getCurrentWebview().setFocus();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L490
setFocusable()
setFocusable(focusable): Promise<void>
Sets whether the window can be focused.
Platform-specific
- macOS: If the window is already focused, it is not possible to unfocus it after calling
set_focusable(false). In this case, you might consider calling Window.setFocus but it will move the window to the back i.e. at the bottom in terms of z-order.
Parameters
| Parameter | Type | Description |
|---|---|---|
focusable |
boolean |
Whether the window can be focused. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setFocusable(true);
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1499
setFullscreen()
setFullscreen(fullscreen): Promise<void>
Sets the window fullscreen state.
Parameters
| Parameter | Type | Description |
|---|---|---|
fullscreen |
boolean |
Whether the window should go to fullscreen or not. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setFullscreen(true);
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1443
setIcon()
setIcon(icon): Promise<void>
Sets the window icon.
Parameters
| Parameter | Type | Description |
|---|---|---|
icon |
| string | Uint8Array | number[] | ArrayBuffer | Image |
Icon bytes or path to the icon file. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setIcon('/tauri/awesome.png');
Note that you may need the image-ico or image-png Cargo features to use this API. To enable it, change your Cargo.toml file:
[dependencies]
tauri = { version = "...", features = ["...", "image-png"] }
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1524
setIgnoreCursorEvents()
setIgnoreCursorEvents(ignore): Promise<void>
Changes the cursor events behavior.
Parameters
| Parameter | Type | Description |
|---|---|---|
ignore |
boolean |
true to ignore the cursor events; false to process them as usual. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setIgnoreCursorEvents(true);
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1671
setMaxSize()
setMaxSize(size): Promise<void>
Sets the window maximum inner size. If the size argument is undefined, the constraint is unset.
Parameters
| Parameter | Type | Description |
|---|---|---|
size |
| undefined | null | LogicalSize | PhysicalSize | Size |
The logical or physical inner size, or null to unset the constraint. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow, LogicalSize } from '@tauri-apps/api/window';
await getCurrentWindow().setMaxSize(new LogicalSize(600, 500));
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1374
setMaximizable()
setMaximizable(maximizable): Promise<void>
Sets whether the window’s native maximize button is enabled or not. If resizable is set to false, this setting is ignored.
Platform-specific
- macOS: Disables the “zoom” button in the window titlebar, which is also used to enter fullscreen mode.
- Linux / iOS / Android: Unsupported.
Parameters
| Parameter | Type |
|---|---|
maximizable |
boolean |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setMaximizable(false);
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L992
setMinSize()
setMinSize(size): Promise<void>
Sets the window minimum inner size. If the size argument is not provided, the constraint is unset.
Parameters
| Parameter | Type | Description |
|---|---|---|
size |
| undefined | null | LogicalSize | PhysicalSize | Size |
The logical or physical inner size, or null to unset the constraint. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow, PhysicalSize } from '@tauri-apps/api/window';
await getCurrentWindow().setMinSize(new PhysicalSize(600, 500));
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1354
setMinimizable()
setMinimizable(minimizable): Promise<void>
Sets whether the window’s native minimize button is enabled or not.
Platform-specific
- Linux / iOS / Android: Unsupported.
Parameters
| Parameter | Type |
|---|---|
minimizable |
boolean |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setMinimizable(false);
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1014
setOverlayIcon()
setOverlayIcon(icon?): Promise<void>
Sets the overlay icon. Windows only The overlay icon can be set for every window.
Note that you may need the image-ico or image-png Cargo features to use this API. To enable it, change your Cargo.toml file:
[dependencies]
tauri = { version = "...", features = ["...", "image-png"] }
Parameters
| Parameter | Type | Description |
|---|---|---|
icon? |
| string | Uint8Array | number[] | ArrayBuffer | Image |
Icon bytes or path to the icon file. Use undefined to remove the overlay icon. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setOverlayIcon("/tauri/awesome.png");
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1775
setPosition()
setPosition(position): Promise<void>
Sets the webview position.
Parameters
| Parameter | Type | Description |
|---|---|---|
position |
LogicalPosition | PhysicalPosition | Position |
The new position, in logical or physical pixels. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrent, LogicalPosition } from '@tauri-apps/api/webview';
await getCurrentWebview().setPosition(new LogicalPosition(600, 500));
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L471
setProgressBar()
setProgressBar(state): Promise<void>
Sets the taskbar progress state.
Platform-specific
- Linux / macOS: Progress bar is app-wide and not specific to this window.
- Linux: Only supported desktop environments with
libunity(e.g. GNOME).
Parameters
| Parameter | Type |
|---|---|
state |
ProgressBarState |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow, ProgressBarStatus } from '@tauri-apps/api/window';
await getCurrentWindow().setProgressBar({
status: ProgressBarStatus.Normal,
progress: 50,
});
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1803
setResizable()
setResizable(resizable): Promise<void>
Updates the window resizable flag.
Parameters
| Parameter | Type |
|---|---|
resizable |
boolean |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setResizable(false);
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L931
setShadow()
setShadow(enable): Promise<void>
Whether or not the window should have shadow.
Platform-specific
-
Windows:
falsehas no effect on decorated window, shadows are always ON.truewill make undecorated window have a 1px white border, and on Windows 11, it will have a rounded corners.
-
Linux: Unsupported.
Parameters
| Parameter | Type |
|---|---|
enable |
boolean |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setShadow(false);
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1245
setSimpleFullscreen()
setSimpleFullscreen(fullscreen): Promise<void>
On macOS, Toggles a fullscreen mode that doesn’t require a new macOS space. Returns a boolean indicating whether the transition was successful (this won’t work if the window was already in the native fullscreen). This is how fullscreen used to work on macOS in versions before Lion. And allows the user to have a fullscreen window without using another space or taking control over the entire monitor.
On other platforms, this is the same as Window.setFullscreen.
Parameters
| Parameter | Type | Description |
|---|---|---|
fullscreen |
boolean |
Whether the window should go to simple fullscreen or not. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1459
setSize()
setSize(size): Promise<void>
Resizes the webview.
Parameters
| Parameter | Type | Description |
|---|---|---|
size |
LogicalSize | PhysicalSize | Size |
The logical or physical size. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrent, LogicalSize } from '@tauri-apps/api/webview';
await getCurrentWebview().setSize(new LogicalSize(600, 500));
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L453
setSizeConstraints()
setSizeConstraints(constraints): Promise<void>
Sets the window inner size constraints.
Parameters
| Parameter | Type | Description |
|---|---|---|
constraints |
undefined | null | WindowSizeConstraints |
The logical or physical inner size, or null to unset the constraint. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setSizeConstraints({ minWidth: 300 });
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1394
setSkipTaskbar()
setSkipTaskbar(skip): Promise<void>
Whether the window icon should be hidden from the taskbar or not.
Platform-specific
- macOS: Unsupported.
Parameters
| Parameter | Type | Description |
|---|---|---|
skip |
boolean |
true to hide window icon, false to show it. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setSkipTaskbar(true);
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1548
setTheme()
setTheme(theme?): Promise<void>
Set window theme, pass in null or undefined to follow system theme
Platform-specific
- Linux / macOS: Theme is app-wide and not specific to this window.
- iOS / Android: Unsupported.
Parameters
| Parameter | Type |
|---|---|
theme? |
null | Theme |
Returns
Promise<void>
Since
2.0.0
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1848
setTitle()
setTitle(title): Promise<void>
Sets the window title.
Parameters
| Parameter | Type | Description |
|---|---|---|
title |
string |
The new title |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setTitle('Tauri');
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1055
setTitleBarStyle()
setTitleBarStyle(style): Promise<void>
Sets the title bar style. macOS only.
Parameters
| Parameter | Type |
|---|---|
style |
TitleBarStyle |
Returns
Promise<void>
Since
2.0.0
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1831
setVisibleOnAllWorkspaces()
setVisibleOnAllWorkspaces(visible): Promise<void>
Sets whether the window should be visible on all workspaces or virtual desktops.
Platform-specific
- Windows / iOS / Android: Unsupported.
Parameters
| Parameter | Type |
|---|---|
visible |
boolean |
Returns
Promise<void>
Since
2.0.0
Inherited from
Window.setVisibleOnAllWorkspaces
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1819
setZoom()
setZoom(scaleFactor): Promise<void>
Set webview zoom level.
Parameters
| Parameter | Type |
|---|---|
scaleFactor |
number |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
await getCurrentWebview().setZoom(1.5);
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L555
show()
show(): Promise<void>
Show the webview.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
await getCurrentWebview().show();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L539
size()
size(): Promise<PhysicalSize>
The physical size of the webview’s client area. The client area is the content of the webview, excluding the title bar and borders.
Returns
The webview’s size.
Example
import { getCurrentWebview } from '@tauri-apps/api/webview';
const size = await getCurrentWebview().size();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webview.ts#L415
startDragging()
startDragging(): Promise<void>
Starts dragging the window.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().startDragging();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1688
startResizeDragging()
startResizeDragging(direction): Promise<void>
Starts resize-dragging the window.
Parameters
| Parameter | Type |
|---|---|
direction |
ResizeDirection |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().startResizeDragging();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1704
theme()
theme(): Promise<null | Theme>
Gets the window’s current theme.
Platform-specific
- macOS: Theme was introduced on macOS 10.14. Returns
lighton macOS 10.13 and below.
Returns
The window theme.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const theme = await getCurrentWindow().theme();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L831
title()
title(): Promise<string>
Gets the window’s current title.
Returns
Promise<string>
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const title = await getCurrentWindow().title();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L810
toggleMaximize()
toggleMaximize(): Promise<void>
Toggles the window maximized state.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().toggleMaximize();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1104
unmaximize()
unmaximize(): Promise<void>
Unmaximizes the window.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().unmaximize();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1088
unminimize()
unminimize(): Promise<void>
Unminimizes the window.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().unminimize();
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1136
getAll()
static getAll(): Promise<WebviewWindow[]>
Gets a list of instances of Webview for all available webviews.
Returns
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webviewWindow.ts#L132
getByLabel()
static getByLabel(label): Promise<null | WebviewWindow>
Gets the Webview for the webview associated with the given label.
Parameters
| Parameter | Type | Description |
|---|---|---|
label |
string |
The webview label. |
Returns
Promise<null | WebviewWindow>
The Webview instance to communicate with the webview or null if the webview doesn’t exist.
Example
import { WebviewWindow } from '@tauri-apps/api/webviewWindow';
const mainWebview = WebviewWindow.getByLabel('main');
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webviewWindow.ts#L112
getCurrent()
static getCurrent(): WebviewWindow
Get an instance of Webview for the current webview.
Returns
Inherited from
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webviewWindow.ts#L125
Functions
getAllWebviewWindows()
function getAllWebviewWindows(): Promise<WebviewWindow[]>
Gets a list of instances of Webview for all available webview windows.
Returns
Since
2.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webviewWindow.ts#L34
getCurrentWebviewWindow()
function getCurrentWebviewWindow(): WebviewWindow
Get an instance of Webview for the current webview window.
Returns
Since
2.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/webviewWindow.ts#L23
window
Provides APIs to create windows, communicate with other windows and manipulate the current window.
Window events
Events can be listened to using Window.listen:
import { getCurrentWindow } from "@tauri-apps/api/window";
getCurrentWindow().listen("my-window-event", ({ event, payload }) => { });
References
Color
Re-exports Color
DragDropEvent
Re-exports DragDropEvent
LogicalPosition
Re-exports LogicalPosition
LogicalSize
Re-exports LogicalSize
PhysicalPosition
Re-exports PhysicalPosition
PhysicalSize
Re-exports PhysicalSize
Enumerations
BackgroundThrottlingPolicy
Background throttling policy
Since
2.0.0
Enumeration Members
Disabled
Disabled: "disabled";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2133
Suspend
Suspend: "suspend";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2135
Throttle
Throttle: "throttle";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2134
Effect
Platform-specific window effects
Since
2.0.0
Enumeration Members
Acrylic
Acrylic: "acrylic";
Windows 10/11
Notes
This effect has bad performance when resizing/dragging the window on Windows 10 v1903+ and Windows 11 build 22000.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2272
AppearanceBased
AppearanceBased: "appearanceBased";
A default material appropriate for the view’s effectiveAppearance. macOS 10.14-
Deprecated
since macOS 10.14. You should instead choose an appropriate semantic material.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2172
Blur
Blur: "blur";
Windows 7/10/11(22H1) Only
Notes
This effect has bad performance when resizing/dragging the window on Windows 11 build 22621.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2264
ContentBackground
ContentBackground: "contentBackground";
macOS 10.14+
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2244
Dark
Dark: "dark";
macOS 10.14-
Deprecated
since macOS 10.14. Use a semantic material instead.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2184
FullScreenUI
FullScreenUI: "fullScreenUI";
macOS 10.14+
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2236
HeaderView
HeaderView: "headerView";
macOS 10.14+
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2220
HudWindow
HudWindow: "hudWindow";
macOS 10.14+
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2232
Light
Light: "light";
macOS 10.14-
Deprecated
since macOS 10.14. Use a semantic material instead.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2178
MediumLight
MediumLight: "mediumLight";
macOS 10.14-
Deprecated
since macOS 10.14. Use a semantic material instead.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2190
Menu
Menu: "menu";
macOS 10.11+
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2208
Mica
Mica: "mica";
Windows 11 Only
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2256
Popover
Popover: "popover";
macOS 10.11+
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2212
Selection
Selection: "selection";
macOS 10.10+
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2204
Sheet
Sheet: "sheet";
macOS 10.14+
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2224
Sidebar
Sidebar: "sidebar";
macOS 10.11+
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2216
Tabbed
Tabbed: "tabbed";
Tabbed effect that matches the system dark preference Windows 11 Only
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2276
TabbedDark
TabbedDark: "tabbedDark";
Tabbed effect with dark mode but only if dark mode is enabled on the system Windows 11 Only
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2280
TabbedLight
TabbedLight: "tabbedLight";
Tabbed effect with light mode Windows 11 Only
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2284
Titlebar
Titlebar: "titlebar";
macOS 10.10+
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2200
Tooltip
Tooltip: "tooltip";
macOS 10.14+
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2240
UltraDark
UltraDark: "ultraDark";
macOS 10.14-
Deprecated
since macOS 10.14. Use a semantic material instead.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2196
UnderPageBackground
UnderPageBackground: "underPageBackground";
macOS 10.14+
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2252
UnderWindowBackground
UnderWindowBackground: "underWindowBackground";
macOS 10.14+
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2248
WindowBackground
WindowBackground: "windowBackground";
macOS 10.14+
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2228
EffectState
Window effect state macOS only
See
https://developer.apple.com/documentation/appkit/nsvisualeffectview/state
Since
2.0.0
Enumeration Members
Active
Active: "active";
Make window effect state always active macOS only
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2302
FollowsWindowActiveState
FollowsWindowActiveState: "followsWindowActiveState";
Make window effect state follow the window’s active state macOS only
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2298
Inactive
Inactive: "inactive";
Make window effect state always inactive macOS only
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2306
ProgressBarStatus
Enumeration Members
Error
Error: "error";
Error state. Treated as Normal on linux
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L220
Indeterminate
Indeterminate: "indeterminate";
Indeterminate state. Treated as Normal on Linux and macOS
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L212
None
None: "none";
Hide progress bar.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L204
Normal
Normal: "normal";
Normal state.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L208
Paused
Paused: "paused";
Paused state. Treated as Normal on Linux
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L216
ScrollBarStyle
The scrollbar style to use in the webview.
Platform-specific
Windows: This option must be given the same value for all webviews.
Since
2.8.0
Enumeration Members
Default
Default: "default";
The default scrollbar style for the webview.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2151
FluentOverlay
FluentOverlay: "fluentOverlay";
Fluent UI style overlay scrollbars. Windows Only
Requires WebView2 Runtime version 125.0.2535.41 or higher, does nothing on older versions, see https://learn.microsoft.com/en-us/microsoft-edge/webview2/release-notes/?tabs=dotnetcsharp#10253541
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2158
UserAttentionType
Attention type to request on a window.
Since
1.0.0
Enumeration Members
Critical
Critical: 1;
Platform-specific
- macOS: Bounces the dock icon until the application is in focus.
- Windows: Flashes both the window and the taskbar button until the application is in focus.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L129
Informational
Informational: 2;
Platform-specific
- macOS: Bounces the dock icon once.
- Windows: Flashes the taskbar button until the application is in focus.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L135
Classes
CloseRequestedEvent
Constructors
new CloseRequestedEvent()
new CloseRequestedEvent(event): CloseRequestedEvent
Parameters
| Parameter | Type |
|---|---|
event |
Event<unknown> |
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L145
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
event |
EventName |
Event name | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L140 |
id |
number |
Event identifier used to unlisten | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L142 |
Methods
isPreventDefault()
isPreventDefault(): boolean
Returns
boolean
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L154
preventDefault()
preventDefault(): void
Returns
void
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L150
Window
Create new window or get a handle to an existing one.
Windows are identified by a label a unique identifier that can be used to reference it later. It may only contain alphanumeric characters a-zA-Z plus the following special characters -, /, : and _.
Example
import { Window } from "@tauri-apps/api/window"
const appWindow = new Window('theUniqueLabel');
appWindow.once('tauri://created', function () {
// window successfully created
});
appWindow.once('tauri://error', function (e) {
// an error happened creating the window
});
// emit an event to the backend
await appWindow.emit("some-event", "data");
// listen to an event from the backend
const unlisten = await appWindow.listen("event-name", e => {});
unlisten();
Since
2.0.0
Extended by
Constructors
new Window()
new Window(label, options): Window
Creates a new Window.
Parameters
| Parameter | Type | Description |
|---|---|---|
label |
string |
The unique window label. Must be alphanumeric: a-zA-Z-/:_. |
options |
WindowOptions |
- |
Returns
The Window instance to communicate with the window.
Example
import { Window } from '@tauri-apps/api/window';
const appWindow = new Window('my-label');
appWindow.once('tauri://created', function () {
// window successfully created
});
appWindow.once('tauri://error', function (e) {
// an error happened creating the window
});
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L328
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
label |
string |
The window label. It is a unique identifier for the window, can be used to reference it later. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L306 |
listeners |
Record<string, EventCallback<any>[]> |
Local event listeners. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L309 |
Methods
activityName()
activityName(): Promise<string>
Returns
Promise<string>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L853
center()
center(): Promise<void>
Centers the window.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().center();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L877
clearEffects()
clearEffects(): Promise<void>
Clear any applied effects if possible.
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1265
close()
close(): Promise<void>
Closes the window.
Note this emits a closeRequested event so you can intercept it. To force window close, use Window.destroy.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().close();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1186
destroy()
destroy(): Promise<void>
Destroys the window. Behaves like Window.close but forces the window close instead of emitting a closeRequested event.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().destroy();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1202
emit()
emit<T>(event, payload?): Promise<void>
Emits an event to all targets.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
event |
string |
Event name. Must include only alphanumeric characters, -, /, : and _. |
payload? |
T |
Event payload. |
Returns
Promise<void>
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().emit('window-loaded', { loggedIn: true, token: 'authToken' });
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L479
emitTo()
emitTo<T>(
target,
event,
payload?): Promise<void>
Emits an event to all targets matching the given target.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
target |
string | EventTarget |
Label of the target Window/Webview/WebviewWindow or raw EventTarget object. |
event |
string |
Event name. Must include only alphanumeric characters, -, /, : and _. |
payload? |
T |
Event payload. |
Returns
Promise<void>
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().emit('main', 'window-loaded', { loggedIn: true, token: 'authToken' });
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L506
hide()
hide(): Promise<void>
Sets the window visibility to false.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().hide();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1168
innerPosition()
innerPosition(): Promise<PhysicalPosition>
The position of the top-left hand corner of the window’s client area relative to the top-left hand corner of the desktop.
Returns
The window’s inner position.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const position = await getCurrentWindow().innerPosition();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L567
innerSize()
innerSize(): Promise<PhysicalSize>
The physical size of the window’s client area. The client area is the content of the window, excluding the title bar and borders.
Returns
The window’s inner size.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const size = await getCurrentWindow().innerSize();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L600
isAlwaysOnTop()
isAlwaysOnTop(): Promise<boolean>
Whether the window is configured to be always on top of other windows or not.
Returns
Promise<boolean>
Whether the window is visible or not.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const alwaysOnTop = await getCurrentWindow().isAlwaysOnTop();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L847
isClosable()
isClosable(): Promise<boolean>
Gets the window’s native close button state.
Platform-specific
- iOS / Android: Unsupported.
Returns
Promise<boolean>
Whether the window’s native close button is enabled or not.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const closable = await getCurrentWindow().isClosable();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L780
isDecorated()
isDecorated(): Promise<boolean>
Gets the window’s current decorated state.
Returns
Promise<boolean>
Whether the window is decorated or not.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const decorated = await getCurrentWindow().isDecorated();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L701
isEnabled()
isEnabled(): Promise<boolean>
Whether the window is enabled or disabled.
Returns
Promise<boolean>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setEnabled(false);
Since
2.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L969
isFocused()
isFocused(): Promise<boolean>
Gets the window’s current focus state.
Returns
Promise<boolean>
Whether the window is focused or not.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const focused = await getCurrentWindow().isFocused();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L685
isFullscreen()
isFullscreen(): Promise<boolean>
Gets the window’s current fullscreen state.
Returns
Promise<boolean>
Whether the window is in fullscreen mode or not.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const fullscreen = await getCurrentWindow().isFullscreen();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L639
isMaximizable()
isMaximizable(): Promise<boolean>
Gets the window’s native maximize button state.
Platform-specific
- Linux / iOS / Android: Unsupported.
Returns
Promise<boolean>
Whether the window’s native maximize button is enabled or not.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const maximizable = await getCurrentWindow().isMaximizable();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L738
isMaximized()
isMaximized(): Promise<boolean>
Gets the window’s current maximized state.
Returns
Promise<boolean>
Whether the window is maximized or not.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const maximized = await getCurrentWindow().isMaximized();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L669
isMinimizable()
isMinimizable(): Promise<boolean>
Gets the window’s native minimize button state.
Platform-specific
- Linux / iOS / Android: Unsupported.
Returns
Promise<boolean>
Whether the window’s native minimize button is enabled or not.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const minimizable = await getCurrentWindow().isMinimizable();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L759
isMinimized()
isMinimized(): Promise<boolean>
Gets the window’s current minimized state.
Returns
Promise<boolean>
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const minimized = await getCurrentWindow().isMinimized();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L653
isResizable()
isResizable(): Promise<boolean>
Gets the window’s current resizable state.
Returns
Promise<boolean>
Whether the window is resizable or not.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const resizable = await getCurrentWindow().isResizable();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L717
isVisible()
isVisible(): Promise<boolean>
Gets the window’s current visible state.
Returns
Promise<boolean>
Whether the window is visible or not.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const visible = await getCurrentWindow().isVisible();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L796
listen()
listen<T>(event, handler): Promise<UnlistenFn>
Listen to an emitted event on this window.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
event |
EventName |
Event name. Must include only alphanumeric characters, -, /, : and _. |
handler |
EventCallback<T> |
Event handler. |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const unlisten = await getCurrentWindow().listen<string>('state-changed', (event) => {
console.log(`Got error: ${payload}`);
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L417
maximize()
maximize(): Promise<void>
Maximizes the window.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().maximize();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1072
minimize()
minimize(): Promise<void>
Minimizes the window.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().minimize();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1120
onCloseRequested()
onCloseRequested(handler): Promise<UnlistenFn>
Listen to window close requested. Emitted when the user requests to closes the window.
Parameters
| Parameter | Type |
|---|---|
handler |
(event) => void | Promise<void> |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { getCurrentWindow } from "@tauri-apps/api/window";
import { confirm } from '@tauri-apps/api/dialog';
const unlisten = await getCurrentWindow().onCloseRequested(async (event) => {
const confirmed = await confirm('Are you sure?');
if (!confirmed) {
// user did not confirm closing the window; let's prevent it
event.preventDefault();
}
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1927
onDragDropEvent()
onDragDropEvent(handler): Promise<UnlistenFn>
Listen to a file drop event. The listener is triggered when the user hovers the selected files on the webview, drops the files or cancels the operation.
Parameters
| Parameter | Type |
|---|---|
handler |
EventCallback<DragDropEvent> |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { getCurrentWindow } from "@tauri-apps/api/webview";
const unlisten = await getCurrentWindow().onDragDropEvent((event) => {
if (event.payload.type === 'over') {
console.log('User hovering', event.payload.position);
} else if (event.payload.type === 'drop') {
console.log('User dropped', event.payload.paths);
} else {
console.log('File drop cancelled');
}
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1965
onFocusChanged()
onFocusChanged(handler): Promise<UnlistenFn>
Listen to window focus change.
Parameters
| Parameter | Type |
|---|---|
handler |
EventCallback<boolean> |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { getCurrentWindow } from "@tauri-apps/api/window";
const unlisten = await getCurrentWindow().onFocusChanged(({ payload: focused }) => {
console.log('Focus changed, window is focused? ' + focused);
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2043
onMoved()
onMoved(handler): Promise<UnlistenFn>
Listen to window move.
Parameters
| Parameter | Type |
|---|---|
handler |
EventCallback<PhysicalPosition> |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { getCurrentWindow } from "@tauri-apps/api/window";
const unlisten = await getCurrentWindow().onMoved(({ payload: position }) => {
console.log('Window moved', position);
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1898
onResized()
onResized(handler): Promise<UnlistenFn>
Listen to window resize.
Parameters
| Parameter | Type |
|---|---|
handler |
EventCallback<PhysicalSize> |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { getCurrentWindow } from "@tauri-apps/api/window";
const unlisten = await getCurrentWindow().onResized(({ payload: size }) => {
console.log('Window resized', size);
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1874
onScaleChanged()
onScaleChanged(handler): Promise<UnlistenFn>
Listen to window scale change. Emitted when the window’s scale factor has changed. The following user actions can cause DPI changes:
- Changing the display’s resolution.
- Changing the display’s scale factor (e.g. in Control Panel on Windows).
- Moving the window to a display with a different scale factor.
Parameters
| Parameter | Type |
|---|---|
handler |
EventCallback<ScaleFactorChanged> |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { getCurrentWindow } from "@tauri-apps/api/window";
const unlisten = await getCurrentWindow().onScaleChanged(({ payload }) => {
console.log('Scale changed', payload.scaleFactor, payload.size);
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2083
onThemeChanged()
onThemeChanged(handler): Promise<UnlistenFn>
Listen to the system theme change.
Parameters
| Parameter | Type |
|---|---|
handler |
EventCallback<Theme> |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { getCurrentWindow } from "@tauri-apps/api/window";
const unlisten = await getCurrentWindow().onThemeChanged(({ payload: theme }) => {
console.log('New theme: ' + theme);
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2109
once()
once<T>(event, handler): Promise<UnlistenFn>
Listen to an emitted event on this window only once.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
event |
EventName |
Event name. Must include only alphanumeric characters, -, /, : and _. |
handler |
EventCallback<T> |
Event handler. |
Returns
A promise resolving to a function to unlisten to the event. Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const unlisten = await getCurrentWindow().once<null>('initialized', (event) => {
console.log(`Window initialized!`);
});
// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
unlisten();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L452
outerPosition()
outerPosition(): Promise<PhysicalPosition>
The position of the top-left hand corner of the window relative to the top-left hand corner of the desktop.
Returns
The window’s outer position.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const position = await getCurrentWindow().outerPosition();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L583
outerSize()
outerSize(): Promise<PhysicalSize>
The physical size of the entire window. These dimensions include the title bar and borders. If you don’t want that (and you usually don’t), use inner_size instead.
Returns
The window’s outer size.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const size = await getCurrentWindow().outerSize();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L620
requestUserAttention()
requestUserAttention(requestType): Promise<void>
Requests user attention to the window, this has no effect if the application is already focused. How requesting for user attention manifests is platform dependent, see UserAttentionType for details.
Providing null will unset the request for user attention. Unsetting the request for user attention might not be done automatically by the WM when the window receives input.
Platform-specific
- macOS:
nullhas no effect. - Linux: Urgency levels have the same effect.
Parameters
| Parameter | Type |
|---|---|
requestType |
null | UserAttentionType |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().requestUserAttention();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L903
scaleFactor()
scaleFactor(): Promise<number>
The scale factor that can be used to map physical pixels to logical pixels.
Returns
Promise<number>
The window’s monitor scale factor.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const factor = await getCurrentWindow().scaleFactor();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L551
sceneIdentifier()
sceneIdentifier(): Promise<string>
Returns
Promise<string>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L859
setAlwaysOnBottom()
setAlwaysOnBottom(alwaysOnBottom): Promise<void>
Whether the window should always be below other windows.
Parameters
| Parameter | Type | Description |
|---|---|---|
alwaysOnBottom |
boolean |
Whether the window should always be below other windows or not. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setAlwaysOnBottom(true);
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1301
setAlwaysOnTop()
setAlwaysOnTop(alwaysOnTop): Promise<void>
Whether the window should always be on top of other windows.
Parameters
| Parameter | Type | Description |
|---|---|---|
alwaysOnTop |
boolean |
Whether the window should always be on top of other windows or not. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setAlwaysOnTop(true);
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1283
setBackgroundColor()
setBackgroundColor(color): Promise<void>
Sets the window background color.
Platform-specific:
- Windows: alpha channel is ignored.
- iOS / Android: Unsupported.
Parameters
| Parameter | Type |
|---|---|
color |
Color |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Since
2.1.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1635
setBadgeCount()
setBadgeCount(count?): Promise<void>
Sets the badge count. It is app wide and not specific to this window.
Platform-specific
- Windows: Unsupported. Use @{linkcode Window.setOverlayIcon} instead.
Parameters
| Parameter | Type | Description |
|---|---|---|
count? |
number |
The badge count. Use undefined to remove the badge. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setBadgeCount(5);
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1727
setBadgeLabel()
setBadgeLabel(label?): Promise<void>
Sets the badge cont macOS only.
Parameters
| Parameter | Type | Description |
|---|---|---|
label? |
string |
The badge label. Use undefined to remove the badge. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setBadgeLabel("Hello");
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1746
setClosable()
setClosable(closable): Promise<void>
Sets whether the window’s native close button is enabled or not.
Platform-specific
- Linux: GTK+ will do its best to convince the window manager not to show a close button. Depending on the system, this function may not have any effect when called on a window that is already visible
- iOS / Android: Unsupported.
Parameters
| Parameter | Type |
|---|---|
closable |
boolean |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setClosable(false);
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1037
setContentProtected()
setContentProtected(protected_): Promise<void>
Prevents the window contents from being captured by other apps.
Parameters
| Parameter | Type |
|---|---|
protected_ |
boolean |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setContentProtected(true);
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1318
setCursorGrab()
setCursorGrab(grab): Promise<void>
Grabs the cursor, preventing it from leaving the window.
There’s no guarantee that the cursor will be hidden. You should hide it by yourself if you want so.
Platform-specific
- Linux: Unsupported.
- macOS: This locks the cursor in a fixed location, which looks visually awkward.
Parameters
| Parameter | Type | Description |
|---|---|---|
grab |
boolean |
true to grab the cursor icon, false to release it. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setCursorGrab(true);
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1574
setCursorIcon()
setCursorIcon(icon): Promise<void>
Modifies the cursor icon of the window.
Parameters
| Parameter | Type | Description |
|---|---|---|
icon |
CursorIcon |
The new cursor icon. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setCursorIcon('help');
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1616
setCursorPosition()
setCursorPosition(position): Promise<void>
Changes the position of the cursor in window coordinates.
Parameters
| Parameter | Type | Description |
|---|---|---|
position |
LogicalPosition | PhysicalPosition | Position |
The new cursor position. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow, LogicalPosition } from '@tauri-apps/api/window';
await getCurrentWindow().setCursorPosition(new LogicalPosition(600, 300));
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1650
setCursorVisible()
setCursorVisible(visible): Promise<void>
Modifies the cursor’s visibility.
Platform-specific
- Windows: The cursor is only hidden within the confines of the window.
- macOS: The cursor is hidden as long as the window has input focus, even if the cursor is outside of the window.
Parameters
| Parameter | Type | Description |
|---|---|---|
visible |
boolean |
If false, this will hide the cursor. If true, this will show the cursor. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setCursorVisible(false);
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1598
setDecorations()
setDecorations(decorations): Promise<void>
Whether the window should have borders and bars.
Parameters
| Parameter | Type | Description |
|---|---|---|
decorations |
boolean |
Whether the window should have borders and bars. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setDecorations(false);
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1219
setEffects()
setEffects(effects): Promise<void>
Set window effects.
Parameters
| Parameter | Type |
|---|---|
effects |
Effects |
Returns
Promise<void>
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1255
setEnabled()
setEnabled(enabled): Promise<void>
Enable or disable the window.
Parameters
| Parameter | Type |
|---|---|
enabled |
boolean |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setEnabled(false);
Since
2.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L950
setFocus()
setFocus(): Promise<void>
Bring the window to front and focus.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setFocus();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1476
setFocusable()
setFocusable(focusable): Promise<void>
Sets whether the window can be focused.
Platform-specific
- macOS: If the window is already focused, it is not possible to unfocus it after calling
set_focusable(false). In this case, you might consider calling Window.setFocus but it will move the window to the back i.e. at the bottom in terms of z-order.
Parameters
| Parameter | Type | Description |
|---|---|---|
focusable |
boolean |
Whether the window can be focused. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setFocusable(true);
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1499
setFullscreen()
setFullscreen(fullscreen): Promise<void>
Sets the window fullscreen state.
Parameters
| Parameter | Type | Description |
|---|---|---|
fullscreen |
boolean |
Whether the window should go to fullscreen or not. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setFullscreen(true);
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1443
setIcon()
setIcon(icon): Promise<void>
Sets the window icon.
Parameters
| Parameter | Type | Description |
|---|---|---|
icon |
| string | Uint8Array | number[] | ArrayBuffer | Image |
Icon bytes or path to the icon file. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setIcon('/tauri/awesome.png');
Note that you may need the image-ico or image-png Cargo features to use this API. To enable it, change your Cargo.toml file:
[dependencies]
tauri = { version = "...", features = ["...", "image-png"] }
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1524
setIgnoreCursorEvents()
setIgnoreCursorEvents(ignore): Promise<void>
Changes the cursor events behavior.
Parameters
| Parameter | Type | Description |
|---|---|---|
ignore |
boolean |
true to ignore the cursor events; false to process them as usual. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setIgnoreCursorEvents(true);
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1671
setMaxSize()
setMaxSize(size): Promise<void>
Sets the window maximum inner size. If the size argument is undefined, the constraint is unset.
Parameters
| Parameter | Type | Description |
|---|---|---|
size |
| undefined | null | LogicalSize | PhysicalSize | Size |
The logical or physical inner size, or null to unset the constraint. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow, LogicalSize } from '@tauri-apps/api/window';
await getCurrentWindow().setMaxSize(new LogicalSize(600, 500));
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1374
setMaximizable()
setMaximizable(maximizable): Promise<void>
Sets whether the window’s native maximize button is enabled or not. If resizable is set to false, this setting is ignored.
Platform-specific
- macOS: Disables the “zoom” button in the window titlebar, which is also used to enter fullscreen mode.
- Linux / iOS / Android: Unsupported.
Parameters
| Parameter | Type |
|---|---|
maximizable |
boolean |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setMaximizable(false);
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L992
setMinSize()
setMinSize(size): Promise<void>
Sets the window minimum inner size. If the size argument is not provided, the constraint is unset.
Parameters
| Parameter | Type | Description |
|---|---|---|
size |
| undefined | null | LogicalSize | PhysicalSize | Size |
The logical or physical inner size, or null to unset the constraint. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow, PhysicalSize } from '@tauri-apps/api/window';
await getCurrentWindow().setMinSize(new PhysicalSize(600, 500));
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1354
setMinimizable()
setMinimizable(minimizable): Promise<void>
Sets whether the window’s native minimize button is enabled or not.
Platform-specific
- Linux / iOS / Android: Unsupported.
Parameters
| Parameter | Type |
|---|---|
minimizable |
boolean |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setMinimizable(false);
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1014
setOverlayIcon()
setOverlayIcon(icon?): Promise<void>
Sets the overlay icon. Windows only The overlay icon can be set for every window.
Note that you may need the image-ico or image-png Cargo features to use this API. To enable it, change your Cargo.toml file:
[dependencies]
tauri = { version = "...", features = ["...", "image-png"] }
Parameters
| Parameter | Type | Description |
|---|---|---|
icon? |
| string | Uint8Array | number[] | ArrayBuffer | Image |
Icon bytes or path to the icon file. Use undefined to remove the overlay icon. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setOverlayIcon("/tauri/awesome.png");
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1775
setPosition()
setPosition(position): Promise<void>
Sets the window outer position.
Parameters
| Parameter | Type | Description |
|---|---|---|
position |
LogicalPosition | PhysicalPosition | Position |
The new position, in logical or physical pixels. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow, LogicalPosition } from '@tauri-apps/api/window';
await getCurrentWindow().setPosition(new LogicalPosition(600, 500));
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1423
setProgressBar()
setProgressBar(state): Promise<void>
Sets the taskbar progress state.
Platform-specific
- Linux / macOS: Progress bar is app-wide and not specific to this window.
- Linux: Only supported desktop environments with
libunity(e.g. GNOME).
Parameters
| Parameter | Type |
|---|---|
state |
ProgressBarState |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow, ProgressBarStatus } from '@tauri-apps/api/window';
await getCurrentWindow().setProgressBar({
status: ProgressBarStatus.Normal,
progress: 50,
});
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1803
setResizable()
setResizable(resizable): Promise<void>
Updates the window resizable flag.
Parameters
| Parameter | Type |
|---|---|
resizable |
boolean |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setResizable(false);
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L931
setShadow()
setShadow(enable): Promise<void>
Whether or not the window should have shadow.
Platform-specific
-
Windows:
falsehas no effect on decorated window, shadows are always ON.truewill make undecorated window have a 1px white border, and on Windows 11, it will have a rounded corners.
-
Linux: Unsupported.
Parameters
| Parameter | Type |
|---|---|
enable |
boolean |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setShadow(false);
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1245
setSimpleFullscreen()
setSimpleFullscreen(fullscreen): Promise<void>
On macOS, Toggles a fullscreen mode that doesn’t require a new macOS space. Returns a boolean indicating whether the transition was successful (this won’t work if the window was already in the native fullscreen). This is how fullscreen used to work on macOS in versions before Lion. And allows the user to have a fullscreen window without using another space or taking control over the entire monitor.
On other platforms, this is the same as Window.setFullscreen.
Parameters
| Parameter | Type | Description |
|---|---|---|
fullscreen |
boolean |
Whether the window should go to simple fullscreen or not. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1459
setSize()
setSize(size): Promise<void>
Resizes the window with a new inner size.
Parameters
| Parameter | Type | Description |
|---|---|---|
size |
LogicalSize | PhysicalSize | Size |
The logical or physical inner size. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow, LogicalSize } from '@tauri-apps/api/window';
await getCurrentWindow().setSize(new LogicalSize(600, 500));
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1336
setSizeConstraints()
setSizeConstraints(constraints): Promise<void>
Sets the window inner size constraints.
Parameters
| Parameter | Type | Description |
|---|---|---|
constraints |
undefined | null | WindowSizeConstraints |
The logical or physical inner size, or null to unset the constraint. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setSizeConstraints({ minWidth: 300 });
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1394
setSkipTaskbar()
setSkipTaskbar(skip): Promise<void>
Whether the window icon should be hidden from the taskbar or not.
Platform-specific
- macOS: Unsupported.
Parameters
| Parameter | Type | Description |
|---|---|---|
skip |
boolean |
true to hide window icon, false to show it. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setSkipTaskbar(true);
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1548
setTheme()
setTheme(theme?): Promise<void>
Set window theme, pass in null or undefined to follow system theme
Platform-specific
- Linux / macOS: Theme is app-wide and not specific to this window.
- iOS / Android: Unsupported.
Parameters
| Parameter | Type |
|---|---|
theme? |
null | Theme |
Returns
Promise<void>
Since
2.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1848
setTitle()
setTitle(title): Promise<void>
Sets the window title.
Parameters
| Parameter | Type | Description |
|---|---|---|
title |
string |
The new title |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().setTitle('Tauri');
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1055
setTitleBarStyle()
setTitleBarStyle(style): Promise<void>
Sets the title bar style. macOS only.
Parameters
| Parameter | Type |
|---|---|
style |
TitleBarStyle |
Returns
Promise<void>
Since
2.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1831
setVisibleOnAllWorkspaces()
setVisibleOnAllWorkspaces(visible): Promise<void>
Sets whether the window should be visible on all workspaces or virtual desktops.
Platform-specific
- Windows / iOS / Android: Unsupported.
Parameters
| Parameter | Type |
|---|---|
visible |
boolean |
Returns
Promise<void>
Since
2.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1819
show()
show(): Promise<void>
Sets the window visibility to true.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().show();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1152
startDragging()
startDragging(): Promise<void>
Starts dragging the window.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().startDragging();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1688
startResizeDragging()
startResizeDragging(direction): Promise<void>
Starts resize-dragging the window.
Parameters
| Parameter | Type |
|---|---|
direction |
ResizeDirection |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().startResizeDragging();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1704
theme()
theme(): Promise<null | Theme>
Gets the window’s current theme.
Platform-specific
- macOS: Theme was introduced on macOS 10.14. Returns
lighton macOS 10.13 and below.
Returns
The window theme.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const theme = await getCurrentWindow().theme();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L831
title()
title(): Promise<string>
Gets the window’s current title.
Returns
Promise<string>
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
const title = await getCurrentWindow().title();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L810
toggleMaximize()
toggleMaximize(): Promise<void>
Toggles the window maximized state.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().toggleMaximize();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1104
unmaximize()
unmaximize(): Promise<void>
Unmaximizes the window.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().unmaximize();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1088
unminimize()
unminimize(): Promise<void>
Unminimizes the window.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { getCurrentWindow } from '@tauri-apps/api/window';
await getCurrentWindow().unminimize();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L1136
getAll()
static getAll(): Promise<Window[]>
Gets a list of instances of Window for all available windows.
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L375
getByLabel()
static getByLabel(label): Promise<null | Window>
Gets the Window associated with the given label.
Parameters
| Parameter | Type | Description |
|---|---|---|
label |
string |
The window label. |
Returns
The Window instance to communicate with the window or null if the window doesn’t exist.
Example
import { Window } from '@tauri-apps/api/window';
const mainWindow = Window.getByLabel('main');
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L361
getCurrent()
static getCurrent(): Window
Get an instance of Window for the current window.
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L368
getFocusedWindow()
static getFocusedWindow(): Promise<null | Window>
Gets the focused window.
Returns
The Window instance or undefined if there is not any focused window.
Example
import { Window } from '@tauri-apps/api/window';
const focusedWindow = Window.getFocusedWindow();
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L389
Interfaces
Effects
The window effects configuration object
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
color? |
Color |
Window effect color. Affects Effect.Blur and Effect.Acrylic only on Windows 10 v1903+. Doesn’t have any effect on Windows 7 or Windows 11. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2331 |
effects |
Effect[] |
List of Window effects to apply to the Window. Conflicting effects will apply the first one and ignore the rest. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2318 |
radius? |
number |
Window effect corner radius macOS Only | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2326 |
state? |
EffectState |
Window effect state macOS Only | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2322 |
Monitor
Allows you to retrieve information about a given monitor.
Since
1.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
name |
null | string |
Human-readable name of the monitor | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L49 |
position |
PhysicalPosition |
the Top-left corner position of the monitor relative to the larger full screen area, in physical pixels. Note that window creation options such as x, y, width and height expect logical pixels, so convert with Monitor.scaleFactor first: import { currentMonitor } from '@tauri-apps/api/window'; import { WebviewWindow } from '@tauri-apps/api/webviewWindow'; const monitor = await currentMonitor(); if (monitor) { const position = monitor.position.toLogical(monitor.scaleFactor); const webview = new WebviewWindow('my-label', { x: position.x, y: position.y }); } |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L75 |
scaleFactor |
number |
The scale factor that can be used to map physical pixels to logical pixels, e.g. monitor.position.toLogical(monitor.scaleFactor). |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L90 |
size |
PhysicalSize |
The monitor’s resolution in physical pixels. Use Monitor.scaleFactor to convert to logical pixels: const logicalSize = monitor.size.toLogical(monitor.scaleFactor); |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L58 |
workArea |
object |
The monitor’s work area (the monitor area excluding taskbars and docks) in physical pixels. Use Monitor.scaleFactor to convert to logical pixels as shown in Monitor.position. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L82 |
workArea.position |
PhysicalPosition |
- | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L83 |
workArea.size |
PhysicalSize |
- | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L84 |
ProgressBarState
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
progress? |
number |
The progress bar progress. This can be a value ranging from 0 to 100 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L238 |
status? |
ProgressBarStatus |
The progress bar status. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L234 |
ScaleFactorChanged
The payload for the scaleChange event.
Since
1.0.2
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
scaleFactor |
number |
The new window scale factor. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L113 |
size |
PhysicalSize |
The new window size | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L115 |
WindowOptions
Configuration for the window to create.
Since
1.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
activityName? |
string |
The name of the Android activity to create for this window. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2568 |
allowLinkPreview? |
boolean |
on macOS and iOS there is a link preview on long pressing links, this is enabled by default. see https://docs.rs/objc2-web-kit/latest/objc2_web_kit/struct.WKWebView.html#method.allowsLinkPreview | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2542 |
alwaysOnBottom? |
boolean |
Whether the window should always be below other windows. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2408 |
alwaysOnTop? |
boolean |
Whether the window should always be on top of other windows or not. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2406 |
backgroundColor? |
Color |
Set the window background color. Platform-specific: - Android / iOS: Unsupported. - Windows: alpha channel is ignored. Since 2.1.0 | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2519 |
backgroundThrottling? |
BackgroundThrottlingPolicy |
Change the default background throttling behaviour. ## Platform-specific - Linux / Windows / Android: Unsupported. Workarounds like a pending WebLock transaction might suffice. - iOS: Supported since version 17.0+. - macOS: Supported since version 14.0+. see https://github.com/tauri-apps/tauri/issues/5250#issuecomment-2569380578 Since 2.3.0 | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2533 |
center? |
boolean |
Show window in the center of the screen.. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2349 |
closable? |
boolean |
Whether the window’s native close button is enabled or not. Defaults to true. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2474 |
contentProtected? |
boolean |
Prevents the window contents from being captured by other apps. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2410 |
createdByActivityName? |
string |
The name of the Android activity that is creating this webview window. This is important to determine which stack the activity will belong to. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2574 |
decorations? |
boolean |
Whether the window should have borders and bars or not. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2404 |
disableInputAccessoryView? |
boolean |
Allows disabling the input accessory view on iOS. The accessory view is the view that appears above the keyboard when a text input element is focused. It usually displays a view with “Done”, “Next” buttons. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2549 |
focus? |
boolean |
Whether the window will be initially focused or not. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2388 |
focusable? |
boolean |
Whether the window can be focused or not. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2390 |
fullscreen? |
boolean |
Whether the window is in fullscreen mode or not. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2386 |
height? |
number |
The initial height in logical pixels. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2357 |
hiddenTitle? |
boolean |
If true, sets the window title to be hidden on macOS. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2455 |
javascriptDisabled? |
boolean |
Whether we should disable JavaScript code execution on the webview or not. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2537 |
maxHeight? |
number |
The maximum height in logical pixels. Only applies if maxWidth is also set. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2365 |
maxWidth? |
number |
The maximum width in logical pixels. Only applies if maxHeight is also set. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2363 |
maximizable? |
boolean |
Whether the window’s native maximize button is enabled or not. Defaults to true. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2466 |
maximized? |
boolean |
Whether the window should be maximized upon creation or not. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2400 |
minHeight? |
number |
The minimum height in logical pixels. Only applies if minWidth is also set. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2361 |
minWidth? |
number |
The minimum width in logical pixels. Only applies if minHeight is also set. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2359 |
minimizable? |
boolean |
Whether the window’s native minimize button is enabled or not. Defaults to true. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2470 |
noRedirectionBitmap? |
boolean |
This sets WS_EX_NOREDIRECTIONBITMAP. This can avoid the white flash that may appear before the webview content is rendered when using a transparent window. Windows only. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2419 |
parent? |
string | Window | WebviewWindow |
Sets a parent to the window to be created. Can be either a Window or a label of the window. Platform-specific - Windows: This sets the passed parent as an owner window to the window to be created. From MSDN owned windows docs: - An owned window is always above its owner in the z-order. - The system automatically destroys an owned window when its owner is destroyed. - An owned window is hidden when its owner is minimized. - Linux: This makes the new window transient for parent, see https://docs.gtk.org/gtk3/method.Window.set_transient_for.html - macOS: This adds the window as a child of parent, see https://developer.apple.com/documentation/appkit/nswindow/1419152-addchildwindow?language=objc |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2488 |
preventOverflow? |
boolean | PreventOverflowMargin |
Prevent the window from overflowing the working area (e.g. monitor size - taskbar size) on creation, which means the window size will be limited to monitor size - taskbar size Can either be set to true or to a PreventOverflowMargin object to set an additional margin that should be considered to determine the working area (in this case the window size will be limited to monitor size - taskbar size - margin) NOTE: The overflow check is only performed on window creation, resizes can still overflow Platform-specific - iOS / Android: Unsupported. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2380 |
requestedBySceneIdentifier? |
string |
Sets the identifier of the UIScene that is requesting the creation of this new scene, establishing a relationship between the two scenes. By default the system uses the foreground scene. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2581 |
resizable? |
boolean |
Whether the window is resizable or not. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2382 |
scrollBarStyle? |
ScrollBarStyle |
Specifies the native scrollbar style to use with the webview. CSS styles that modify the scrollbar are applied on top of the native appearance configured here. Defaults to default, which is the browser default. ## Platform-specific - Windows: - fluentOverlay requires WebView2 Runtime version 125.0.2535.41 or higher, and does nothing on older versions. - This option must be given the same value for all webviews. - Linux / Android / iOS / macOS: Unsupported. Only supports Default and performs no operation. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2564 |
shadow? |
boolean |
Whether or not the window has shadow. Platform-specific - Windows: - false has no effect on decorated window, shadows are always ON. - true will make undecorated window have a 1px white border, and on Windows 11, it will have a rounded corners. - Linux: Unsupported. Since 2.0.0 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2433 |
skipTaskbar? |
boolean |
Whether or not the window icon should be added to the taskbar. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2412 |
tabbingIdentifier? |
string |
Defines the window tabbing identifier on macOS. Windows with the same tabbing identifier will be grouped together. If the tabbing identifier is not set, automatic tabbing will be disabled. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2462 |
theme? |
Theme |
The initial window theme. Defaults to the system theme. Only implemented on Windows and macOS 10.14+. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2439 |
title? |
string |
Window title. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2384 |
titleBarStyle? |
TitleBarStyle |
The style of the macOS title bar. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2443 |
trafficLightPosition? |
LogicalPosition |
The position of the window controls on macOS. Requires titleBarStyle: 'overlay' and decorations: true. Since 2.4.0 |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2451 |
transparent? |
boolean |
Whether the window is transparent or not. Note that on macOS this requires the macos-private-api feature flag, enabled under tauri.conf.json > app > macOSPrivateApi. WARNING: Using private APIs on macOS prevents your application from being accepted to the App Store. On Windows, using noRedirectionBitmap can help avoid a white flash when creating a transparent window. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2398 |
visible? |
boolean |
Whether the window should be immediately visible upon creation or not. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2402 |
visibleOnAllWorkspaces? |
boolean |
Whether the window should be visible on all workspaces or virtual desktops. Platform-specific - Windows / iOS / Android: Unsupported. Since 2.0.0 | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2497 |
width? |
number |
The initial width in logical pixels. | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2355 |
windowEffects? |
Effects |
Window effects. Requires the window to be transparent. Platform-specific: - Windows: If using decorations or shadows, you may want to try this workaround https://github.com/tauri-apps/tao/issues/72#issuecomment-975607891 - Linux: Unsupported | Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2508 |
x? |
number |
The initial vertical position in logical pixels. Only applies if y is also set. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2351 |
y? |
number |
The initial horizontal position in logical pixels. Only applies if x is also set. |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2353 |
WindowSizeConstraints
Properties
| Property | Type | Defined in |
|---|---|---|
maxHeight? |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L227 |
maxWidth? |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L226 |
minHeight? |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L225 |
minWidth? |
number |
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L224 |
Type Aliases
CursorIcon
type CursorIcon:
| "default"
| "crosshair"
| "hand"
| "arrow"
| "move"
| "text"
| "wait"
| "help"
| "progress"
| "notAllowed"
| "contextMenu"
| "cell"
| "verticalText"
| "alias"
| "copy"
| "noDrop"
| "grab"
| "grabbing"
| "allScroll"
| "zoomIn"
| "zoomOut"
| "eResize"
| "nResize"
| "neResize"
| "nwResize"
| "sResize"
| "seResize"
| "swResize"
| "wResize"
| "ewResize"
| "nsResize"
| "neswResize"
| "nwseResize"
| "colResize"
| "rowResize";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L159
Theme
type Theme: "light" | "dark";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L93
TitleBarStyle
type TitleBarStyle: "visible" | "transparent" | "overlay";
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L94
Functions
availableMonitors()
function availableMonitors(): Promise<Monitor[]>
Returns the list of all the monitors available on the system.
Returns
Example
import { availableMonitors } from '@tauri-apps/api/window';
const monitors = await availableMonitors();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2660
currentMonitor()
function currentMonitor(): Promise<Monitor | null>
Returns the monitor on which the window currently resides. Returns null if current monitor can’t be detected.
Returns
Example
import { currentMonitor } from '@tauri-apps/api/window';
const monitor = await currentMonitor();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2610
cursorPosition()
function cursorPosition(): Promise<PhysicalPosition>
Get the cursor position relative to the top-left hand corner of the desktop.
Note that the top-left hand corner of the desktop is not necessarily the same as the screen. If the user uses a desktop with multiple monitors, the top-left hand corner of the desktop is the top-left hand corner of the main monitor on Windows and macOS or the top-left of the leftmost monitor on X11.
The coordinates can be negative if the top-left hand corner of the window is outside of the visible screen region.
Returns
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2676
getAllWindows()
function getAllWindows(): Promise<Window[]>
Gets a list of instances of Window for all available windows.
Returns
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L258
getCurrentWindow()
function getCurrentWindow(): Window
Get an instance of Window for the current window.
Returns
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L246
monitorFromPoint()
function monitorFromPoint(x, y): Promise<Monitor | null>
Returns the monitor that contains the given point. Returns null if can’t find any.
Parameters
| Parameter | Type |
|---|---|
x |
number |
y |
number |
Returns
Example
import { monitorFromPoint } from '@tauri-apps/api/window';
const monitor = await monitorFromPoint(100.0, 200.0);
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2643
primaryMonitor()
function primaryMonitor(): Promise<Monitor | null>
Returns the primary monitor of the system. Returns null if it can’t identify any monitor as a primary one.
Returns
Example
import { primaryMonitor } from '@tauri-apps/api/window';
const monitor = await primaryMonitor();
Since
1.0.0
Source: https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/window.ts#L2627
@tauri-apps/plugin-autostart
Functions
disable()
function disable(): Promise<void>
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/autostart/guest-js/index.ts#L15
enable()
function enable(): Promise<void>
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/autostart/guest-js/index.ts#L11
isEnabled()
function isEnabled(): Promise<boolean>
Returns
Promise<boolean>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/autostart/guest-js/index.ts#L7
@tauri-apps/plugin-barcode-scanner
Enumerations
Format
Enumeration Members
Aztec
Aztec: "AZTEC";
Codabar
Codabar: "CODABAR";
Not supported on iOS.
Code128
Code128: "CODE_128";
Code39
Code39: "CODE_39";
Code93
Code93: "CODE_93";
DataMatrix
DataMatrix: "DATA_MATRIX";
EAN13
EAN13: "EAN_13";
EAN8
EAN8: "EAN_8";
GS1DataBar
GS1DataBar: "GS1_DATA_BAR";
Not supported on Android. Requires iOS 15.4+
GS1DataBarExpanded
GS1DataBarExpanded: "GS1_DATA_BAR_EXPANDED";
Not supported on Android. Requires iOS 15.4+
GS1DataBarLimited
GS1DataBarLimited: "GS1_DATA_BAR_LIMITED";
Not supported on Android. Requires iOS 15.4+
ITF
ITF: "ITF";
PDF417
PDF417: "PDF_417";
QRCode
QRCode: "QR_CODE";
UPC_A
UPC_A: "UPC_A";
Not supported on iOS.
UPC_E
UPC_E: "UPC_E";
Interfaces
ScanOptions
Properties
| Property | Type | Defined in |
|---|---|---|
cameraDirection? |
"back" | "front" |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/barcode-scanner/guest-js/index.ts#L48 |
formats? |
Format[] |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/barcode-scanner/guest-js/index.ts#L49 |
windowed? |
boolean |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/barcode-scanner/guest-js/index.ts#L50 |
Scanned
Properties
| Property | Type | Defined in |
|---|---|---|
bounds |
unknown |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/barcode-scanner/guest-js/index.ts#L56 |
content |
string |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/barcode-scanner/guest-js/index.ts#L54 |
format |
Format |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/barcode-scanner/guest-js/index.ts#L55 |
Type Aliases
PermissionState
type PermissionState: "granted" | "denied" | "prompt" | "prompt-with-rationale";
Source: undefined
Functions
cancel()
function cancel(): Promise<void>
Cancel the current scan process.
Returns
Promise<void>
checkPermissions()
function checkPermissions(): Promise<PermissionState>
Get permission state.
Returns
Promise<PermissionState>
openAppSettings()
function openAppSettings(): Promise<void>
Open application settings. Useful if permission was denied and the user must manually enable it.
Returns
Promise<void>
requestPermissions()
function requestPermissions(): Promise<PermissionState>
Request permissions to use the camera.
Returns
Promise<PermissionState>
scan()
function scan(options?): Promise<Scanned>
Start scanning.
Parameters
| Parameter | Type | Description |
|---|---|---|
options? |
ScanOptions |
Returns
@tauri-apps/plugin-biometric
Enumerations
BiometryType
Enumeration Members
FaceID
FaceID: 2;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/biometric/guest-js/index.ts#L12
Iris
Iris: 3;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/biometric/guest-js/index.ts#L14
None
None: 0;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/biometric/guest-js/index.ts#L8
TouchID
TouchID: 1;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/biometric/guest-js/index.ts#L10
Interfaces
AuthOptions
Properties
| Property | Type | Defined in |
|---|---|---|
allowDeviceCredential? |
boolean |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/biometric/guest-js/index.ts#L36 |
cancelTitle? |
string |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/biometric/guest-js/index.ts#L37 |
confirmationRequired? |
boolean |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/biometric/guest-js/index.ts#L45 |
fallbackTitle? |
string |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/biometric/guest-js/index.ts#L40 |
maxAttemps? |
number |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/biometric/guest-js/index.ts#L46 |
subtitle? |
string |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/biometric/guest-js/index.ts#L44 |
title? |
string |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/biometric/guest-js/index.ts#L43 |
Status
Properties
| Property | Type | Defined in |
|---|---|---|
biometryType |
BiometryType |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/biometric/guest-js/index.ts#L19 |
error? |
string |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/biometric/guest-js/index.ts#L20 |
errorCode? |
| "appCancel" | "authenticationFailed" | "invalidContext" | "notInteractive" | "passcodeNotSet" | "systemCancel" | "userCancel" | "userFallback" | "biometryLockout" | "biometryNotAvailable" | "biometryNotEnrolled" |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/biometric/guest-js/index.ts#L21 |
isAvailable |
boolean |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/biometric/guest-js/index.ts#L18 |
Functions
authenticate()
function authenticate(reason, options?): Promise<void>
Prompts the user for authentication using the system interface (touchID, faceID or Android Iris). Rejects if the authentication fails.
import { authenticate } from "@tauri-apps/plugin-biometric";
await authenticate('Open your wallet');
Parameters
| Parameter | Type | Description |
|---|---|---|
reason |
string |
|
options? |
AuthOptions |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/biometric/guest-js/index.ts#L69
checkStatus()
function checkStatus(): Promise<Status>
Checks if the biometric authentication is available.
Returns
a promise resolving to an object containing all the information about the status of the biometry.
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/biometric/guest-js/index.ts#L53
@tauri-apps/plugin-cli
Parse arguments from your Command Line Interface.
Interfaces
ArgMatch
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
occurrences |
number |
Number of occurrences | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/cli/guest-js/index.ts#L26 |
value |
null | string | boolean | string[] |
string if takes value boolean if flag string[] or null if takes multiple values | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/cli/guest-js/index.ts#L22 |
CliMatches
Since
2.0.0
Properties
| Property | Type | Defined in |
|---|---|---|
args |
Record<string, ArgMatch> |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/cli/guest-js/index.ts#L41 |
subcommand |
null | SubcommandMatch |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/cli/guest-js/index.ts#L42 |
SubcommandMatch
Since
2.0.0
Properties
| Property | Type | Defined in |
|---|---|---|
matches |
CliMatches |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/cli/guest-js/index.ts#L34 |
name |
string |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/cli/guest-js/index.ts#L33 |
Functions
getMatches()
function getMatches(): Promise<CliMatches>
Parse the arguments provided to the current process and get the matches using the configuration defined tauri.cli in tauri.conf.json
Returns
Example
import { getMatches } from '@tauri-apps/plugin-cli';
const matches = await getMatches();
if (matches.subcommand?.name === 'run') {
// `./your-app run $ARGS` was executed
const args = matches.subcommand?.matches.args
if ('debug' in args) {
// `./your-app run --debug` was executed
}
} else {
const args = matches.args
// `./your-app $ARGS` was executed
}
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/cli/guest-js/index.ts#L66
@tauri-apps/plugin-clipboard-manager
Read and write to the system clipboard.
Functions
clear()
function clear(): Promise<void>
Clears the clipboard.
Platform-specific
- Android: Only supported on SDK 28+. For older releases we write an empty string to the clipboard instead.
Returns
Promise<void>
Example
import { clear } from '@tauri-apps/plugin-clipboard-manager';
await clear();
Since
2.0.0
readImage()
function readImage(): Promise<Image>
Gets the clipboard content as Uint8Array image.
Platform-specific
- Android / iOS: Not supported.
Returns
Promise<Image>
Example
import { readImage } from '@tauri-apps/plugin-clipboard-manager';
const clipboardImage = await readImage();
const blob = new Blob([await clipboardImage.rgba()], { type: 'image' })
const url = URL.createObjectURL(blob)
Since
2.0.0
readText()
function readText(): Promise<string>
Gets the clipboard content as plain text.
Returns
Promise<string>
Example
import { readText } from '@tauri-apps/plugin-clipboard-manager';
const clipboardText = await readText();
Since
2.0.0
writeHtml()
function writeHtml(html, altText?): Promise<void>
- Writes HTML or fallbacks to write provided plain text to the clipboard.
Platform-specific
- Android / iOS: Not supported.
Parameters
| Parameter | Type |
|---|---|
html |
string |
altText? |
string |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { writeHtml } from '@tauri-apps/plugin-clipboard-manager';
await writeHtml('<h1>Tauri is awesome!</h1>', 'plaintext');
// The following will write "<h1>Tauri is awesome</h1>" as plain text
await writeHtml('<h1>Tauri is awesome!</h1>', '<h1>Tauri is awesome</h1>');
// we can read html data only as a string so there's just readText(), no readHtml()
assert(await readText(), '<h1>Tauri is awesome!</h1>');
Since
2.0.0
writeImage()
function writeImage(image): Promise<void>
Writes image buffer to the clipboard.
Platform-specific
- Android / iOS: Not supported.
Parameters
| Parameter | Type |
|---|---|
image |
| string | number[] | ArrayBuffer | Uint8Array | Image |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { writeImage } from '@tauri-apps/plugin-clipboard-manager';
const buffer = [
// A red pixel
255, 0, 0, 255,
// A green pixel
0, 255, 0, 255,
];
await writeImage(buffer);
Since
2.0.0
writeText()
function writeText(text, opts?): Promise<void>
Writes plain text to the clipboard.
Parameters
| Parameter | Type |
|---|---|
text |
string |
opts? |
object |
opts.label? |
string |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { writeText, readText } from '@tauri-apps/plugin-clipboard-manager';
await writeText('Tauri is awesome!');
assert(await readText(), 'Tauri is awesome!');
Since
2.0.0
@tauri-apps/plugin-deep-link
Functions
getCurrent()
function getCurrent(): Promise<string[] | null>
Get the current URLs that triggered the deep link. Use this on app load to check whether your app was started via a deep link.
Returns
Promise<string[] | null>
Example
import { getCurrent } from '@tauri-apps/plugin-deep-link';
const urls = await getCurrent();
Platform-specific
- Windows / Linux: This function reads the command line arguments and checks if there’s only one value, which must be an URL with scheme matching one of the configured values. Note that you must manually check the arguments when registering deep link schemes dynamically with [
Self::register]. Additionally, the deep link might have been provided as a CLI argument so you should check if its format matches what you expect.
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/deep-link/guest-js/index.ts#L25
isRegistered()
function isRegistered(protocol): Promise<boolean>
Check whether the app is the default handler for the specified protocol.
Parameters
| Parameter | Type | Description |
|---|---|---|
protocol |
string |
The name of the protocol without ://. |
Returns
Promise<boolean>
Example
import { isRegistered } from '@tauri-apps/plugin-deep-link';
await isRegistered("my-scheme");
Platform-specific
- macOS / Android / iOS: Unsupported.
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/deep-link/guest-js/index.ts#L88
onOpenUrl()
function onOpenUrl(handler): Promise<UnlistenFn>
Helper function for the deep-link://new-url event to run a function each time the protocol is triggered while the app is running. Use getCurrent on app load to check whether your app was started via a deep link.
Parameters
| Parameter | Type |
|---|---|
handler |
(urls) => void |
Returns
Promise<UnlistenFn>
Example
import { onOpenUrl } from '@tauri-apps/plugin-deep-link';
await onOpenUrl((urls) => { console.log(urls) });
Platform-specific
- Windows / Linux: Unsupported without the single-instance plugin. The OS will spawn a new app instance passing the URL as a CLI argument.
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/deep-link/guest-js/index.ts#L109
register()
function register(protocol): Promise<null>
Register the app as the default handler for the specified protocol.
Parameters
| Parameter | Type | Description |
|---|---|---|
protocol |
string |
The name of the protocol without ://. For example, if you want your app to handle tauri:// links, call this method with tauri as the protocol. |
Returns
Promise<null>
Example
import { register } from '@tauri-apps/plugin-deep-link';
await register("my-scheme");
Platform-specific
- macOS / Android / iOS: Unsupported.
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/deep-link/guest-js/index.ts#L46
unregister()
function unregister(protocol): Promise<null>
Unregister the app as the default handler for the specified protocol.
Parameters
| Parameter | Type | Description |
|---|---|---|
protocol |
string |
The name of the protocol without ://. |
Returns
Promise<null>
Example
import { unregister } from '@tauri-apps/plugin-deep-link';
await unregister("my-scheme");
Platform-specific
- macOS / Linux / Android / iOS: Unsupported.
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/deep-link/guest-js/index.ts#L67
@tauri-apps/plugin-dialog
Interfaces
ConfirmDialogOptions
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
cancelLabel? |
string |
The label of the cancel button. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L293 |
kind? |
"info" | "warning" | "error" |
The kind of the dialog. Defaults to info. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L289 |
okLabel? |
string |
The label of the confirm button. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L291 |
title? |
string |
The title of the dialog. Defaults to the app name. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L287 |
DialogFilter
Extension filters for the file dialog.
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
extensions |
string[] |
Extensions to filter, without a . prefix. Note: Mobile platforms have different APIs for filtering that may not support extensions. iOS: Extensions are supported in the document picker, but not in the media picker. Android: Extensions are not supported. For these platforms, MIME types are the primary way to filter files, as opposed to extensions. This means the string values here labeled as extensions may also be a MIME type. This property name of extensions is being kept for backwards compatibility, but this may be revisited to specify the difference between extension or MIME type filtering. Example extensions: ['svg', 'png'] |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L32 |
name |
string |
Filter name. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L14 |
MessageDialogOptions
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
buttons? |
MessageDialogButtons |
The buttons of the dialog. Example // Use system default buttons texts await message('Hello World!', { buttons: 'Ok' }) await message('Hello World!', { buttons: 'OkCancel' }) // Or with custom button texts await message('Hello World!', { buttons: { ok: 'Yes!' } }) await message('Take on the task?', { buttons: { ok: 'Accept', cancel: 'Cancel' } }) await message('Show the file content?', { buttons: { yes: 'Show content', no: 'Show in folder', cancel: 'Cancel' } }) Since 2.4.0 |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L259 |
kind? |
"info" | "warning" | "error" |
The kind of the dialog. Defaults to info. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L230 |
okLabel? |
string |
The label of the Ok button. Deprecated Use MessageDialogOptions.buttons instead. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L236 |
title? |
string |
The title of the dialog. Defaults to the app name. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L228 |
OpenDialogOptions
Options for the open dialog.
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
canCreateDirectories? |
boolean |
Whether to allow creating directories in the dialog. Enabled by default. macOS Only | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L71 |
defaultPath? |
string |
Initial directory or file path. If it’s a directory path, the dialog interface will change to that folder. If it’s not an existing directory, the file name will be set to the dialog’s file name input and the dialog will be set to the parent folder. On mobile the file name is always used on the dialog’s file name input. If not provided, Android uses (invalid).txt as default file name. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L60 |
directory? |
boolean |
Whether the dialog is a directory selection or not. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L64 |
fileAccessMode? |
FileAccessMode |
The file access mode of the dialog. If not provided, copy is used, which matches the behavior of the open method before the introduction of this option. Usage If a file is opened with : 'copy', it will be copied to the app’s sandbox. This means the file can be read, edited, deleted, copied, or any other operation without any issues, since the file now belongs to the app. This also means that the caller has responsibility of deleting the file if this file is not meant to be retained in the app sandbox. If a file is opened with : 'scoped', the file will remain in its original location and security-scoped access will be automatically managed by the system. Note This is specifically meant for document pickers on iOS or MacOS, in conjunction with security scoped resources. Why only document pickers, and not image or video pickers? The image and video pickers on iOS behave differently from the document pickers, and return NSItemProvider objects instead of file URLs. These are meant to be ephemeral (only available within the callback of the picker), and are not accessible outside of the callback. So for image and video pickers, the only way to access the file is to copy it to the app’s sandbox, and this is the URL that is returned from this API. This means there is no provision for using scoped mode with image or video pickers. If an image or video picker is used, copy is always used. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L103 |
filters? |
DialogFilter[] |
The filters of the dialog. On mobile platforms, if either: A) the pickerMode is set to media, image, or video – or – B) the filters include only either image or video mime types, the media picker will be displayed. Otherwise, the document picker will be displayed. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L51 |
multiple? |
boolean |
Whether the dialog allows multiple selection or not. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L62 |
pickerMode? |
PickerMode |
The preferred mode of the dialog. This is meant for mobile platforms (iOS and Android) which have distinct file and media pickers. If not provided, the dialog will automatically choose the best mode based on the MIME types or extensions of the filters. On desktop, this option is ignored. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L78 |
recursive? |
boolean |
If directory is true, indicates that it will be read recursively later. Defines whether subdirectories will be allowed on the scope or not. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L69 |
title? |
string |
The title of the dialog window (desktop only). | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L42 |
SaveDialogOptions
Options for the save dialog.
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
canCreateDirectories? |
boolean |
Whether to allow creating directories in the dialog. Enabled by default. macOS Only | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L126 |
defaultPath? |
string |
Initial directory or file path. If it’s a directory path, the dialog interface will change to that folder. If it’s not an existing directory, the file name will be set to the dialog’s file name input and the dialog will be set to the parent folder. On mobile the file name is always used on the dialog’s file name input. If not provided, Android uses (invalid).txt as default file name. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L124 |
filters? |
DialogFilter[] |
The filters of the dialog. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L115 |
title? |
string |
The title of the dialog window (desktop only). | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L113 |
Type Aliases
FileAccessMode
type FileAccessMode: "copy" | "scoped";
The file access mode of the dialog.
copy: copy/move the picked file to the app sandbox; no scoped access required.scoped: keep file in place; security-scoped access is automatically managed.
Note: This option is only supported on iOS 14 and above. This parameter is ignored on iOS 13 and below.
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L147
MessageDialogButtons
type MessageDialogButtons: MessageDialogDefaultButtons | MessageDialogCustomButtons;
The buttons of a message dialog.
Since
2.4.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L219
MessageDialogButtonsOk
type MessageDialogButtonsOk: object & BanExcept<"ok">;
The Ok button of a message dialog.
Type declaration
| Name | Type | Description | Defined in |
|---|---|---|---|
ok |
string |
The Ok button. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L201 |
Since
2.4.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L199
MessageDialogButtonsOkCancel
type MessageDialogButtonsOkCancel: object & BanExcept<"ok" | "cancel">;
The Ok and Cancel buttons of a message dialog.
Type declaration
| Name | Type | Description | Defined in |
|---|---|---|---|
cancel |
string |
The Cancel button. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L191 |
ok |
string |
The Ok button. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L189 |
Since
2.4.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L187
MessageDialogButtonsYesNoCancel
type MessageDialogButtonsYesNoCancel: object & BanExcept<"yes" | "no" | "cancel">;
The Yes, No and Cancel buttons of a message dialog.
Type declaration
| Name | Type | Description | Defined in |
|---|---|---|---|
cancel |
string |
The Cancel button. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L179 |
no |
string |
The No button. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L177 |
yes |
string |
The Yes button. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L175 |
Since
2.4.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L173
MessageDialogCustomButtons
type MessageDialogCustomButtons: MessageDialogButtonsYesNoCancel | MessageDialogButtonsOkCancel | MessageDialogButtonsOk;
Custom buttons for a message dialog.
Since
2.4.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L209
MessageDialogDefaultButtons
type MessageDialogDefaultButtons: "Ok" | "OkCancel" | "YesNo" | "YesNoCancel";
Default buttons for a message dialog.
Since
2.4.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L154
MessageDialogResult
type MessageDialogResult:
| "Yes"
| "No"
| "Ok"
| "Cancel"
| string & object;
The result of a message dialog.
The result is a string if the dialog has custom buttons, otherwise it is one of the default buttons.
Since
2.4.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L406
OpenDialogReturn<T>
type OpenDialogReturn<T>: T["directory"] extends true ? T["multiple"] extends true ? string[] | null : string | null : T["multiple"] extends true ? string[] | null : string | null;
Type Parameters
| Type Parameter |
|---|
T extends OpenDialogOptions |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L296
PickerMode
type PickerMode: "document" | "media" | "image" | "video";
The preferred mode of the dialog. This is meant for mobile platforms (iOS and Android) which have distinct file and media pickers. On desktop, this option is ignored. If not provided, the dialog will automatically choose the best mode based on the MIME types or extensions of the filters.
Note: This option is only supported on iOS 14 and above. This parameter is ignored on iOS 13 and below.
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L137
Functions
ask()
function ask(message, options?): Promise<boolean>
Shows a question dialog with Yes and No buttons.
Convenient wrapper for await message('msg', { buttons: 'YesNo' }) === 'Yes'
Parameters
| Parameter | Type | Description |
|---|---|---|
message |
string |
The message to show. |
options? |
string | ConfirmDialogOptions |
The dialog’s options. If a string, it represents the dialog title. |
Returns
Promise<boolean>
A promise resolving to a boolean indicating whether Yes was clicked or not.
Example
import { ask } from '@tauri-apps/plugin-dialog';
const yes = await ask('Are you sure?', 'Tauri');
const yes2 = await ask('This action cannot be reverted. Are you sure?', { title: 'Tauri', kind: 'warning' });
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L467
confirm()
function confirm(message, options?): Promise<boolean>
Shows a question dialog with Ok and Cancel buttons.
Convenient wrapper for await message('msg', { buttons: 'OkCancel' }) === 'Ok'
Parameters
| Parameter | Type | Description |
|---|---|---|
message |
string |
The message to show. |
options? |
string | ConfirmDialogOptions |
The dialog’s options. If a string, it represents the dialog title. |
Returns
Promise<boolean>
A promise resolving to a boolean indicating whether Ok was clicked or not.
Example
import { confirm } from '@tauri-apps/plugin-dialog';
const confirmed = await confirm('Are you sure?', 'Tauri');
const confirmed2 = await confirm('This action cannot be reverted. Are you sure?', { title: 'Tauri', kind: 'warning' });
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L504
message()
function message(message, options?): Promise<MessageDialogResult>
Shows a message dialog with an Ok button.
Parameters
| Parameter | Type | Description |
|---|---|---|
message |
string |
The message to show. |
options? |
string | MessageDialogOptions |
The dialog’s options. If a string, it represents the dialog title. |
Returns
A promise indicating the success or failure of the operation.
Example
import { message } from '@tauri-apps/plugin-dialog';
await message('Tauri is awesome', 'Tauri');
await message('File not found', { title: 'Tauri', kind: 'error' });
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L437
open()
function open<T>(options): Promise<OpenDialogReturn<T>>
Open a file/directory selection dialog.
The selected paths are added to the filesystem and asset protocol scopes. When security is more important than the easy of use of this API, prefer writing a dedicated command instead.
Note that the scope change is not persisted, so the values are cleared when the application is restarted. You can save it to the filesystem using tauri-plugin-persisted-scope.
Type Parameters
| Type Parameter |
|---|
T extends OpenDialogOptions |
Parameters
| Parameter | Type |
|---|---|
options |
T |
Returns
A promise resolving to the selected path(s)
Examples
import { open } from '@tauri-apps/plugin-dialog';
// Open a selection dialog for image files
const selected = await open({
multiple: true,
filters: [{
name: 'Image',
extensions: ['png', 'jpeg']
}]
});
if (Array.isArray(selected)) {
// user selected multiple files
} else if (selected === null) {
// user cancelled the selection
} else {
// user selected a single file
}
import { open } from '@tauri-apps/plugin-dialog';
import { appDir } from '@tauri-apps/api/path';
// Open a selection dialog for directories
const selected = await open({
directory: true,
multiple: true,
defaultPath: await appDir(),
});
if (Array.isArray(selected)) {
// user selected multiple directories
} else if (selected === null) {
// user cancelled the selection
} else {
// user selected a single directory
}
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L356
save()
function save(options): Promise<string | null>
Open a file/directory save dialog.
The selected path is added to the filesystem and asset protocol scopes. When security is more important than the easy of use of this API, prefer writing a dedicated command instead.
Note that the scope change is not persisted, so the values are cleared when the application is restarted. You can save it to the filesystem using tauri-plugin-persisted-scope.
Parameters
| Parameter | Type |
|---|---|
options |
SaveDialogOptions |
Returns
Promise<string | null>
A promise resolving to the selected path.
Example
import { save } from '@tauri-apps/plugin-dialog';
const filePath = await save({
filters: [{
name: 'Image',
extensions: ['png', 'jpeg']
}]
});
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/dialog/guest-js/index.ts#L390
@tauri-apps/plugin-fs
Access the file system.
iOS security-scoped resources
On iOS, the fs plugin automatically manages access to security-scoped resources when a file URL is accessed. This is required for files outside the app’s sandbox (e.g., from file picker).
Example
import { open } from '@tauri-apps/plugin-fs';
const file = await open('file:///path/to/file.txt');
await file.close();
Security
This module prevents path traversal, not allowing parent directory accessors to be used (i.e. “/usr/path/to/../file” or “../path/to/file” paths are not allowed). Paths accessed with this API must be either relative to one of the base directories or created with the path API.
The API has a scope configuration that forces you to restrict the paths that can be accessed using glob patterns.
The scope configuration is an array of glob patterns describing file/directory paths that are allowed. For instance, this scope configuration allows all enabled fs APIs to (only) access files in the databases directory of the $APPDATA directory:
{
"permissions": [
{
"identifier": "fs:scope",
"allow": [{ "path": "$APPDATA/databases/*" }]
}
]
}
Scopes can also be applied to specific fs APIs by using the API’s identifier instead of fs:scope:
{
"permissions": [
{
"identifier": "fs:allow-exists",
"allow": [{ "path": "$APPDATA/databases/*" }]
}
]
}
Notice the use of the $APPDATA variable. The value is injected at runtime, resolving to the app data directory.
The available variables are: $APPCONFIG, $APPDATA, $APPLOCALDATA, $APPCACHE, $APPLOG, $AUDIO, $CACHE, $CONFIG, $DATA, $LOCALDATA, $DESKTOP, $DOCUMENT, $DOWNLOAD, $EXE, $FONT, $HOME, $PICTURE, $PUBLIC, $RUNTIME, $TEMPLATE, $VIDEO, $RESOURCE, $TEMP.
Trying to execute any API with a URL not configured on the scope results in a promise rejection due to denied access.
Enumerations
BaseDirectory
Since
2.0.0
Enumeration Members
AppCache
AppCache: 16;
See
appCacheDir for more information.
Source: undefined
AppConfig
AppConfig: 13;
See
appConfigDir for more information.
Source: undefined
AppData
AppData: 14;
See
appDataDir for more information.
Source: undefined
AppLocalData
AppLocalData: 15;
See
appLocalDataDir for more information.
Source: undefined
AppLog
AppLog: 17;
See
appLogDir for more information.
Source: undefined
Audio
Audio: 1;
See
audioDir for more information.
Source: undefined
Cache
Cache: 2;
See
cacheDir for more information.
Source: undefined
Config
Config: 3;
See
configDir for more information.
Source: undefined
Data
Data: 4;
See
dataDir for more information.
Source: undefined
Desktop
Desktop: 18;
See
desktopDir for more information.
Source: undefined
Document
Document: 6;
See
documentDir for more information.
Source: undefined
Download
Download: 7;
See
downloadDir for more information.
Source: undefined
Executable
Executable: 19;
See
executableDir for more information.
Source: undefined
Font
Font: 20;
See
fontDir for more information.
Source: undefined
Home
Home: 21;
See
homeDir for more information.
Source: undefined
LocalData
LocalData: 5;
See
localDataDir for more information.
Source: undefined
Picture
Picture: 8;
See
pictureDir for more information.
Source: undefined
Public
Public: 9;
See
publicDir for more information.
Source: undefined
Resource
Resource: 11;
See
resourceDir for more information.
Source: undefined
Runtime
Runtime: 22;
See
runtimeDir for more information.
Source: undefined
Temp
Temp: 12;
See
tempDir for more information.
Source: undefined
Template
Template: 23;
See
templateDir for more information.
Source: undefined
Video
Video: 10;
See
videoDir for more information.
Source: undefined
SeekMode
Enumeration Members
Current
Current: 1;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L93
End
End: 2;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L94
Start
Start: 0;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L92
Classes
FileHandle
The Tauri abstraction for reading and writing files.
Since
2.0.0
Extends
Resource
Constructors
new FileHandle()
new FileHandle(rid): FileHandle
Parameters
| Parameter | Type |
|---|---|
rid |
number |
Returns
Inherited from
Resource.constructor
Source: undefined
Accessors
rid
get rid(): number
Returns
number
Inherited from
Resource.rid
Source: undefined
Methods
close()
close(): Promise<void>
Destroys and cleans up this resource from memory. You should not call any method on this object anymore and should drop any reference to it.
Returns
Promise<void>
Inherited from
Resource.close
Source: undefined
read()
read(buffer): Promise<null | number>
Reads up to p.byteLength bytes into p. It resolves to the number of bytes read (0 < n <= p.byteLength) and rejects if any error encountered. Even if read() resolves to n < p.byteLength, it may use all of p as scratch space during the call. If some data is available but not p.byteLength bytes, read() conventionally resolves to what is available instead of waiting for more.
When read() encounters end-of-file condition, it resolves to EOF (null).
When read() encounters an error, it rejects with an error.
Callers should always process the n > 0 bytes returned before considering the EOF (null). Doing so correctly handles I/O errors that happen after reading some bytes and also both of the allowed EOF behaviors.
Parameters
| Parameter | Type |
|---|---|
buffer |
Uint8Array |
Returns
Promise<null | number>
Example
import { open, BaseDirectory } from "@tauri-apps/plugin-fs"
// if "$APPCONFIG/foo/bar.txt" contains the text "hello world":
const file = await open("foo/bar.txt", { baseDir: BaseDirectory.AppConfig });
const buf = new Uint8Array(100);
const numberOfBytesRead = await file.read(buf); // 11 bytes
const text = new TextDecoder().decode(buf); // "hello world"
await file.close();
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L327
seek()
seek(offset, whence): Promise<number>
Seek sets the offset for the next read() or write() to offset, interpreted according to whence: Start means relative to the start of the file, Current means relative to the current offset, and End means relative to the end. Seek resolves to the new offset relative to the start of the file.
Seeking to an offset before the start of the file is an error. Seeking to any positive offset is legal, but the behavior of subsequent I/O operations on the underlying object is implementation-dependent. It returns the number of cursor position.
Parameters
| Parameter | Type |
|---|---|
offset |
number |
whence |
SeekMode |
Returns
Promise<number>
Example
import { open, SeekMode, BaseDirectory } from '@tauri-apps/plugin-fs';
// Given hello.txt pointing to file with "Hello world", which is 11 bytes long:
const file = await open('hello.txt', { read: true, write: true, truncate: true, create: true, baseDir: BaseDirectory.AppLocalData });
await file.write(new TextEncoder().encode("Hello world"));
// Seek 6 bytes from the start of the file
console.log(await file.seek(6, SeekMode.Start)); // "6"
// Seek 2 more bytes from the current position
console.log(await file.seek(2, SeekMode.Current)); // "8"
// Seek backwards 2 bytes from the end of the file
console.log(await file.seek(-2, SeekMode.End)); // "9" (e.g. 11-2)
await file.close();
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L382
stat()
stat(): Promise<FileInfo>
Returns a FileInfo for this file.
Returns
Example
import { open, BaseDirectory } from '@tauri-apps/plugin-fs';
const file = await open("file.txt", { read: true, baseDir: BaseDirectory.AppLocalData });
const fileInfo = await file.stat();
console.log(fileInfo.isFile); // true
await file.close();
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L404
truncate()
truncate(len?): Promise<void>
Truncates or extends this file, to reach the specified len. If len is not specified then the entire file contents are truncated.
Parameters
| Parameter | Type |
|---|---|
len? |
number |
Returns
Promise<void>
Example
import { open, BaseDirectory } from '@tauri-apps/plugin-fs';
// truncate the entire file
const file = await open("my_file.txt", { read: true, write: true, create: true, baseDir: BaseDirectory.AppLocalData });
await file.truncate();
// truncate part of the file
const file = await open("my_file.txt", { read: true, write: true, create: true, baseDir: BaseDirectory.AppLocalData });
await file.write(new TextEncoder().encode("Hello World"));
await file.truncate(7);
const data = new Uint8Array(32);
await file.read(data);
console.log(new TextDecoder().decode(data)); // Hello W
await file.close();
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L436
write()
write(data): Promise<number>
Writes data.byteLength bytes from data to the underlying data stream. It resolves to the number of bytes written from data (0 <= n <= data.byteLength) or reject with the error encountered that caused the write to stop early. write() must reject with a non-null error if would resolve to n < data.byteLength. write() must not modify the slice data, even temporarily.
Parameters
| Parameter | Type |
|---|---|
data |
Uint8Array |
Returns
Promise<number>
Example
import { open, write, BaseDirectory } from '@tauri-apps/plugin-fs';
const encoder = new TextEncoder();
const data = encoder.encode("Hello world");
const file = await open("bar.txt", { write: true, baseDir: BaseDirectory.AppLocalData });
const bytesWritten = await file.write(data); // 11
await file.close();
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L463
Interfaces
CopyFileOptions
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
fromPathBaseDir? |
BaseDirectory |
Base directory for fromPath. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L599 |
toPathBaseDir? |
BaseDirectory |
Base directory for toPath. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L601 |
CreateOptions
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
baseDir? |
BaseDirectory |
Base directory for path |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L476 |
DebouncedWatchOptions
Since
2.0.0
Extends
Properties
| Property | Type | Description | Inherited from | Defined in |
|---|---|---|---|---|
baseDir? |
BaseDirectory |
Base directory for path |
WatchOptions.baseDir |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1195 |
delayMs? |
number |
Debounce delay | - | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1203 |
recursive? |
boolean |
Watch a directory recursively | WatchOptions.recursive |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1193 |
DirEntry
A disk entry which is either a file, a directory or a symlink.
This is the result of the readDir.
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
isDirectory |
boolean |
Specifies whether this entry is a directory or not. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L690 |
isFile |
boolean |
Specifies whether this entry is a file or not. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L692 |
isSymlink |
boolean |
Specifies whether this entry is a symlink or not. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L694 |
name |
string |
The name of the entry (file name with extension or directory name). | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L688 |
ExistsOptions
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
baseDir? |
BaseDirectory |
Base directory for path. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1160 |
FileInfo
A FileInfo describes a file and is returned by stat, lstat or fstat.
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
atime |
null | Date |
The last access time of the file. This corresponds to the atime field from stat on Unix and ftLastAccessTime on Windows. This may not be available on all platforms. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L133 |
birthtime |
null | Date |
The creation time of the file. This corresponds to the birthtime field from stat on Mac/BSD and ftCreationTime on Windows. This may not be available on all platforms. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L139 |
blksize |
null | number |
Blocksize for filesystem I/O. Platform-specific - Windows: Unsupported. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L216 |
blocks |
null | number |
Number of blocks allocated to the file, in 512-byte units. Platform-specific - Windows: Unsupported. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L224 |
dev |
null | number |
ID of the device containing the file. Platform-specific - Windows: Unsupported. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L159 |
fileAttributes |
null | number |
This field contains the file system attribute information for a file or directory. For possible values and their descriptions, see File Attribute Constants in the Windows Dev Center Platform-specific - macOS / Linux / Android / iOS: Unsupported. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L151 |
gid |
null | number |
Group ID of the owner of this file. Platform-specific - Windows: Unsupported. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L200 |
ino |
null | number |
Inode number. Platform-specific - Windows: Unsupported. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L167 |
isDirectory |
boolean |
True if this is info for a regular directory. Mutually exclusive to FileInfo.isFile and FileInfo.isSymlink. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L112 |
isFile |
boolean |
True if this is info for a regular file. Mutually exclusive to FileInfo.isDirectory and FileInfo.isSymlink. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L107 |
isSymlink |
boolean |
True if this is info for a symlink. Mutually exclusive to FileInfo.isFile and FileInfo.isDirectory. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L117 |
mode |
null | number |
The underlying raw st_mode bits that contain the standard Unix permissions for this file/directory. Platform-specific - Windows: Unsupported. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L176 |
mtime |
null | Date |
The last modification time of the file. This corresponds to the mtime field from stat on Linux/Mac OS and ftLastWriteTime on Windows. This may not be available on all platforms. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L127 |
nlink |
null | number |
Number of hard links pointing to this file. Platform-specific - Windows: Unsupported. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L184 |
rdev |
null | number |
Device ID of this file. Platform-specific - Windows: Unsupported. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L208 |
readonly |
boolean |
Whether this is a readonly (unwritable) file. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L141 |
size |
number |
The size of the file, in bytes. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L121 |
uid |
null | number |
User ID of the owner of this file. Platform-specific - Windows: Unsupported. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L192 |
MkdirOptions
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
baseDir? |
BaseDirectory |
Base directory for path |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L644 |
mode? |
number |
Permissions to use when creating the directory (defaults to 0o777, before the process’s umask). Ignored on Windows. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L638 |
recursive? |
boolean |
Defaults to false. If set to true, means that any intermediate directories will also be created (as with the shell command mkdir -p). |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L642 |
OpenOptions
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
append? |
boolean |
Sets the option for the append mode. This option, when true, means that writes will append to a file instead of overwriting previous contents. Note that setting { write: true, append: true } has the same effect as setting only { append: true }. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L531 |
baseDir? |
BaseDirectory |
Base directory for path |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L559 |
create? |
boolean |
Sets the option to allow creating a new file, if one doesn’t already exist at the specified path. Requires write or append access to be used. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L544 |
createNew? |
boolean |
Defaults to false. If set to true, no file, directory, or symlink is allowed to exist at the target location. Requires write or append access to be used. When createNew is set to true, create and truncate are ignored. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L551 |
mode? |
number |
Permissions to use if creating the file (defaults to 0o666, before the process’s umask). Ignored on Windows. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L557 |
read? |
boolean |
Sets the option for read access. This option, when true, means that the file should be read-able if opened. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L517 |
truncate? |
boolean |
Sets the option for truncating a previous file. If a file is successfully opened with this option set it will truncate the file to 0 size if it already exists. The file must be opened with write access for truncate to work. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L538 |
write? |
boolean |
Sets the option for write access. This option, when true, means that the file should be write-able if opened. If the file already exists, any write calls on it will overwrite its contents, by default without truncating it. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L524 |
ReadDirOptions
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
baseDir? |
BaseDirectory |
Base directory for path |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L676 |
ReadFileOptions
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
baseDir? |
BaseDirectory |
Base directory for path |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L738 |
encoding? |
string |
Text encoding to use when reading a text file. Defaults to ‘utf-8’. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L740 |
RemoveOptions
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
baseDir? |
BaseDirectory |
Base directory for path |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L882 |
recursive? |
boolean |
Defaults to false. If set to true, path will be removed even if it’s a non-empty directory. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L880 |
RenameOptions
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
newPathBaseDir? |
BaseDirectory |
Base directory for newPath. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L918 |
oldPathBaseDir? |
BaseDirectory |
Base directory for oldPath. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L916 |
StatOptions
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
baseDir? |
BaseDirectory |
Base directory for path. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L960 |
TruncateOptions
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
baseDir? |
BaseDirectory |
Base directory for path. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1019 |
WatchEvent
Since
2.0.0
Properties
| Property | Type | Defined in |
|---|---|---|
attrs |
unknown |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1212 |
paths |
string[] |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1211 |
type |
WatchEventKind |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1210 |
WatchOptions
Since
2.0.0
Extended by
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
baseDir? |
BaseDirectory |
Base directory for path |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1195 |
recursive? |
boolean |
Watch a directory recursively | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1193 |
WriteFileOptions
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
append? |
boolean |
Defaults to false. If set to true, will append to a file instead of overwriting previous contents. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1063 |
baseDir? |
BaseDirectory |
Base directory for path |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1071 |
create? |
boolean |
Sets the option to allow creating a new file, if one doesn’t already exist at the specified path (defaults to true). |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1065 |
createNew? |
boolean |
Sets the option to create a new file, failing if it already exists. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1067 |
mode? |
number |
File permissions. Ignored on Windows. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1069 |
Type Aliases
UnwatchFn()
type UnwatchFn: () => void;
Returns
void
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1277
WatchEventKind
type WatchEventKind:
| "any"
| object
| object
| object
| object
| "other";
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1218
WatchEventKindAccess
type WatchEventKindAccess: object | object | object | object;
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1229
WatchEventKindCreate
type WatchEventKindCreate: object | object | object | object;
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1238
WatchEventKindModify
type WatchEventKindModify:
| object
| object
| object
| object
| object;
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1247
WatchEventKindRemove
type WatchEventKindRemove: object | object | object | object;
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1267
Functions
copyFile()
function copyFile(
fromPath,
toPath,
options?): Promise<void>
Copies the contents and permissions of one file to another specified path, by default creating a new file if needed, else overwriting.
Parameters
| Parameter | Type |
|---|---|
fromPath |
string | URL |
toPath |
string | URL |
options? |
CopyFileOptions |
Returns
Promise<void>
Example
import { copyFile, BaseDirectory } from '@tauri-apps/plugin-fs';
await copyFile('app.conf', 'app.conf.bk', { fromPathBaseDir: BaseDirectory.AppConfig, toPathBaseDir: BaseDirectory.AppConfig });
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L614
create()
function create(path, options?): Promise<FileHandle>
Creates a file if none exists or truncates an existing file and resolves to an instance of FileHandle.
Parameters
| Parameter | Type |
|---|---|
path |
string | URL |
options? |
CreateOptions |
Returns
Example
import { create, BaseDirectory } from "@tauri-apps/plugin-fs"
const file = await create("foo/bar.txt", { baseDir: BaseDirectory.AppConfig });
await file.write(new TextEncoder().encode("Hello world"));
await file.close();
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L493
exists()
function exists(path, options?): Promise<boolean>
Check if a path exists.
Parameters
| Parameter | Type |
|---|---|
path |
string | URL |
options? |
ExistsOptions |
Returns
Promise<boolean>
Example
import { exists, BaseDirectory } from '@tauri-apps/plugin-fs';
// Check if the `$APPDATA/avatar.png` file exists
await exists('avatar.png', { baseDir: BaseDirectory.AppData });
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1174
lstat()
function lstat(path, options?): Promise<FileInfo>
Resolves to a FileInfo for the specified path. If path is a symlink, information for the symlink will be returned instead of what it points to.
Parameters
| Parameter | Type |
|---|---|
path |
string | URL |
options? |
StatOptions |
Returns
Example
import { lstat, BaseDirectory } from '@tauri-apps/plugin-fs';
const fileInfo = await lstat("hello.txt", { baseDir: BaseDirectory.AppLocalData });
console.log(fileInfo.isFile); // true
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1002
mkdir()
function mkdir(path, options?): Promise<void>
Creates a new directory with the specified path.
Parameters
| Parameter | Type |
|---|---|
path |
string | URL |
options? |
MkdirOptions |
Returns
Promise<void>
Example
import { mkdir, BaseDirectory } from '@tauri-apps/plugin-fs';
await mkdir('users', { baseDir: BaseDirectory.AppLocalData });
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L657
open()
function open(path, options?): Promise<FileHandle>
Open a file and resolve to an instance of FileHandle. The file does not need to previously exist if using the create or createNew open options. It is the callers responsibility to close the file when finished with it.
Parameters
| Parameter | Type |
|---|---|
path |
string | URL |
options? |
OpenOptions |
Returns
Example
import { open, BaseDirectory } from "@tauri-apps/plugin-fs"
const file = await open("foo/bar.txt", { read: true, write: true, baseDir: BaseDirectory.AppLocalData });
// Do work with file
await file.close();
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L578
readDir()
function readDir(path, options?): Promise<DirEntry[]>
Reads the directory given by path and returns an array of DirEntry.
Parameters
| Parameter | Type |
|---|---|
path |
string | URL |
options? |
ReadDirOptions |
Returns
Example
import { readDir, BaseDirectory } from '@tauri-apps/plugin-fs';
import { join } from '@tauri-apps/api/path';
const dir = "users"
const entries = await readDir('users', { baseDir: BaseDirectory.AppLocalData });
processEntriesRecursively(dir, entries);
async function processEntriesRecursively(parent, entries) {
for (const entry of entries) {
console.log(`Entry: ${entry.name}`);
if (entry.isDirectory) {
const dir = await join(parent, entry.name);
processEntriesRecursively(dir, await readDir(dir, { baseDir: BaseDirectory.AppLocalData }))
}
}
}
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L719
readFile()
function readFile(path, options?): Promise<Uint8Array>
Reads and resolves to the entire contents of a file as an array of bytes. TextDecoder can be used to transform the bytes to string if required.
Parameters
| Parameter | Type |
|---|---|
path |
string | URL |
options? |
ReadFileOptions |
Returns
Example
import { readFile, BaseDirectory } from '@tauri-apps/plugin-fs';
const contents = await readFile('avatar.png', { baseDir: BaseDirectory.Resource });
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L754
readTextFile()
function readTextFile(path, options?): Promise<string>
Reads and returns the entire contents of a file as a string using the specified encoding (default: UTF-8).
Parameters
| Parameter | Type |
|---|---|
path |
string | URL |
options? |
ReadFileOptions |
Returns
Promise<string>
Example
import { readTextFile, BaseDirectory } from '@tauri-apps/plugin-fs';
const contents = await readTextFile('app.conf', { baseDir: BaseDirectory.AppConfig });
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L780
readTextFileLines()
function readTextFileLines(path, options?): Promise<AsyncIterableIterator<string>>
Returns an async AsyncIterableIterator over the lines of a file, decoded using the specified encoding (default: UTF-8).
Parameters
| Parameter | Type |
|---|---|
path |
string | URL |
options? |
ReadFileOptions |
Returns
Promise<AsyncIterableIterator<string>>
Example
import { readTextFileLines, BaseDirectory } from '@tauri-apps/plugin-fs';
const lines = await readTextFileLines('app.conf', { baseDir: BaseDirectory.AppConfig });
for await (const line of lines) {
console.log(line);
}
You could also call AsyncIterableIterator.next to advance the iterator so you can lazily read the next line whenever you want.
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L813
remove()
function remove(path, options?): Promise<void>
Removes the named file or directory. If the directory is not empty and the recursive option isn’t set to true, the promise will be rejected.
Parameters
| Parameter | Type |
|---|---|
path |
string | URL |
options? |
RemoveOptions |
Returns
Promise<void>
Example
import { remove, BaseDirectory } from '@tauri-apps/plugin-fs';
await remove('users/file.txt', { baseDir: BaseDirectory.AppLocalData });
await remove('users', { baseDir: BaseDirectory.AppLocalData });
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L897
rename()
function rename(
oldPath,
newPath,
options?): Promise<void>
Renames (moves) oldpath to newpath. Paths may be files or directories. If newpath already exists and is not a directory, rename() replaces it. OS-specific restrictions may apply when oldpath and newpath are in different directories.
On Unix, this operation does not follow symlinks at either path.
Parameters
| Parameter | Type |
|---|---|
oldPath |
string | URL |
newPath |
string | URL |
options? |
RenameOptions |
Returns
Promise<void>
Example
import { rename, BaseDirectory } from '@tauri-apps/plugin-fs';
await rename('avatar.png', 'deleted.png', { oldPathBaseDir: BaseDirectory.App, newPathBaseDir: BaseDirectory.AppLocalData });
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L936
size()
function size(path): Promise<number>
Get the size of a file or directory. For files, the stat functions can be used as well.
If path is a directory, this function will recursively iterate over every file and every directory inside of path and therefore will be very time consuming if used on larger directories.
Parameters
| Parameter | Type |
|---|---|
path |
string | URL |
Returns
Promise<number>
Example
import { size, BaseDirectory } from '@tauri-apps/plugin-fs';
// Get the size of the `$APPDATA/tauri` directory.
const dirSize = await size('tauri', { baseDir: BaseDirectory.AppData });
console.log(dirSize); // 1024
Since
2.1.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1359
startAccessingSecurityScopedResource()
function startAccessingSecurityScopedResource(path): Promise<void>
Starts accessing a security-scoped resource for the given file URL. This should be called when you’re accessing a file that was opened using a security-scoped URL (e.g., from a file picker).
Note that accessing security-scoped resources is automatically managed by the plugin on iOS, so you don’t need to call this function unless you want to manage the scope manually.
You must call stopAccessingSecurityScopedResource when you’re done accessing the resource.
Platform-specific
- iOS: Starts accessing the security-scoped resource.
- Other platforms: does nothing.
Parameters
| Parameter | Type |
|---|---|
path |
string | URL |
Returns
Promise<void>
Example
import { startAccessingSecurityScopedResource } from '@tauri-apps/plugin-fs';
const filePath = 'file:///path/to/file.txt';
await startAccessingSecurityScopedResource(filePath);
// ... use the resource ...
Since
2.5.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1395
stat()
function stat(path, options?): Promise<FileInfo>
Resolves to a FileInfo for the specified path. Will always follow symlinks but will reject if the symlink points to a path outside of the scope.
Parameters
| Parameter | Type |
|---|---|
path |
string | URL |
options? |
StatOptions |
Returns
Example
import { stat, BaseDirectory } from '@tauri-apps/plugin-fs';
const fileInfo = await stat("hello.txt", { baseDir: BaseDirectory.AppLocalData });
console.log(fileInfo.isFile); // true
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L976
stopAccessingSecurityScopedResource()
function stopAccessingSecurityScopedResource(path): Promise<void>
Stops accessing a security-scoped resource for the given file URL. This should be called when you’re done accessing a file that was opened using a security-scoped URL (e.g., from a file picker) when using manual tracking via startAccessingSecurityScopedResource.
Platform-specific
- iOS: Stops accessing the security-scoped resource.
- Other platforms: does nothing.
Parameters
| Parameter | Type |
|---|---|
path |
string | URL |
Returns
Promise<void>
Example
import { stopAccessingSecurityScopedResource } from '@tauri-apps/plugin-fs';
const filePath = 'file:///path/to/file.txt';
await startAccessingSecurityScopedResource(filePath);
// ... use the resource ...
// when you're done with the resource:
await stopAccessingSecurityScopedResource(filePath);
Since
2.5.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1430
truncate()
function truncate(
path,
len?,
options?): Promise<void>
Truncates or extends the specified file, to reach the specified len. If len is 0 or not specified, then the entire file contents are truncated.
Parameters
| Parameter | Type |
|---|---|
path |
string | URL |
len? |
number |
options? |
TruncateOptions |
Returns
Promise<void>
Example
import { truncate, readTextFile, writeTextFile, BaseDirectory } from '@tauri-apps/plugin-fs';
// truncate the entire file
await truncate("my_file.txt", 0, { baseDir: BaseDirectory.AppLocalData });
// truncate part of the file
const filePath = "file.txt";
await writeTextFile(filePath, "Hello World", { baseDir: BaseDirectory.AppLocalData });
await truncate(filePath, 7, { baseDir: BaseDirectory.AppLocalData });
const data = await readTextFile(filePath, { baseDir: BaseDirectory.AppLocalData });
console.log(data); // "Hello W"
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1042
watch()
function watch(
paths,
cb,
options?): Promise<UnwatchFn>
Watch changes (after a delay) on files or directories.
Parameters
| Parameter | Type |
|---|---|
paths |
string | URL | string[] | URL[] |
cb |
(event) => void |
options? |
DebouncedWatchOptions |
Returns
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1316
watchImmediate()
function watchImmediate(
paths,
cb,
options?): Promise<UnwatchFn>
Watch changes on files or directories.
Parameters
| Parameter | Type |
|---|---|
paths |
string | URL | string[] | URL[] |
cb |
(event) => void |
options? |
WatchOptions |
Returns
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1333
writeFile()
function writeFile(
path,
data,
options?): Promise<void>
Write data to the given path, by default creating a new file if needed, else overwriting.
Parameters
| Parameter | Type |
|---|---|
path |
string | URL |
data |
Uint8Array | ReadableStream<Uint8Array> |
options? |
WriteFileOptions |
Returns
Promise<void>
Example
import { writeFile, BaseDirectory } from '@tauri-apps/plugin-fs';
let encoder = new TextEncoder();
let data = encoder.encode("Hello World");
await writeFile('file.txt', data, { baseDir: BaseDirectory.AppLocalData });
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1087
writeTextFile()
function writeTextFile(
path,
data,
options?): Promise<void>
Writes UTF-8 string data to the given path, by default creating a new file if needed, else overwriting.
Parameters
| Parameter | Type |
|---|---|
path |
string | URL |
data |
string |
options? |
WriteFileOptions |
Returns
Promise<void>
Example
import { writeTextFile, BaseDirectory } from '@tauri-apps/plugin-fs';
await writeTextFile('file.txt', "Hello world", { baseDir: BaseDirectory.AppLocalData });
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/fs/guest-js/index.ts#L1136
@tauri-apps/plugin-geolocation
Type Aliases
Coordinates
type Coordinates: object;
Type declaration
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/geolocation/guest-js/index.ts#L12
PermissionStatus
type PermissionStatus: object;
Type declaration
| Name | Type | Description | Defined in |
|---|---|---|---|
coarseLocation |
PermissionState |
Permissions state for the coarseLoaction alias. On Android it requests/checks ACCESS_COARSE_LOCATION. On Android 12+, users can choose between Approximate location (ACCESS_COARSE_LOCATION) and Precise location (ACCESS_FINE_LOCATION). On iOS it will have the same value as the location alias. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/geolocation/guest-js/index.ts#L59 |
location |
PermissionState |
Permission state for the location alias. On Android it requests/checks both ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION permissions. On iOS it requests/checks location permissions. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/geolocation/guest-js/index.ts#L49 |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/geolocation/guest-js/index.ts#L41
PermissionType
type PermissionType: "location" | "coarseLocation";
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/geolocation/guest-js/index.ts#L62
Position
type Position: object;
Type declaration
| Name | Type | Description | Defined in |
|---|---|---|---|
coords |
Coordinates |
The GPD coordinates along with the accuracy of the data. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/geolocation/guest-js/index.ts#L72 |
timestamp |
number |
Creation time for these coordinates. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/geolocation/guest-js/index.ts#L68 |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/geolocation/guest-js/index.ts#L64
PositionOptions
type PositionOptions: object;
Type declaration
| Name | Type | Description | Defined in |
|---|---|---|---|
enableHighAccuracy |
boolean |
High accuracy mode (such as GPS, if available) Will be ignored on Android 12+ if users didn’t grant the ACCESS_FINE_LOCATION permission (coarseLocation permission). |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/geolocation/guest-js/index.ts#L80 |
maximumAge |
number |
The maximum age in milliseconds of a possible cached position that is acceptable to return. Default: 0 Ignored on iOS | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/geolocation/guest-js/index.ts#L92 |
timeout |
number |
The maximum wait time in milliseconds for location updates. On Android the timeout gets ignored for getCurrentPosition. Ignored on iOS | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/geolocation/guest-js/index.ts#L86 |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/geolocation/guest-js/index.ts#L75
Functions
checkPermissions()
function checkPermissions(): Promise<PermissionStatus>
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/geolocation/guest-js/index.ts#L128
clearWatch()
function clearWatch(channelId): Promise<void>
Parameters
| Parameter | Type |
|---|---|
channelId |
number |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/geolocation/guest-js/index.ts#L122
getCurrentPosition()
function getCurrentPosition(options?): Promise<Position>
Parameters
| Parameter | Type |
|---|---|
options? |
PositionOptions |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/geolocation/guest-js/index.ts#L114
requestPermissions()
function requestPermissions(permissions): Promise<PermissionStatus>
Parameters
| Parameter | Type |
|---|---|
permissions |
null | PermissionType[] |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/geolocation/guest-js/index.ts#L132
watchPosition()
function watchPosition(options, cb): Promise<number>
Parameters
| Parameter | Type |
|---|---|
options |
PositionOptions |
cb |
(location, error?) => void |
Returns
Promise<number>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/geolocation/guest-js/index.ts#L95
@tauri-apps/plugin-global-shortcut
Register global shortcuts.
Interfaces
ShortcutEvent
Properties
| Property | Type | Defined in |
|---|---|---|
id |
number |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/global-shortcut/guest-js/index.ts#L15 |
shortcut |
string |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/global-shortcut/guest-js/index.ts#L14 |
state |
"Released" | "Pressed" |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/global-shortcut/guest-js/index.ts#L16 |
Type Aliases
ShortcutHandler()
type ShortcutHandler: (event) => void;
Parameters
| Parameter | Type |
|---|---|
event |
ShortcutEvent |
Returns
void
Functions
isRegistered()
function isRegistered(shortcut): Promise<boolean>
Determines whether the given shortcut is registered by this application or not.
If the shortcut is registered by another application, it will still return false.
Parameters
| Parameter | Type | Description |
|---|---|---|
shortcut |
string |
shortcut definition, modifiers and key separated by “+” e.g. CmdOrControl+Q |
Returns
Promise<boolean>
Example
import { isRegistered } from '@tauri-apps/plugin-global-shortcut';
const isRegistered = await isRegistered('CommandOrControl+P');
Since
2.0.0
register()
function register(shortcuts, handler): Promise<void>
Register a global shortcut or a list of shortcuts.
The handler is called when any of the registered shortcuts are pressed by the user.
If the shortcut is already taken by another application, the handler will not be triggered. Make sure the shortcut is as unique as possible while still taking user experience into consideration.
Parameters
| Parameter | Type | Description |
|---|---|---|
shortcuts |
string | string[] |
- |
handler |
ShortcutHandler |
Shortcut handler callback - takes the triggered shortcut as argument |
Returns
Promise<void>
Example
import { register } from '@tauri-apps/plugin-global-shortcut';
// register a single hotkey
await register('CommandOrControl+Shift+C', (event) => {
if (event.state === "Pressed") {
console.log('Shortcut triggered');
}
});
// or register multiple hotkeys at once
await register(['CommandOrControl+Shift+C', 'Alt+A'], (event) => {
console.log(`Shortcut ${event.shortcut} triggered`);
});
Since
2.0.0
unregister()
function unregister(shortcuts): Promise<void>
Unregister a global shortcut or a list of shortcuts.
Parameters
| Parameter | Type |
|---|---|
shortcuts |
string | string[] |
Returns
Promise<void>
Example
import { unregister } from '@tauri-apps/plugin-global-shortcut';
// unregister a single hotkey
await unregister('CmdOrControl+Space');
// or unregister multiple hotkeys at the same time
await unregister(['CmdOrControl+Space', 'Alt+A']);
Since
2.0.0
unregisterAll()
function unregisterAll(): Promise<void>
Unregister all global shortcuts.
Returns
Promise<void>
Example
import { unregisterAll } from '@tauri-apps/plugin-global-shortcut';
await unregisterAll();
Since
2.0.0
@tauri-apps/plugin-haptics
Type Aliases
ImpactFeedbackStyle
type ImpactFeedbackStyle:
| "light"
| "medium"
| "heavy"
| "soft"
| "rigid";
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/haptics/guest-js/bindings.ts#L76
NotificationFeedbackType
type NotificationFeedbackType: "success" | "warning" | "error";
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/haptics/guest-js/bindings.ts#L82
Functions
impactFeedback()
function impactFeedback(style): Promise<Result<null, never>>
Parameters
| Parameter | Type |
|---|---|
style |
ImpactFeedbackStyle |
Returns
Promise<Result<null, never>>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/haptics/guest-js/index.ts#L11
notificationFeedback()
function notificationFeedback(type): Promise<Result<null, never>>
Parameters
| Parameter | Type |
|---|---|
type |
NotificationFeedbackType |
Returns
Promise<Result<null, never>>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/haptics/guest-js/index.ts#L12
selectionFeedback()
function selectionFeedback(): Promise<Result<null, never>>
Returns
Promise<Result<null, never>>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/haptics/guest-js/index.ts#L13
vibrate()
function vibrate(duration): Promise<Result<null, never>>
Parameters
| Parameter | Type |
|---|---|
duration |
number |
Returns
Promise<Result<null, never>>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/haptics/guest-js/index.ts#L10
@tauri-apps/plugin-http
Make HTTP requests with the Rust backend.
Security
This API has a scope configuration that forces you to restrict the URLs that can be accessed using glob patterns.
For instance, this scope configuration only allows making HTTP requests to all subdomains for tauri.app except for https://private.tauri.app:
{
"permissions": [
{
"identifier": "http:default",
"allow": [{ "url": "https://*.tauri.app" }],
"deny": [{ "url": "https://private.tauri.app" }]
}
]
}
Trying to execute any API with a URL not configured on the scope results in a promise rejection due to denied access.
Interfaces
ClientOptions
Options to configure the Rust client used to make fetch requests
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
connectTimeout? |
number |
Timeout in milliseconds | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/http/guest-js/index.ts#L82 |
danger? |
DangerousSettings |
Configuration for dangerous settings on the client such as disabling SSL verification. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/http/guest-js/index.ts#L90 |
maxRedirections? |
number |
Defines the maximum number of redirects the client should follow. If set to 0, no redirects will be followed. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/http/guest-js/index.ts#L80 |
proxy? |
Proxy |
Configuration of a proxy that a Client should pass requests to. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/http/guest-js/index.ts#L86 |
DangerousSettings
Configuration for dangerous settings on the client such as disabling SSL verification.
Since
2.3.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
acceptInvalidCerts? |
boolean |
Disables SSL verification. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/http/guest-js/index.ts#L102 |
acceptInvalidHostnames? |
boolean |
Disables hostname verification. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/http/guest-js/index.ts#L106 |
Proxy
Configuration of a proxy that a Client should pass requests to.
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
all? |
string | ProxyConfig |
Proxy all traffic to the passed URL. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/http/guest-js/index.ts#L40 |
http? |
string | ProxyConfig |
Proxy all HTTP traffic to the passed URL. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/http/guest-js/index.ts#L44 |
https? |
string | ProxyConfig |
Proxy all HTTPS traffic to the passed URL. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/http/guest-js/index.ts#L48 |
ProxyConfig
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
basicAuth? |
object |
Set the Proxy-Authorization header using Basic auth. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/http/guest-js/index.ts#L59 |
basicAuth.password |
string |
- | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/http/guest-js/index.ts#L61 |
basicAuth.username |
string |
- | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/http/guest-js/index.ts#L60 |
noProxy? |
string |
A configuration for filtering out requests that shouldn’t be proxied. Entries are expected to be comma-separated (whitespace between entries is ignored) | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/http/guest-js/index.ts#L67 |
url |
string |
The URL of the proxy server. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/http/guest-js/index.ts#L55 |
Functions
fetch()
function fetch(input, init?): Promise<Response>
Fetch a resource from the network. It returns a Promise that resolves to the Response to that Request, whether it is successful or not.
Parameters
| Parameter | Type |
|---|---|
input |
string | URL | Request |
init? |
RequestInit & ClientOptions |
Returns
Example
const response = await fetch("http://my.json.host/data.json");
console.log(response.status); // e.g. 200
console.log(response.statusText); // e.g. "OK"
const jsonData = await response.json();
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/http/guest-js/index.ts#L125
@tauri-apps/plugin-log
Enumerations
LogLevel
Enumeration Members
Debug
Debug: 2;
The “debug” level.
Designates lower priority information.
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/log/guest-js/index.ts#L26
Error
Error: 5;
The “error” level.
Designates very serious errors.
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/log/guest-js/index.ts#L44
Info
Info: 3;
The “info” level.
Designates useful information.
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/log/guest-js/index.ts#L32
Trace
Trace: 1;
The “trace” level.
Designates very low priority, often extremely verbose, information.
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/log/guest-js/index.ts#L20
Warn
Warn: 4;
The “warn” level.
Designates hazardous situations.
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/log/guest-js/index.ts#L38
Interfaces
LogOptions
Properties
| Property | Type | Defined in |
|---|---|---|
file? |
string |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/log/guest-js/index.ts#L9 |
keyValues? |
Record<string, undefined | string> |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/log/guest-js/index.ts#L11 |
line? |
number |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/log/guest-js/index.ts#L10 |
Functions
attachConsole()
function attachConsole(): Promise<UnlistenFn>
Attaches a listener that writes log entries to the console as they come in.
Returns
Promise<UnlistenFn>
a function to cancel the listener.
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/log/guest-js/index.ts#L277
attachLogger()
function attachLogger(fn): Promise<UnlistenFn>
Attaches a listener for the log, and calls the passed function for each log entry.
Parameters
| Parameter | Type | Description |
|---|---|---|
fn |
LoggerFn |
Returns
Promise<UnlistenFn>
a function to cancel the listener.
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/log/guest-js/index.ts#L256
debug()
function debug(message, options?): Promise<void>
Logs a message at the debug level.
Parameters
| Parameter | Type | Description |
|---|---|---|
message |
string |
# Examples import { debug } from '@tauri-apps/plugin-log'; const pos = { x: 3.234, y: -1.223 }; debug(New position: x: {pos.x}, y: {pos.y}); |
options? |
LogOptions |
- |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/log/guest-js/index.ts#L214
error()
function error(message, options?): Promise<void>
Logs a message at the error level.
Parameters
| Parameter | Type | Description |
|---|---|---|
message |
string |
# Examples import { error } from '@tauri-apps/plugin-log'; const err_info = "No connection"; const port = 22; error(Error: ${err_info} on port ${port}); |
options? |
LogOptions |
- |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/log/guest-js/index.ts#L148
info()
function info(message, options?): Promise<void>
Logs a message at the info level.
Parameters
| Parameter | Type | Description |
|---|---|---|
message |
string |
# Examples import { info } from '@tauri-apps/plugin-log'; const conn_info = { port: 40, speed: 3.20 }; info(Connected to port {conn_info.port} at {conn_info.speed} Mb/s); |
options? |
LogOptions |
- |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/log/guest-js/index.ts#L192
trace()
function trace(message, options?): Promise<void>
Logs a message at the trace level.
Parameters
| Parameter | Type | Description |
|---|---|---|
message |
string |
# Examples import { trace } from '@tauri-apps/plugin-log'; let pos = { x: 3.234, y: -1.223 }; trace(Position is: x: {pos.x}, y: {pos.y}); |
options? |
LogOptions |
- |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/log/guest-js/index.ts#L236
warn()
function warn(message, options?): Promise<void>
Logs a message at the warn level.
Parameters
| Parameter | Type | Description |
|---|---|---|
message |
string |
# Examples import { warn } from '@tauri-apps/plugin-log'; const warn_description = "Invalid Input"; warn(Warning! {warn_description}!); |
options? |
LogOptions |
- |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/log/guest-js/index.ts#L170
@tauri-apps/plugin-nfc
Enumerations
NFCTypeNameFormat
Enumeration Members
AbsoluteURI
AbsoluteURI: 3;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L84
Empty
Empty: 0;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L81
Media
Media: 2;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L83
NfcExternal
NfcExternal: 4;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L85
NfcWellKnown
NfcWellKnown: 1;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L82
Unchanged
Unchanged: 6;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L87
Unknown
Unknown: 5;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L86
TechKind
Enumeration Members
IsoDep
IsoDep: 0;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L17
MifareClassic
MifareClassic: 1;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L18
MifareUltralight
MifareUltralight: 2;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L19
Ndef
Ndef: 3;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L20
NdefFormatable
NdefFormatable: 4;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L21
NfcA
NfcA: 5;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L22
NfcB
NfcB: 6;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L23
NfcBarcode
NfcBarcode: 7;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L24
NfcF
NfcF: 8;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L25
NfcV
NfcV: 9;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L26
Interfaces
NFCRecord
Properties
| Property | Type | Defined in |
|---|---|---|
format |
NFCTypeNameFormat |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L104 |
id |
number[] |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L106 |
kind |
number[] |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L105 |
payload |
number[] |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L107 |
ScanOptions
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
keepSessionAlive? |
boolean |
- | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L63 |
message? |
string |
Message displayed in the UI. iOS only. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L65 |
successMessage? |
string |
Message displayed in the UI when the message has been read. iOS only. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L67 |
Tag
Properties
| Property | Type | Defined in |
|---|---|---|
id |
number[] |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L98 |
kind |
string[] |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L99 |
records |
TagRecord[] |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L100 |
TagRecord
Properties
| Property | Type | Defined in |
|---|---|---|
id |
number[] |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L93 |
kind |
number[] |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L92 |
payload |
number[] |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L94 |
tnf |
NFCTypeNameFormat |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L91 |
UriFilter
Properties
| Property | Type | Defined in |
|---|---|---|
host? |
string |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L12 |
pathPrefix? |
string |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L13 |
scheme? |
string |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L11 |
WriteOptions
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
kind? |
ScanKind |
- | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L71 |
message? |
string |
Message displayed in the UI when reading the tag. iOS only. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L73 |
successMessage? |
string |
Message displayed in the UI when the message has been written. iOS only. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L77 |
successfulReadMessage? |
string |
Message displayed in the UI when the tag has been read. iOS only. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L75 |
Type Aliases
ScanKind
type ScanKind: object | object;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L29
Variables
RTD_TEXT
const RTD_TEXT: number[];
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L7
RTD_URI
const RTD_URI: number[];
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L8
Functions
isAvailable()
function isAvailable(): Promise<boolean>
Returns
Promise<boolean>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L271
record()
function record(
format,
kind,
id,
payload): NFCRecord
Parameters
| Parameter | Type |
|---|---|
format |
NFCTypeNameFormat |
kind |
string | number[] |
id |
string | number[] |
payload |
string | number[] |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L110
scan()
function scan(kind, options?): Promise<Tag>
Scans an NFC tag.
import { scan } from "@tauri-apps/plugin-nfc";
await scan({ type: "tag" });
See https://developer.android.com/develop/connectivity/nfc/nfc#ndef for more information.
Parameters
| Parameter | Type | Description |
|---|---|---|
kind |
ScanKind |
|
options? |
ScanOptions |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L231
textRecord()
function textRecord(
text,
id?,
language?): NFCRecord
Parameters
| Parameter | Type | Default value |
|---|---|---|
text |
string |
undefined |
id? |
string | number[] |
undefined |
language? |
string |
'en' |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L130
uriRecord()
function uriRecord(uri, id?): NFCRecord
Parameters
| Parameter | Type |
|---|---|
uri |
string |
id? |
string | number[] |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L203
write()
function write(records, options?): Promise<void>
Write to an NFC tag.
import { uriRecord, write } from "@tauri-apps/plugin-nfc";
await write([uriRecord("https://tauri.app")], { kind: { type: "ndef" } });
If you did not previously call scan with ScanOptions.keepSessionAlive set to true, it will first scan the tag then write to it.
Parameters
| Parameter | Type | Description |
|---|---|---|
records |
NFCRecord[] |
|
options? |
WriteOptions |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/nfc/guest-js/index.ts#L256
@tauri-apps/plugin-notification
Send toast notifications (brief auto-expiring OS window element) to your user. Can also be used with the Notification Web API.
Enumerations
Importance
Enumeration Members
Default
Default: 3;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L293
High
High: 4;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L294
Low
Low: 2;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L292
Min
Min: 1;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L291
None
None: 0;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L290
ScheduleEvery
Enumeration Members
Day
Day: "day";
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L165
Hour
Hour: "hour";
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L166
Minute
Minute: "minute";
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L167
Month
Month: "month";
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L162
Second
Second: "second";
Not supported on iOS.
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L171
TwoWeeks
TwoWeeks: "twoWeeks";
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L163
Week
Week: "week";
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L164
Year
Year: "year";
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L161
Visibility
Enumeration Members
Private
Private: 0;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L299
Public
Public: 1;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L300
Secret
Secret: -1;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L298
Classes
Schedule
Constructors
new Schedule()
new Schedule(): Schedule
Returns
Properties
| Property | Type | Defined in |
|---|---|---|
at |
undefined | object |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L175 |
every |
undefined | object |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L190 |
interval |
undefined | object |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L183 |
Methods
at()
static at(
date,
repeating,
allowWhileIdle): Schedule
Parameters
| Parameter | Type | Default value |
|---|---|---|
date |
Date |
undefined |
repeating |
boolean |
false |
allowWhileIdle |
boolean |
false |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L198
every()
static every(
kind,
count,
allowWhileIdle): Schedule
Parameters
| Parameter | Type | Default value |
|---|---|---|
kind |
ScheduleEvery |
undefined |
count |
number |
undefined |
allowWhileIdle |
boolean |
false |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L217
interval()
static interval(interval, allowWhileIdle): Schedule
Parameters
| Parameter | Type | Default value |
|---|---|---|
interval |
ScheduleInterval |
undefined |
allowWhileIdle |
boolean |
false |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L206
Interfaces
Action
Properties
ActionType
Properties
ActiveNotification
Properties
Attachment
Attachment of a notification.
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
id |
string |
Attachment identifier. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L235 |
url |
string |
Attachment URL. Accepts the asset and file protocols. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L237 |
Channel
Properties
Options
Options to send a notification.
Since
2.0.0
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
actionTypeId? |
string |
Defines an action type for this notification. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L62 |
attachments? |
Attachment[] |
Notification attachments. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L110 |
autoCancel? |
boolean |
Automatically cancel the notification when the user clicks on it. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L126 |
body? |
string |
Optional notification body. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L44 |
channelId? |
string |
Identifier of the Channel that deliveres this notification. If the channel does not exist, the notification won’t fire. Make sure the channel exists with listChannels and createChannel. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L36 |
extra? |
Record<string, unknown> |
Extra payload to store in the notification. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L114 |
group? |
string |
Identifier used to group multiple notifications. https://developer.apple.com/documentation/usernotifications/unmutablenotificationcontent/1649872-threadidentifier | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L68 |
groupSummary? |
boolean |
Instructs the system that this notification is the summary of a group on Android. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L72 |
icon? |
string |
Notification icon. On Android the icon must be placed in the app’s res/drawable folder. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L96 |
iconColor? |
string |
Icon color on Android. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L106 |
id? |
number |
The notification identifier to reference this object later. Must be a 32-bit integer. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L29 |
inboxLines? |
string[] |
List of lines to add to the notification. Changes the notification style to inbox. Cannot be used with largeBody. Only supports up to 5 lines. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L90 |
largeBody? |
string |
Multiline text. Changes the notification style to big text. Cannot be used with inboxLines. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L54 |
largeIcon? |
string |
Notification large icon (Android). The icon must be placed in the app’s res/drawable folder. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L102 |
number? |
number |
Sets the number of items this notification represents on Android. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L138 |
ongoing? |
boolean |
If true, the notification cannot be dismissed by the user on Android. An application service must manage the dismissal of the notification. It is typically used to indicate a background task that is pending (e.g. a file download) or the user is engaged with (e.g. playing music). | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L122 |
schedule? |
Schedule |
Schedule this notification to fire on a later time or a fixed interval. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L48 |
silent? |
boolean |
Changes the notification presentation to be silent on iOS (no badge, no sound, not listed). | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L130 |
sound? |
string |
The sound resource name or file path for the notification. Platform specific behavior: - On macOS: use system sounds (e.g., “Ping”, “Blow”) or sound files in the app bundle - On Linux: use XDG theme sounds (e.g., “message-new-instant”) or file paths - On Windows: use file paths to sound files (.wav format) - On Mobile: use resource names | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L82 |
summary? |
string |
Detail text for the notification with largeBody, inboxLines or groupSummary. |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L58 |
title |
string |
Notification title. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L40 |
visibility? |
Visibility |
Notification visibility. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L134 |
PendingNotification
Properties
| Property | Type | Defined in |
|---|---|---|
body? |
string |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L270 |
id |
number |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L268 |
schedule |
Schedule |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L271 |
title? |
string |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L269 |
ScheduleInterval
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
day? |
number |
- | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L144 |
hour? |
number |
- | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L155 |
minute? |
number |
- | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L156 |
month? |
number |
- | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L143 |
second? |
number |
- | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L157 |
weekday? |
number |
1 - Sunday 2 - Monday 3 - Tuesday 4 - Wednesday 5 - Thursday 6 - Friday 7 - Saturday | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L154 |
year? |
number |
- | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L142 |
Type Aliases
PermissionState
type PermissionState: "granted" | "denied" | "prompt" | "prompt-with-rationale";
Source: undefined
Functions
active()
function active(): Promise<ActiveNotification[]>
Retrieves the list of active notifications.
Returns
A promise resolving to the list of active notifications.
Example
import { active } from '@tauri-apps/plugin-notification';
const activeNotifications = await active();
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L465
cancel()
function cancel(notifications): Promise<void>
Cancels the pending notifications with the given list of identifiers.
Parameters
| Parameter | Type |
|---|---|
notifications |
number[] |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { cancel } from '@tauri-apps/plugin-notification';
await cancel([-34234, 23432, 4311]);
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L431
cancelAll()
function cancelAll(): Promise<void>
Cancels all pending notifications.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { cancelAll } from '@tauri-apps/plugin-notification';
await cancelAll();
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L448
channels()
function channels(): Promise<Channel[]>
Retrieves the list of notification channels.
Returns
A promise resolving to the list of notification channels.
Example
import { channels } from '@tauri-apps/plugin-notification';
const notificationChannels = await channels();
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L559
createChannel()
function createChannel(channel): Promise<void>
Creates a notification channel.
Parameters
| Parameter | Type |
|---|---|
channel |
Channel |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { createChannel, Importance, Visibility } from '@tauri-apps/plugin-notification';
await createChannel({
id: 'new-messages',
name: 'New Messages',
lights: true,
vibration: true,
importance: Importance.Default,
visibility: Visibility.Private
});
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L525
isPermissionGranted()
function isPermissionGranted(): Promise<boolean>
Checks if the permission to send notifications is granted.
Returns
Promise<boolean>
Example
import { isPermissionGranted } from '@tauri-apps/plugin-notification';
const permissionGranted = await isPermissionGranted();
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L325
onAction()
function onAction(cb): Promise<PluginListener>
Parameters
| Parameter | Type |
|---|---|
cb |
(notification) => void |
Returns
Promise<PluginListener>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L569
onNotificationReceived()
function onNotificationReceived(cb): Promise<PluginListener>
Parameters
| Parameter | Type |
|---|---|
cb |
(notification) => void |
Returns
Promise<PluginListener>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L563
pending()
function pending(): Promise<PendingNotification[]>
Retrieves the list of pending notifications.
Returns
Promise<PendingNotification[]>
A promise resolving to the list of pending notifications.
Example
import { pending } from '@tauri-apps/plugin-notification';
const pendingNotifications = await pending();
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L414
registerActionTypes()
function registerActionTypes(types): Promise<void>
Register actions that are performed when the user clicks on the notification.
Parameters
| Parameter | Type |
|---|---|
types |
ActionType[] |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { registerActionTypes } from '@tauri-apps/plugin-notification';
await registerActionTypes([{
id: 'tauri',
actions: [{
id: 'my-action',
title: 'Settings'
}]
}])
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L397
removeActive()
function removeActive(notifications): Promise<void>
Removes the active notifications with the given list of identifiers.
Parameters
| Parameter | Type |
|---|---|
notifications |
object[] |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { cancel } from '@tauri-apps/plugin-notification';
await cancel([-34234, 23432, 4311])
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L482
removeAllActive()
function removeAllActive(): Promise<void>
Removes all active notifications.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { removeAllActive } from '@tauri-apps/plugin-notification';
await removeAllActive()
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L501
removeChannel()
function removeChannel(id): Promise<void>
Removes the channel with the given identifier.
Parameters
| Parameter | Type |
|---|---|
id |
string |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { removeChannel } from '@tauri-apps/plugin-notification';
await removeChannel();
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L542
requestPermission()
function requestPermission(): Promise<NotificationPermission>
Requests the permission to send notifications.
Returns
Promise<NotificationPermission>
A promise resolving to whether the user granted the permission or not.
Example
import { isPermissionGranted, requestPermission } from '@tauri-apps/plugin-notification';
let permissionGranted = await isPermissionGranted();
if (!permissionGranted) {
const permission = await requestPermission();
permissionGranted = permission === 'granted';
}
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L348
sendNotification()
function sendNotification(options): void
Sends a notification to the user.
Parameters
| Parameter | Type |
|---|---|
options |
string | Options |
Returns
void
Example
import { isPermissionGranted, requestPermission, sendNotification } from '@tauri-apps/plugin-notification';
let permissionGranted = await isPermissionGranted();
if (!permissionGranted) {
const permission = await requestPermission();
permissionGranted = permission === 'granted';
}
if (permissionGranted) {
sendNotification('Tauri is awesome!');
sendNotification({ title: 'TAURI', body: 'Tauri is awesome!' });
}
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/notification/guest-js/index.ts#L370
@tauri-apps/plugin-opener
Open files and URLs using their default application.
Security
This API has a scope configuration that forces you to restrict the files and urls to be opened.
Restricting access to the open | open API
On the configuration object, open: true means that the open API can be used with any URL, as the argument is validated with the ^((mailto:\w+)|(tel:\w+)|(https?://\w+)).+ regex. You can change that regex by changing the boolean value to a string, e.g. open: ^https://github.com/.
Functions
openPath()
function openPath(path, openWith?): Promise<void>
Opens a path with the system’s default app, or the one specified with openWith.
Parameters
| Parameter | Type | Description |
|---|---|---|
path |
string |
The path to open. |
openWith? |
string |
The app to open the path with. If not specified, defaults to the system default application for the specified path type. |
Returns
Promise<void>
Example
import { openPath } from '@tauri-apps/plugin-opener';
// opens a file using the default program:
await openPath('/path/to/file');
// opens a file using `vlc` command on Windows.
await openPath('C:/path/to/file', 'vlc');
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/opener/guest-js/index.ts#L71
openUrl()
function openUrl(url, openWith?): Promise<void>
Opens a url with the system’s default app, or the one specified with openWith.
Parameters
| Parameter | Type | Description |
|---|---|---|
url |
string | URL |
The URL to open. |
openWith? |
string |
The app to open the URL with. If not specified, defaults to the system default application for the specified url type. On mobile, openWith can be provided as inAppBrowser to open the URL in an in-app browser. Otherwise, it will open the URL in the system default browser. |
Returns
Promise<void>
Example
import { openUrl } from '@tauri-apps/plugin-opener';
// opens the given URL on the default browser:
await openUrl('https://github.com/tauri-apps/tauri');
// opens the given URL using `firefox`:
await openUrl('https://github.com/tauri-apps/tauri', 'firefox');
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/opener/guest-js/index.ts#L42
revealItemInDir()
function revealItemInDir(path): Promise<void>
Reveal a path with the system’s default explorer.
Platform-specific:
- Android / iOS: Unsupported.
Parameters
| Parameter | Type | Description |
|---|---|---|
path |
string | string[] |
The path to reveal. |
Returns
Promise<void>
Example
import { revealItemInDir } from '@tauri-apps/plugin-opener';
await revealItemInDir('/path/to/file');
await revealItemInDir([ '/path/to/file', '/path/to/another/file' ]);
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/opener/guest-js/index.ts#L96
@tauri-apps/plugin-os
Provides operating system-related utility methods and properties.
Type Aliases
Arch
type Arch:
| "x86"
| "x86_64"
| "arm"
| "aarch64"
| "mips"
| "mips64"
| "powerpc"
| "powerpc64"
| "riscv64"
| "s390x"
| "sparc64";
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/os/guest-js/index.ts#L42
Family
type Family: "unix" | "windows";
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/os/guest-js/index.ts#L97
OsType
type OsType:
| "linux"
| "windows"
| "macos"
| "ios"
| "android";
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/os/guest-js/index.ts#L40
Platform
type Platform:
| "linux"
| "macos"
| "ios"
| "freebsd"
| "dragonfly"
| "netbsd"
| "openbsd"
| "solaris"
| "android"
| "windows";
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/os/guest-js/index.ts#L28
Functions
arch()
function arch(): Arch
Returns the current operating system architecture. Possible values are 'x86', 'x86_64', 'arm', 'aarch64', 'mips', 'mips64', 'powerpc', 'powerpc64', 'riscv64', 's390x', 'sparc64'.
Returns
Example
import { arch } from '@tauri-apps/plugin-os';
const archName = arch();
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/os/guest-js/index.ts#L138
eol()
function eol(): string
Returns the operating system-specific end-of-line marker.
\non POSIX\r\non Windows
Returns
string
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/os/guest-js/index.ts#L62
exeExtension()
function exeExtension(): string
Returns the file extension, if any, used for executable binaries on this platform. Possible values are 'exe' and '' (empty string).
Returns
string
Example
import { exeExtension } from '@tauri-apps/plugin-os';
const exeExt = exeExtension();
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/os/guest-js/index.ts#L152
family()
function family(): Family
Returns the current operating system family. Possible values are 'unix', 'windows'.
Returns
Example
import { family } from '@tauri-apps/plugin-os';
const family = family();
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/os/guest-js/index.ts#L109
hostname()
function hostname(): Promise<string | null>
Returns the host name of the operating system.
Returns
Promise<string | null>
Example
import { hostname } from '@tauri-apps/plugin-os';
const hostname = await hostname();
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/os/guest-js/index.ts#L181
locale()
function locale(): Promise<string | null>
Returns a String with a BCP-47 language tag inside. If the locale couldn’t be obtained, null is returned instead.
Returns
Promise<string | null>
Example
import { locale } from '@tauri-apps/plugin-os';
const locale = await locale();
if (locale) {
// use the locale string here
}
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/os/guest-js/index.ts#L169
platform()
function platform(): Platform
Returns a string describing the specific operating system in use. The value is set at compile time. Possible values are 'linux', 'macos', 'ios', 'freebsd', 'dragonfly', 'netbsd', 'openbsd', 'solaris', 'android', 'windows'
Returns
Example
import { platform } from '@tauri-apps/plugin-os';
const platformName = platform();
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/os/guest-js/index.ts#L79
type()
function type(): OsType
Returns the current operating system type. Returns 'linux' on Linux, 'macos' on macOS, 'windows' on Windows, 'ios' on iOS and 'android' on Android.
Returns
Example
import { type } from '@tauri-apps/plugin-os';
const osType = type();
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/os/guest-js/index.ts#L123
version()
function version(): string
Returns the current operating system version.
Returns
string
Example
import { version } from '@tauri-apps/plugin-os';
const osVersion = version();
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/os/guest-js/index.ts#L93
@tauri-apps/plugin-positioner
Enumerations
Position
Well known window positions.
Enumeration Members
BottomCenter
BottomCenter: 5;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/positioner/guest-js/index.ts#L18
BottomLeft
BottomLeft: 2;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/positioner/guest-js/index.ts#L15
BottomRight
BottomRight: 3;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/positioner/guest-js/index.ts#L16
Center
Center: 8;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/positioner/guest-js/index.ts#L21
LeftCenter
LeftCenter: 6;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/positioner/guest-js/index.ts#L19
RightCenter
RightCenter: 7;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/positioner/guest-js/index.ts#L20
TopCenter
TopCenter: 4;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/positioner/guest-js/index.ts#L17
TopLeft
TopLeft: 0;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/positioner/guest-js/index.ts#L13
TopRight
TopRight: 1;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/positioner/guest-js/index.ts#L14
TrayBottomCenter
TrayBottomCenter: 14;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/positioner/guest-js/index.ts#L27
TrayBottomLeft
TrayBottomLeft: 10;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/positioner/guest-js/index.ts#L23
TrayBottomRight
TrayBottomRight: 12;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/positioner/guest-js/index.ts#L25
TrayCenter
TrayCenter: 13;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/positioner/guest-js/index.ts#L26
TrayLeft
TrayLeft: 9;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/positioner/guest-js/index.ts#L22
TrayRight
TrayRight: 11;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/positioner/guest-js/index.ts#L24
Functions
handleIconState()
function handleIconState(event): Promise<void>
Parameters
| Parameter | Type |
|---|---|
event |
TrayIconEvent |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/positioner/guest-js/index.ts#L55
moveWindow()
function moveWindow(to): Promise<void>
Moves the Window to the given Position using WindowExt.move_window() All positions are relative to the current screen.
Parameters
| Parameter | Type | Description |
|---|---|---|
to |
Position |
The Position to move to. |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/positioner/guest-js/index.ts#L36
moveWindowConstrained()
function moveWindowConstrained(to): Promise<void>
Moves the Window to the given Position using WindowExt.move_window_constrained()
This move operation constrains the window to the screen dimensions in case of tray-icon positions.
Parameters
| Parameter | Type | Description |
|---|---|---|
to |
Position |
The (tray) Position to move to. |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/positioner/guest-js/index.ts#L49
@tauri-apps/plugin-process
Perform operations on the current process.
Functions
exit()
function exit(code): Promise<void>
Exits immediately with the given exitCode.
Parameters
| Parameter | Type | Default value | Description |
|---|---|---|---|
code |
number |
0 |
The exit code to use. |
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { exit } from '@tauri-apps/plugin-process';
await exit(1);
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/process/guest-js/index.ts#L25
relaunch()
function relaunch(): Promise<void>
Exits the current instance of the app then relaunches it.
Returns
Promise<void>
A promise indicating the success or failure of the operation.
Example
import { relaunch } from '@tauri-apps/plugin-process';
await relaunch();
Since
2.0.0
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/process/guest-js/index.ts#L41
@tauri-apps/plugin-sql
Classes
default
Database
The Database class serves as the primary interface for communicating with the rust side of the sql plugin.
Constructors
new default()
new default(path): default
Parameters
| Parameter | Type |
|---|---|
path |
string |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/sql/guest-js/index.ts#L29
Properties
| Property | Type | Defined in |
|---|---|---|
path |
string |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/sql/guest-js/index.ts#L28 |
Methods
close()
close(db?): Promise<boolean>
close
Closes the database connection pool.
Parameters
| Parameter | Type | Description |
|---|---|---|
db? |
string |
Optionally state the name of a database if you are managing more than one. Otherwise, all database pools will be in scope. |
Returns
Promise<boolean>
Example
const success = await db.close()
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/sql/guest-js/index.ts#L162
execute()
execute(query, bindValues?): Promise<QueryResult>
execute
Passes a SQL expression to the database for execution.
Parameters
| Parameter | Type |
|---|---|
query |
string |
bindValues? |
unknown[] |
Returns
Example
// for sqlite & postgres
// INSERT example
const result = await db.execute(
"INSERT into todos (id, title, status) VALUES ($1, $2, $3)",
[ todos.id, todos.title, todos.status ]
);
// UPDATE example
const result = await db.execute(
"UPDATE todos SET title = $1, completed = $2 WHERE id = $3",
[ todos.title, todos.status, todos.id ]
);
// for mysql
// INSERT example
const result = await db.execute(
"INSERT into todos (id, title, status) VALUES (?, ?, ?)",
[ todos.id, todos.title, todos.status ]
);
// UPDATE example
const result = await db.execute(
"UPDATE todos SET title = ?, completed = ? WHERE id = ?",
[ todos.title, todos.status, todos.id ]
);
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/sql/guest-js/index.ts#L108
select()
select<T>(query, bindValues?): Promise<T>
select
Passes in a SELECT query to the database for execution.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type |
|---|---|
query |
string |
bindValues? |
unknown[] |
Returns
Promise<T>
Example
// for sqlite & postgres
const result = await db.select(
"SELECT * from todos WHERE id = $1", [ id ]
);
// for mysql
const result = await db.select(
"SELECT * from todos WHERE id = ?", [ id ]
);
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/sql/guest-js/index.ts#L141
get()
static get(path): default
get
A static initializer which synchronously returns an instance of the Database class while deferring the actual database connection until the first invocation or selection on the database.
Sqlite
The path is relative to tauri::path::BaseDirectory::App and must start with sqlite:.
Parameters
| Parameter | Type |
|---|---|
path |
string |
Returns
Example
const db = Database.get("sqlite:test.db");
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/sql/guest-js/index.ts#L72
load()
static load(path): Promise<default>
load
A static initializer which connects to the underlying database and returns a Database instance once a connection to the database is established.
Sqlite
The path is relative to tauri::path::BaseDirectory::App and must start with sqlite:.
Parameters
| Parameter | Type |
|---|---|
path |
string |
Returns
Example
const db = await Database.load("sqlite:test.db");
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/sql/guest-js/index.ts#L48
Interfaces
QueryResult
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
lastInsertId? |
number |
The last inserted id. This value is not set for Postgres databases. If the last inserted id is required on Postgres, the select function must be used, with a RETURNING clause (INSERT INTO todos (title) VALUES ($1) RETURNING id). |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/sql/guest-js/index.ts#L18 |
rowsAffected |
number |
The number of rows affected by the query. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/sql/guest-js/index.ts#L9 |
@tauri-apps/plugin-store
Classes
LazyStore
A lazy loaded key-value store persisted by the backend layer.
Implements
IStore
Constructors
new LazyStore()
new LazyStore(path, options?): LazyStore
Note that the options are not applied if someone else already created the store
Parameters
| Parameter | Type | Description |
|---|---|---|
path |
string |
Path to save the store in app_data_dir |
options? |
StoreOptions |
Store configuration options |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L104
Methods
clear()
clear(): Promise<void>
Clears the store, removing all key-value pairs.
Note: To clear the storage and reset it to its default value, use reset instead.
Returns
Promise<void>
Implementation of
IStore.clear
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L132
close()
close(): Promise<void>
Close the store and cleans up this resource from memory. You should not call any method on this object anymore and should drop any reference to it.
Returns
Promise<void>
Implementation of
IStore.close
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L177
delete()
delete(key): Promise<boolean>
Removes a key-value pair from the store.
Parameters
| Parameter | Type | Description |
|---|---|---|
key |
string |
Returns
Promise<boolean>
Implementation of
IStore.delete
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L128
entries()
entries<T>(): Promise<[string, T][]>
Returns a list of all entries in the store.
Type Parameters
| Type Parameter |
|---|
T |
Returns
Promise<[string, T][]>
Implementation of
IStore.entries
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L148
get()
get<T>(key): Promise<undefined | T>
Returns the value for the given key or undefined if the key does not exist.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
key |
string |
Returns
Promise<undefined | T>
Implementation of
IStore.get
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L120
has()
has(key): Promise<boolean>
Returns true if the given key exists in the store.
Parameters
| Parameter | Type | Description |
|---|---|---|
key |
string |
Returns
Promise<boolean>
Implementation of
IStore.has
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L124
init()
init(): Promise<void>
Init/load the store if it’s not loaded already
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L112
keys()
keys(): Promise<string[]>
Returns a list of all keys in the store.
Returns
Promise<string[]>
Implementation of
IStore.keys
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L140
length()
length(): Promise<number>
Returns the number of key-value pairs in the store.
Returns
Promise<number>
Implementation of
IStore.length
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L152
onChange()
onChange<T>(cb): Promise<UnlistenFn>
Listen to changes on the store.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
cb |
(key, value) => void |
Returns
Promise<UnlistenFn>
A promise resolving to a function to unlisten to the event.
Since
2.0.0
Implementation of
IStore.onChange
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L171
onKeyChange()
onKeyChange<T>(key, cb): Promise<UnlistenFn>
Listen to changes on a store key.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
key |
string |
|
cb |
(value) => void |
Returns
Promise<UnlistenFn>
A promise resolving to a function to unlisten to the event.
Since
2.0.0
Implementation of
IStore.onKeyChange
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L164
reload()
reload(options?): Promise<void>
Attempts to load the on-disk state at the store’s path into memory.
This method is useful if the on-disk state was edited by the user and you want to synchronize the changes.
Note:
- This method loads the data and merges it with the current store, this behavior will be changed to resetting to default first and then merging with the on-disk state in v3, to fully match the store with the on-disk state, set
ignoreDefaultstotrue - This method does not emit change events.
Parameters
| Parameter | Type |
|---|---|
options? |
ReloadOptions |
Returns
Promise<void>
Implementation of
IStore.reload
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L156
reset()
reset(): Promise<void>
Resets the store to its default value.
If no default value has been set, this method behaves identical to clear.
Returns
Promise<void>
Implementation of
IStore.reset
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L136
save()
save(): Promise<void>
Saves the store to disk at the store’s path.
Returns
Promise<void>
Implementation of
IStore.save
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L160
set()
set(key, value): Promise<void>
Inserts a key-value pair into the store.
Parameters
| Parameter | Type | Description |
|---|---|---|
key |
string |
|
value |
unknown |
Returns
Promise<void>
Implementation of
IStore.set
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L116
values()
values<T>(): Promise<T[]>
Returns a list of all values in the store.
Type Parameters
| Type Parameter |
|---|
T |
Returns
Promise<T[]>
Implementation of
IStore.values
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L144
Store
A key-value store persisted by the backend layer.
Extends
Resource
Implements
IStore
Accessors
rid
get rid(): number
Returns
number
Inherited from
Resource.rid
Source: undefined
Methods
clear()
clear(): Promise<void>
Clears the store, removing all key-value pairs.
Note: To clear the storage and reset it to its default value, use reset instead.
Returns
Promise<void>
Implementation of
IStore.clear
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L267
close()
close(): Promise<void>
Destroys and cleans up this resource from memory. You should not call any method on this object anymore and should drop any reference to it.
Returns
Promise<void>
Implementation of
IStore.close
Inherited from
Resource.close
Source: undefined
delete()
delete(key): Promise<boolean>
Removes a key-value pair from the store.
Parameters
| Parameter | Type | Description |
|---|---|---|
key |
string |
Returns
Promise<boolean>
Implementation of
IStore.delete
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L260
entries()
entries<T>(): Promise<[string, T][]>
Returns a list of all entries in the store.
Type Parameters
| Type Parameter |
|---|
T |
Returns
Promise<[string, T][]>
Implementation of
IStore.entries
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L283
get()
get<T>(key): Promise<undefined | T>
Returns the value for the given key or undefined if the key does not exist.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
key |
string |
Returns
Promise<undefined | T>
Implementation of
IStore.get
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L245
has()
has(key): Promise<boolean>
Returns true if the given key exists in the store.
Parameters
| Parameter | Type | Description |
|---|---|---|
key |
string |
Returns
Promise<boolean>
Implementation of
IStore.has
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L253
keys()
keys(): Promise<string[]>
Returns a list of all keys in the store.
Returns
Promise<string[]>
Implementation of
IStore.keys
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L275
length()
length(): Promise<number>
Returns the number of key-value pairs in the store.
Returns
Promise<number>
Implementation of
IStore.length
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L287
onChange()
onChange<T>(cb): Promise<UnlistenFn>
Listen to changes on the store.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
cb |
(key, value) => void |
Returns
Promise<UnlistenFn>
A promise resolving to a function to unlisten to the event.
Since
2.0.0
Implementation of
IStore.onChange
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L310
onKeyChange()
onKeyChange<T>(key, cb): Promise<UnlistenFn>
Listen to changes on a store key.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type | Description |
|---|---|---|
key |
string |
|
cb |
(value) => void |
Returns
Promise<UnlistenFn>
A promise resolving to a function to unlisten to the event.
Since
2.0.0
Implementation of
IStore.onKeyChange
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L299
reload()
reload(options?): Promise<void>
Attempts to load the on-disk state at the store’s path into memory.
This method is useful if the on-disk state was edited by the user and you want to synchronize the changes.
Note:
- This method loads the data and merges it with the current store, this behavior will be changed to resetting to default first and then merging with the on-disk state in v3, to fully match the store with the on-disk state, set
ignoreDefaultstotrue - This method does not emit change events.
Parameters
| Parameter | Type |
|---|---|
options? |
ReloadOptions |
Returns
Promise<void>
Implementation of
IStore.reload
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L291
reset()
reset(): Promise<void>
Resets the store to its default value.
If no default value has been set, this method behaves identical to clear.
Returns
Promise<void>
Implementation of
IStore.reset
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L271
save()
save(): Promise<void>
Saves the store to disk at the store’s path.
Returns
Promise<void>
Implementation of
IStore.save
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L295
set()
set(key, value): Promise<void>
Inserts a key-value pair into the store.
Parameters
| Parameter | Type | Description |
|---|---|---|
key |
string |
|
value |
unknown |
Returns
Promise<void>
Implementation of
IStore.set
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L237
values()
values<T>(): Promise<T[]>
Returns a list of all values in the store.
Type Parameters
| Type Parameter |
|---|
T |
Returns
Promise<T[]>
Implementation of
IStore.values
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L279
get()
static get(path): Promise<null | Store>
Gets an already loaded store.
If the store is not loaded, returns null. In this case you must load it.
This function is more useful when you already know the store is loaded and just need to access its instance. Prefer Store.load otherwise.
Parameters
| Parameter | Type | Description |
|---|---|---|
path |
string |
Path of the store. |
Returns
Example
import { Store } from '@tauri-apps/api/store';
let store = await Store.get('store.json');
if (!store) {
store = await Store.load('store.json');
}
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L231
load()
static load(path, options?): Promise<Store>
Create a new Store or load the existing store with the path.
Parameters
| Parameter | Type | Description |
|---|---|---|
path |
string |
Path to save the store in app_data_dir |
options? |
StoreOptions |
Store configuration options |
Returns
Example
import { Store } from '@tauri-apps/api/store';
const store = await Store.load('store.json');
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L204
Type Aliases
ReloadOptions
type ReloadOptions: object;
Options to IStore.reload a IStore
Type declaration
| Name | Type | Description | Defined in |
|---|---|---|---|
ignoreDefaults |
boolean |
To fully match the store with the on-disk state, ignoring defaults | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L461 |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L457
StoreOptions
type StoreOptions: object;
Options to create a store
Type declaration
| Name | Type | Description | Defined in |
|---|---|---|---|
autoSave |
boolean | number |
Auto save on modification with debounce duration in milliseconds, it’s 100ms by default, pass in false to disable it |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L28 |
createNew |
boolean |
Force create a new store with default values even if it already exists. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L40 |
defaults |
object |
Default value of the store | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L24 |
deserializeFnName |
string |
Name of a deserialize function registered in the rust side plugin builder | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L36 |
overrideDefaults |
boolean |
When creating the store, override the store with the on-disk state if it exists, ignoring defaults | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L44 |
serializeFnName |
string |
Name of a serialize function registered in the rust side plugin builder | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L32 |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L20
Functions
getStore()
function getStore(path): Promise<Store | null>
Gets an already loaded store.
If the store is not loaded, returns null. In this case you must load it.
This function is more useful when you already know the store is loaded and just need to access its instance. Prefer Store.load otherwise.
Parameters
| Parameter | Type | Description |
|---|---|---|
path |
string |
Path of the store. |
Returns
Example
import { getStore } from '@tauri-apps/api/store';
const store = await getStore('store.json');
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L82
load()
function load(path, options?): Promise<Store>
Create a new Store or load the existing store with the path.
Parameters
| Parameter | Type | Description |
|---|---|---|
path |
string |
Path to save the store in app_data_dir |
options? |
StoreOptions |
Store configuration options |
Returns
Example
import { Store } from '@tauri-apps/api/store';
const store = await Store.load('store.json');
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/store/guest-js/index.ts#L59
@tauri-apps/plugin-stronghold
Classes
Client
Constructors
new Client()
new Client(path, name): Client
Parameters
| Parameter | Type |
|---|---|
path |
string |
name |
ClientPath |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L265
Properties
| Property | Type | Defined in |
|---|---|---|
name |
ClientPath |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L263 |
path |
string |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L262 |
Methods
getStore()
getStore(): Store
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L280
getVault()
getVault(name): Vault
Get a vault by name.
Parameters
| Parameter | Type | Description |
|---|---|---|
name |
VaultPath |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L276
Location
Constructors
new Location()
new Location(type, payload): Location
Parameters
| Parameter | Type |
|---|---|
type |
string |
payload |
Record<string, unknown> |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L86
Properties
| Property | Type | Defined in |
|---|---|---|
payload |
Record<string, unknown> |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L84 |
type |
string |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L83 |
Methods
counter()
static counter(vault, counter): Location
Parameters
| Parameter | Type |
|---|---|
vault |
VaultPath |
counter |
number |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L98
generic()
static generic(vault, record): Location
Parameters
| Parameter | Type |
|---|---|
vault |
VaultPath |
record |
RecordPath |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L91
Store
Constructors
new Store()
new Store(path, client): Store
Parameters
| Parameter | Type |
|---|---|
path |
string |
client |
ClientPath |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L289
Properties
| Property | Type | Defined in |
|---|---|---|
client |
ClientPath |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L287 |
path |
string |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L286 |
Methods
get()
get(key): Promise<null | Uint8Array>
Parameters
| Parameter | Type |
|---|---|
key |
StoreKey |
Returns
Promise<null | Uint8Array>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L294
insert()
insert(
key,
value,
lifetime?): Promise<void>
Parameters
| Parameter | Type |
|---|---|
key |
StoreKey |
value |
number[] |
lifetime? |
Duration |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L302
remove()
remove(key): Promise<null | Uint8Array>
Parameters
| Parameter | Type |
|---|---|
key |
StoreKey |
Returns
Promise<null | Uint8Array>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L316
Stronghold
A representation of an access to a stronghold.
Properties
| Property | Type | Defined in |
|---|---|---|
path |
string |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L388 |
Methods
createClient()
createClient(client): Promise<Client>
Parameters
| Parameter | Type |
|---|---|
client |
ClientPath |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L428
loadClient()
loadClient(client): Promise<Client>
Parameters
| Parameter | Type |
|---|---|
client |
ClientPath |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L421
save()
save(): Promise<void>
Persists the stronghold state to the snapshot.
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L439
unload()
unload(): Promise<void>
Remove this instance from the cache.
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L415
load()
static load(path, password): Promise<Stronghold>
Load the snapshot if it exists (password must match), or start a fresh stronghold instance otherwise.
Parameters
| Parameter | Type | Description |
|---|---|---|
path |
string |
- |
password |
string |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L405
Vault
A key-value storage that allows create, update and delete operations. It does not allow reading the data, so one of the procedures must be used to manipulate the stored data, allowing secure storage of secrets.
Extends
ProcedureExecutor
Constructors
new Vault()
new Vault(
path,
client,
name): Vault
Parameters
| Parameter | Type |
|---|---|
path |
string |
client |
ClientPath |
name |
VaultPath |
Returns
Overrides
ProcedureExecutor.constructor
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L340
Properties
| Property | Type | Description | Inherited from | Defined in |
|---|---|---|---|---|
client |
ClientPath |
- | - | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L336 |
name |
VaultPath |
The vault name. | - | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L338 |
path |
string |
The vault path. | - | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L335 |
procedureArgs |
Record<string, unknown> |
- | ProcedureExecutor.procedureArgs |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L107 |
Methods
deriveSLIP10()
deriveSLIP10(
chain,
source,
sourceLocation,
outputLocation): Promise<Uint8Array>
Derive a SLIP10 private key using a seed or key.
Parameters
| Parameter | Type | Description |
|---|---|---|
chain |
number[] |
The chain path. |
source |
"Seed" | "Key" |
The source type, either ‘Seed’ or ‘Key’. |
sourceLocation |
Location |
The source location, must be the outputLocation of a previous call to generateSLIP10Seed or deriveSLIP10. |
outputLocation |
Location |
Location of the record where the private key will be stored. |
Returns
Inherited from
ProcedureExecutor.deriveSLIP10
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L145
generateBIP39()
generateBIP39(outputLocation, passphrase?): Promise<Uint8Array>
Generate a BIP39 seed.
Parameters
| Parameter | Type | Description |
|---|---|---|
outputLocation |
Location |
The location of the record where the BIP39 seed will be stored. |
passphrase? |
string |
The optional mnemonic passphrase. |
Returns
Inherited from
ProcedureExecutor.generateBIP39
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L200
generateSLIP10Seed()
generateSLIP10Seed(outputLocation, sizeBytes?): Promise<Uint8Array>
Generate a SLIP10 seed for the given location.
Parameters
| Parameter | Type | Description |
|---|---|---|
outputLocation |
Location |
Location of the record where the seed will be stored. |
sizeBytes? |
number |
The size in bytes of the SLIP10 seed. |
Returns
Inherited from
ProcedureExecutor.generateSLIP10Seed
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L120
getEd25519PublicKey()
getEd25519PublicKey(privateKeyLocation): Promise<Uint8Array>
Gets the Ed25519 public key of a SLIP10 private key.
Parameters
| Parameter | Type | Description |
|---|---|---|
privateKeyLocation |
Location |
The location of the private key. Must be the outputLocation of a previous call to deriveSLIP10. |
Returns
A promise resolving to the public key hex string.
Since
2.0.0
Inherited from
ProcedureExecutor.getEd25519PublicKey
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L223
insert()
insert(recordPath, secret): Promise<void>
Insert a record to this vault.
Parameters
| Parameter | Type |
|---|---|
recordPath |
RecordPath |
secret |
number[] |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L358
recoverBIP39()
recoverBIP39(
mnemonic,
outputLocation,
passphrase?): Promise<Uint8Array>
Store a BIP39 mnemonic.
Parameters
| Parameter | Type | Description |
|---|---|---|
mnemonic |
string |
The mnemonic string. |
outputLocation |
Location |
The location of the record where the BIP39 mnemonic will be stored. |
passphrase? |
string |
The optional mnemonic passphrase. |
Returns
Inherited from
ProcedureExecutor.recoverBIP39
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L175
remove()
remove(location): Promise<void>
Remove a record from the vault.
Parameters
| Parameter | Type | Description |
|---|---|---|
location |
Location |
The record location. |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L374
signEd25519()
signEd25519(privateKeyLocation, msg): Promise<Uint8Array>
Creates a Ed25519 signature from a private key.
Parameters
| Parameter | Type | Description |
|---|---|---|
privateKeyLocation |
Location |
The location of the record where the private key is stored. Must be the outputLocation of a previous call to deriveSLIP10. |
msg |
string |
The message to sign. |
Returns
A promise resolving to the signature hex string.
Since
2.0.0
Inherited from
ProcedureExecutor.signEd25519
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L244
Interfaces
AddressInfo
Properties
| Property | Type | Defined in |
|---|---|---|
peers |
Map<string, PeerAddress> |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L43 |
relays |
string[] |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L44 |
ClientAccess
Properties
ConnectionLimits
Properties
| Property | Type | Defined in |
|---|---|---|
maxEstablishedIncoming? |
number |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L31 |
maxEstablishedOutgoing? |
number |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L32 |
maxEstablishedPerPeer? |
number |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L33 |
maxEstablishedTotal? |
number |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L34 |
maxPendingIncoming? |
number |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L29 |
maxPendingOutgoing? |
number |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L30 |
Duration
A duration definition.
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
nanos |
number |
The fractional part of this Duration, in nanoseconds. Must be greater or equal to 0 and smaller than 1e+9 (the max number of nanoseoncds in a second) | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L79 |
secs |
number |
The number of whole seconds contained by this Duration. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L77 |
NetworkConfig
Properties
PeerAddress
Properties
| Property | Type | Defined in |
|---|---|---|
known |
string[] |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L38 |
use_relay_fallback |
boolean |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L39 |
Permissions
Properties
| Property | Type | Defined in |
|---|---|---|
default? |
ClientAccess |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L59 |
exceptions? |
Map<VaultPath, ClientAccess> |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L60 |
Type Aliases
ClientPath
type ClientPath: string | Iterable<number> | ArrayLike<number> | ArrayBuffer;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L7
RecordPath
type RecordPath: string | Iterable<number> | ArrayLike<number> | ArrayBuffer;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L17
StoreKey
type StoreKey: string | Iterable<number> | ArrayLike<number> | ArrayBuffer;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L22
VaultPath
type VaultPath: string | Iterable<number> | ArrayLike<number> | ArrayBuffer;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/stronghold/guest-js/index.ts#L12
@tauri-apps/plugin-updater
Classes
Update
Extends
Resource
Constructors
new Update()
new Update(metadata): Update
Parameters
| Parameter | Type |
|---|---|
metadata |
UpdateMetadata |
Returns
Overrides
Resource.constructor
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/updater/guest-js/index.ts#L77
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
available |
boolean |
Deprecated This is always true, check if the return value is null instead when using check |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/updater/guest-js/index.ts#L69 |
body? |
string |
- | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/updater/guest-js/index.ts#L73 |
currentVersion |
string |
- | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/updater/guest-js/index.ts#L70 |
date? |
string |
- | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/updater/guest-js/index.ts#L72 |
rawJson |
Record<string, unknown> |
- | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/updater/guest-js/index.ts#L74 |
version |
string |
- | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/updater/guest-js/index.ts#L71 |
Accessors
rid
get rid(): number
Returns
number
Inherited from
Resource.rid
Source: undefined
Methods
close()
close(): Promise<void>
Destroys and cleans up this resource from memory. You should not call any method on this object anymore and should drop any reference to it.
Returns
Promise<void>
Overrides
Resource.close
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/updater/guest-js/index.ts#L138
download()
download(onEvent?, options?): Promise<void>
Download the updater package
Parameters
| Parameter | Type |
|---|---|
onEvent? |
(progress) => void |
options? |
DownloadOptions |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/updater/guest-js/index.ts#L88
downloadAndInstall()
downloadAndInstall(onEvent?, options?): Promise<void>
Downloads the updater package and installs it
Parameters
| Parameter | Type |
|---|---|
onEvent? |
(progress) => void |
options? |
DownloadOptions & InstallOptions |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/updater/guest-js/index.ts#L122
install()
install(options?): Promise<void>
Install downloaded updater package
Parameters
| Parameter | Type |
|---|---|
options? |
InstallOptions |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/updater/guest-js/index.ts#L106
Interfaces
CheckOptions
Options used when checking for updates
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
allowDowngrades? |
boolean |
Allow downgrades to previous versions by not checking if the current version is greater than the available version. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/updater/guest-js/index.ts#L28 |
headers? |
HeadersInit |
Request headers | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/updater/guest-js/index.ts#L12 |
proxy? |
string |
A proxy url to be used when checking and downloading updates. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/updater/guest-js/index.ts#L20 |
target? |
string |
Target identifier for the running application. This is sent to the backend. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/updater/guest-js/index.ts#L24 |
timeout? |
number |
Timeout in milliseconds | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/updater/guest-js/index.ts#L16 |
DownloadOptions
Options used when downloading an update
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
headers? |
HeadersInit |
Request headers | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/updater/guest-js/index.ts#L36 |
timeout? |
number |
Timeout in milliseconds | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/updater/guest-js/index.ts#L40 |
Type Aliases
DownloadEvent
type DownloadEvent: object | object | object;
Updater download event
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/updater/guest-js/index.ts#L61
Functions
check()
function check(options?): Promise<Update | null>
Check for updates, resolves to null if no updates are available
Parameters
| Parameter | Type |
|---|---|
options? |
CheckOptions |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/updater/guest-js/index.ts#L145
@tauri-apps/plugin-upload
Enumerations
HttpMethod
Enumeration Members
Patch
Patch: "PATCH";
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/upload/guest-js/index.ts#L19
Post
Post: "POST";
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/upload/guest-js/index.ts#L17
Put
Put: "PUT";
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/upload/guest-js/index.ts#L18
Functions
download()
function download(
url,
filePath,
progressHandler?,
headers?,
body?): Promise<void>
Parameters
| Parameter | Type |
|---|---|
url |
string |
filePath |
string |
progressHandler? |
ProgressHandler |
headers? |
Map<string, string> |
body? |
string |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/upload/guest-js/index.ts#L53
upload()
function upload(
url,
filePath,
progressHandler?,
headers?,
method?): Promise<string>
Parameters
| Parameter | Type |
|---|---|
url |
string |
filePath |
string |
progressHandler? |
ProgressHandler |
headers? |
Map<string, string> |
method? |
HttpMethod |
Returns
Promise<string>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/upload/guest-js/index.ts#L22
@tauri-apps/plugin-websocket
Classes
default
Constructors
new default()
new default(id, listeners): default
Parameters
| Parameter | Type |
|---|---|
id |
number |
listeners |
Set<(arg) => void> |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/websocket/guest-js/index.ts#L63
Properties
| Property | Type | Defined in |
|---|---|---|
id |
number |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/websocket/guest-js/index.ts#L60 |
Methods
addListener()
addListener(cb): () => void
Parameters
| Parameter | Type |
|---|---|
cb |
(arg) => void |
Returns
Function
Returns
void
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/websocket/guest-js/index.ts#L92
disconnect()
disconnect(): Promise<void>
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/websocket/guest-js/index.ts#L119
send()
send(message): Promise<void>
Parameters
| Parameter | Type |
|---|---|
message |
string | number[] | Message |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/websocket/guest-js/index.ts#L100
connect()
static connect(url, config?): Promise<default>
Parameters
| Parameter | Type |
|---|---|
url |
string |
config? |
ConnectionConfig |
Returns
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/websocket/guest-js/index.ts#L68
Interfaces
CloseFrame
Properties
| Property | Type | Defined in |
|---|---|---|
code |
number |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/websocket/guest-js/index.ts#L48 |
reason |
string |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/websocket/guest-js/index.ts#L49 |
ConnectionConfig
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
acceptUnmaskedFrames? |
boolean |
When set to true, the server will accept and handle unmasked frames from the client. According to the RFC 6455, the server must close the connection to the client in such cases, however it seems like there are some popular libraries that are sending unmasked frames, ignoring the RFC. By default this option is set to false, i.e. according to RFC 6455. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/websocket/guest-js/index.ts#L35 |
headers? |
HeadersInit |
Additional connect request headers. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/websocket/guest-js/index.ts#L39 |
maxFrameSize? |
number | "none" |
The maximum size of a single incoming message frame. The string “none” means no size limit. The limit is for frame payload NOT including the frame header. The default value is 16 MiB which should be reasonably big for all normal use-cases but small enough to prevent memory eating by a malicious user. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/websocket/guest-js/index.ts#L31 |
maxMessageSize? |
number | "none" |
The maximum size of an incoming message. The string “none” means no size limit. The default value is 64 MiB which should be reasonably big for all normal use-cases but small enough to prevent memory eating by a malicious user. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/websocket/guest-js/index.ts#L27 |
maxWriteBufferSize? |
number |
The max size of the write buffer in bytes. Setting this can provide backpressure in the case the write buffer is filling up due to write errors. The default value is unlimited. Note: The write buffer only builds up past write_buffer_size when writes to the underlying stream are failing. So the write buffer can not fill up if you are not observing write errors. Note: Should always be at least write_buffer_size + 1 message and probably a little more depending on error handling strategy. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/websocket/guest-js/index.ts#L23 |
readBufferSize? |
number |
Read buffer capacity. The default value is 128 KiB. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/websocket/guest-js/index.ts#L11 |
writeBufferSize? |
number |
The target minimum size of the write buffer to reach before writing the data to the underlying stream. The default value is 128 KiB. If set to 0 each message will be eagerly written to the underlying stream. It is often more optimal to allow them to buffer a little, hence the default value. | Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/websocket/guest-js/index.ts#L16 |
MessageKind<T, D>
Type Parameters
| Type Parameter |
|---|
T |
D |
Properties
| Property | Type | Defined in |
|---|---|---|
data |
D |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/websocket/guest-js/index.ts#L44 |
type |
T |
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/websocket/guest-js/index.ts#L43 |
Type Aliases
Message
type Message:
| MessageKind<"Text", string>
| MessageKind<"Binary", number[]>
| MessageKind<"Ping", number[]>
| MessageKind<"Pong", number[]>
| MessageKind<"Close", CloseFrame | null>;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/websocket/guest-js/index.ts#L52
@tauri-apps/plugin-window-state
Enumerations
StateFlags
Enumeration Members
ALL
ALL: 63;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/window-state/guest-js/index.ts#L15
DECORATIONS
DECORATIONS: 16;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/window-state/guest-js/index.ts#L13
FULLSCREEN
FULLSCREEN: 32;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/window-state/guest-js/index.ts#L14
MAXIMIZED
MAXIMIZED: 4;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/window-state/guest-js/index.ts#L11
POSITION
POSITION: 2;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/window-state/guest-js/index.ts#L10
SIZE
SIZE: 1;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/window-state/guest-js/index.ts#L9
VISIBLE
VISIBLE: 8;
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/window-state/guest-js/index.ts#L12
Functions
filename()
function filename(): Promise<string>
Get the name of the file used to store window state.
Returns
Promise<string>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/window-state/guest-js/index.ts#L44
restoreState()
function restoreState(label, flags?): Promise<void>
Restore the state for the specified window from disk.
Parameters
| Parameter | Type |
|---|---|
label |
string |
flags? |
StateFlags |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/window-state/guest-js/index.ts#L28
restoreStateCurrent()
function restoreStateCurrent(flags?): Promise<void>
Restore the state for the current window from disk.
Parameters
| Parameter | Type |
|---|---|
flags? |
StateFlags |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/window-state/guest-js/index.ts#L38
saveWindowState()
function saveWindowState(flags?): Promise<void>
Save the state of all open windows to disk.
Parameters
| Parameter | Type |
|---|---|
flags? |
StateFlags |
Returns
Promise<void>
Source: https://github.com/tauri-apps/plugins-workspace/blob/v2/plugins/window-state/guest-js/index.ts#L21
Webview Versions
WebView2 (Windows)
Tauri uses WebView2 which is based on Microsoft Edge and therefore Chromium. WebView2 can update itself, you are guaranteed a relatively recent chromium build on all Windows targets.
WebView2 is supported on Windows 7 and newer and comes preinstalled on Windows 11. On versions older than Windows 11 the installer generated by Tauri takes care of ensuring WebView2 is installed on the system.
Android WebView (Android)
Tauri uses the system Android WebView, which is based on Chromium. Tauri does not bundle a WebView with your app, so the runtime version depends on the device’s currently selected WebView provider.
On most production Android devices, WebView is an updatable system component. Some Android images can use a different preinstalled provider or allow switching providers in developer settings, so web platform support is tied to that provider’s Chromium/WebView version.
To check the version used by a development build, open the Android Web Inspector and inspect the running WebView with Chrome DevTools. You can also check the selected WebView provider and app version in Android’s developer settings.
WebKit (macOS, iOS, & Linux)
Tauri uses WebKit on macOS (through WKWebView) and Linux (through webkit2gtk).
Interpreting WebKit Version Numbers
Webkit version numbers are quite complicated, so below is some helpful information to understand them.
WebKit version numbers are made up of 5 segments and a numeric prefix indicating which OS WebKit is built for:
$(SYSTEM_VERSION_PREFIX)$(MAJOR_VERSION).$(MINOR_VERSION).$(TINY_VERSION).$(MICRO_VERSION).$(NANO_VERSION)
The numeric prefix is called the SYSTEM_VERSION_PREFIX and seems to be only present for macOS and iOS builds (not for Linux). Furthermore, if the last two segments are both 0 they can be omitted (so a version like 613.2.7.0.0 would be referred to as 613.2.7).
As an example, the WebKit version shipped with Safari 15.5 on macOS Monterey (12.x) has the version number 17613.2.7.1.8. You can interpret it like this:
SYSTEM_VERSION_PREFIX: 17MAJOR_VERSION: 613MINOR_VERSION: 2TINY_VERSION: 7MICRO_VERSION: 1NANO_VERSION: 8
Here is what the SYSTEM_VERSION_PREFIX values map to:
| macOS version | SYSTEM_VERSION_PREFIX |
|---|---|
| sdk=iphone* | 8 |
| 14.0 | 19 |
| 13.0 | 18 |
| 12.0 | 17 |
| 11.0 | 16 |
| 10.15 | 15 |
| 10.14 | 14 |
| 10.13 | 13 |
| 10.12 | 12 |
| 10.11 | 11 |
macOS & iOS
On macOS, Tauri uses the webview that comes preinstalled with macOS since version 10.10 (Yosemite). It is considered a core component and is therefore updated with the regular OS updates. This means unsupported macOS versions do not receive WebKit updates.
To find the WebKit version used by WKWebView on your version of macOS you can use this command in the terminal:
awk '/CFBundleVersion/{getline;gsub(/<[^>]*>/,"");print}' /System/Library/Frameworks/WebKit.framework/Resources/Info.plist
WebKit Versions in Safari
The table below maps an OS version to the corresponding WebKit Safari versions so that you can use sites like caniuse to figure out if a specific web platform feature is supported.
| OS Name | OS Version | WebKit Version | Safari Version | Notes |
|---|---|---|---|---|
| Sonoma | 14.0 (Beta) | 616.1.14.11.11 | 17.0 | Verified on a 2023 M2 14“ MacBook Pro |
| Ventura | 13.4.1 | 615.2.9.11.7 | 16.5.1 | Verified on a 2023 M2 14“ MacBook Pro |
| 13.3.1 | 615.1.26.11.23 | Verified on a 2023 M2 14“ MacBook Pro | ||
| 13.3 | 615.1.26.11.22 | 16.4 | Verified on a 2023 M2 14“ MacBook Pro | |
| 13.2.1 | 614.4.6.1.6 | |||
| 13.2 | ? | 16.3 | ||
| 13.1 | 614.3.7.1.5 | 16.2 | Verified on a 2020 M1 13“ MacBook Pro | |
| 13.0.1 | Verified on a 2020 M1 13“ MacBook Pro | |||
| 13.0 | 614.2.9.1.12 | 16.1 | Verified on a 2020 M1 13“ MacBook Pro | |
| Monterey | 12.6 | Verified on a 2020 M1 13“ MacBook Pro | ||
| 12.5.1 | 613.3.9.1.16 | 15.6.1 | Verified on a 2020 M1 13“ MacBook Pro | |
| 12.5 | 613.3.9.1.5 | 15.6 | Verified on a 2020 M1 13“ MacBook Pro | |
| 12.4 | 613.2.7.1.8 | 15.5 | Verified on a 2020 M1 13“ MacBook Pro | |
| 12.3.1 | 613.1.17.1.13 | |||
| 12.3 | 613.1.17.1.6 | 15.4 | ||
| 12.2.1 | 612.4.9.1.8 | |||
| 12.2 | 612.4.9.1.5 | 15.3 | ||
| 12.1.1 | ||||
| 12.1 | 612.3.6.1.6 | 15.2 | ||
| 12.0.1 | 612.2.9.1.20 | 15.1 | ||
| 12.0 | 612.1.29.41.4 | 15.0 | ||
| Big Sur | 11.6.7 | |||
| 11.6.6 | ||||
| 11.6.5 | ||||
| 11.6.2 | ||||
| 11.6.1 | ||||
| 11.6 | ||||
| 11.5.2 | 611.3.10.1.6 | |||
| 11.5.1 | ||||
| 11.5 | 611.3.10.1.3 | 14.1.2 | ||
| 11.4 | 611.2.7.1.4 | 14.1.1 | ||
| 11.3.1 | ||||
| 11.3 | 611.1.21.161.3 | 14.1 | 24“ M1 iMac received a special WebKit version 611.1.21.1.12 | |
| 11.2.3 | 610.4.3.1.7 | |||
| 11.2.2 | ||||
| 11.2.1 | ||||
| 11.2 | 610.4.3.1.4 | 14.0.3 | ||
| 11.1 | 610.3.7.1.9 | 14.0.2 | ||
| 11.0.1 | 610.2.11.51.8 | |||
| 11.0 | 610.2.11.1.3 | 14.0.1 | Safari 14.0 was only ever available on iPhones | |
| Catalina | 10.15.7 Security Update 2022-004 | 609.4.1.1.1 | ||
| 10.15.7 | 609.4.1 | 13.1.3 | ||
| 10.15.6 | 609.3.5.1.3 | 13.1.2 | ||
| 10.15.5 | 609.2.9.1.2 | 13.1.1 | ||
| 10.15.4 | 609.1.20.111.8 | 13.1 | ||
| 10.15.3 | 608.5.11 | 13.0.5 | ||
| 10.15.2 | 608.4.9.1.3 | 13.0.4 | ||
| 10.15.1 | 608.3.10.1.4 | 13.0.3 | Verified on a 2014 15“ MacBook Pro | |
| 10.15 | 608.2.30.1.1 | 13.0.2 | ||
| Mojave | 10.14.6 | 608.1.49 | 13.0 | |
| 10.14.4 | 607.1.40.1.5 | 12.1 | ||
| 10.14.3 | 606.4.5 | 12.0.3 | ||
| 10.14.2 | 606.3.4 | 12.0.2 | ||
| 10.14.1 | 606.2.104.1.1 | 12.0.1 | ||
| 10.14 | 606.2.11 | 12.0 | ||
| High Sierra | 10.13.6 | 605.3.8 | 11.1.2 | |
| 10.13.5 | 605.2.8 | 11.1.1 | ||
| 10.13.4 Security Update 2018-001 | 605.1.33.1.4 | 11.1 | ||
| 10.13.4 | 605.1.33.1.2 | 11.1 | ||
| 10.13.3 | 604.5.6 | 11.0.3 | ||
| 10.13.2 Supplemental Update | 604.4.7.1.6 | 11.0.2 | 27“ iMac Pro received a special WebKit version 604.4.7.10.6 | |
| 10.13.2 | 604.4.7.1.3 | 11.0.2 | 27“ iMac Pro received a special WebKit version 604.4.7.10.4 | |
| 10.13.1 | 604.3.5 | 11.0.1 | ||
| 10.13 | 604.1.38.1.6 | 11.0 |
Linux
The diverse nature of the Linux ecosystem means it is very hard to compile accurate information about WebKitGTK on the various distros. The table below is a very incomplete list of the most commonly used distributions and their WebKit versions. You should always check your distro’s repositories for up-to-date information.
| Distro | webkitgtk Version |
WebKit Version | Safari Equivalent |
|---|---|---|---|
| Debian 11 (with update), Ubuntu 20.04 (with update), Ubuntu 22.04 | 2.36 | 614.1.6 | TP 140 (16.0) |
| Debian 10 (with update) | 2.34 | 613.1.1 | 15.4 |
| Debian 11, Ubuntu 18.04 (with update), centos 8 (non-stream) | 2.32 | 612.1.6 | 15.0 |
| Ubuntu 20.04 | 2.28 | 610.1.1 | 14.0 |
| Debian 9 (with backport), Debian 10 | 2.24 | 608.1.6 | 13.0 |
| Ubuntu 18.04 | 2.20 | 606.1.4 | 12.0 |
Tauri RSS Feeds
All updatesGet notified about any updates across the entire site.
Blog updatesStay up-to-date with the latest blog posts and articles.
Pages updatesReceive updates for the main website pages.
Security
High-level concepts and security features at the core of Tauri's design and ecosystem that make you, your applications and your users more secure by default
This page is designed to explain the high-level concepts and security features at the core of Tauri’s design and ecosystem that make you, your applications and your users more secure by default.
It also includes advice on best practices, how to report vulnerabilities to us and references to detailed concept explanations.
Note
It is important to remember that the security of your Tauri application is the sum of the overall security of Tauri itself, all Rust and npm dependencies, your code, and the devices that run the final application. The Tauri team does its best to do their part, the security community does its part and you should also follow some important best practices.
Trust Boundaries
Trust boundary is a term used in computer science and security which describes a boundary where program data or execution changes its level of “trust,” or where two principals with different capabilities exchange data or commands. 1
Tauri’s security model differentiates between Rust code written for the application’s core and frontend code written in any framework or language understood by the system WebView.
Inspecting and strongly defining all data passed between boundaries is very important to prevent trust boundary violations. If data is passed without access control between these boundaries then it’s easy for attackers to elevate and abuse privileges.
The IPC layer is the bridge for communication between these two trust groups and ensures that boundaries are not broken.
Any code executed by the plugins or the application core has full access to all available system resources and is not constrained.
Any code executed in the WebView has only access to exposed system resources via the well-defined IPC layer. Access to core application commands is configured and restricted by capabilities defined in the application configuration. The individual command implementations enforce the optional fine-grained access levels also defined in the capabilities configuration.
Learn more about the individual components and boundary enforcement:
Tauri allows developers to choose their own frontend stack and framework. This means that we cannot provide a hardening guide for every frontend stack of of choice, but Tauri provides generic features to control and contain the attack surface.
(Not) Bundling WebViews
Tauri’s approach is to rely on the operating system WebView and not bundling the WebView into the application binary.
This has a multitude of reasons but from a security perspective the most important reason is the average time it takes from publication of a security patched version of a WebView to being rolled out to the application end user.
We have observed that WebView packet maintainer and operating system packet maintainers are in average significantly faster to patch and roll out security patched Webview releases than application developers who bundle the WebView directly with their application.
There are exceptions from this observation and in theory both paths can be taken in a similar time frame but this involves a larger overhead infrastructure for each application.
Bundling has it’s drawbacks from a Tauri application developer experience and we do not think it is inherently insecure but the current design is a trade off that significantly reduces known vulnerabilities in the wild.
Ecosystem
The Tauri organization provides and maintains more than just the Tauri repository, and to ensure we provide a reasonable secure multi platform application framework, we make sure to go some extra miles.
To learn more about how we secure our development process, what you could adapt and implement, what known threats your application can face and what we plan to improve or harden in the future, you can check out the following documents:
Coordinated Disclosure
If you feel that there is a security concern or issue with anything in Tauri or other repositories in our organization, please do not publicly comment on your findings. Instead, reach out directly to our security team.
The preferred disclosure method is via Github Vulnerability Disclosure on the affected repository. Most of our repositories have this feature enabled but if in doubt please submit via the Tauri repository.
Alternatively you can contact us via email at: security@tauri.app.
Although we do not currently have a budget for security bounties, in some cases, we will consider rewarding coordinated disclosure with our limited resources.
Footnotes
Asset protocol scope
Configure app.security.assetProtocol so the WebView can load local files safely, including FsScope, requireLiteralLeadingDot, and dynamic paths.
Tauri can serve files from disk into the WebView through the asset custom protocol (for example when you use convertFileSrc in the frontend). Whether a path is allowed is controlled by app.security.assetProtocol in tauri.conf.json.
You must set enable to true and define a scope that lists which filesystem paths may be exposed. Paths resolved at runtime must match that scope, or the WebView will refuse the load (often with an error such as “asset protocol not configured to allow the path”).
Content Security Policy for asset: sources is documented on the Content Security Policy (CSP) page. This page focuses on scope and how it interacts with globs and hidden path segments.
How scope is defined
assetProtocol.scope uses the same FsScope type as filesystem-related configuration elsewhere: either a JSON array of allowed glob patterns, or a JSON object with allow, optional deny, and optional requireLiteralLeadingDot. For how “scopes” fit into Tauri’s security model more broadly, see Command scopes.
Patterns may start with a base directory variable (for example $HOME, $CACHE, $APPCACHE, $APPDATA, $RESOURCE). See the path / base directory APIs for the full set of variables your app can rely on.
Paths resolved when loading assets are usually absolute (on Linux, often under /home/...). A pattern like ["*/**"] typically does not match those paths, because it does not line up with a leading / or a base-directory variable. Prefer patterns such as $HOME/**/*, /home/username/**/*, or another form that mirrors the resolved path.
Array form (allowed paths only)
Use a list when you only need a fixed allow list and default glob behavior is enough:
src-tauri/tauri.conf.json
{
"app": {
"security": {
"assetProtocol": {
"enable": true,
"scope": ["$APPCACHE/**/*", "$RESOURCE/**/*"]
}
}
}
}
With the array form you cannot set requireLiteralLeadingDot; for that, use the object form below.
Object form (allow, deny, requireLiteralLeadingDot)
Use an object when you need deny rules or to change leading-dot matching:
src-tauri/tauri.conf.json
{
"app": {
"security": {
"assetProtocol": {
"enable": true,
"scope": {
"allow": ["$APPCACHE/**/*"],
"deny": ["$APPCACHE/**/secrets/**"]
}
}
}
}
}
deny takes precedence over allow when both match.
Unix: path segments starting with .
On Unix, requireLiteralLeadingDot defaults to true. Then wildcard tokens such as *, ?, **, and [...] do not match a path component that starts with . (dotfiles and dot-directories such as .cache or .ssh).
So a pattern like $HOME/** can allow /home/user/Documents/file.png but not /home/user/.cache/myapp/preview.png, because .cache is a dot-prefixed component. A pattern that names the segment literally (for example $HOME/.cache/myapp/**) does match.
To allow dot-prefixed components under a broad glob, you can set requireLiteralLeadingDot to false on the object scope (this widens what the WebView can load; review carefully):
src-tauri/tauri.conf.json
{
"app": {
"security": {
"assetProtocol": {
"enable": true,
"scope": {
"requireLiteralLeadingDot": false,
"allow": ["$HOME/**/*"]
}
}
}
}
}
Still blocked on Linux-style paths?
Community members often hit this when a path goes through a dot-directory (for example ~/.cache/...) while the allow pattern only uses ** under $HOME. See the discussion in tauri#13788 for concrete examples and fixes.
Prefer **/* over bare ** for “all files under here”
For globs that should match files under a tree, prefer **/* (and variants like $DIR/**/*) rather than bare **, consistent with other Tauri path examples. Bare ** is easy to misuse when you intend “everything under this directory recursively.”
Highly permissive configuration (use with extreme care)
If you intentionally need the broadest possible access and dot-prefixed segments, a maintainer-suggested shape looks like this. This is not a default recommendation; it increases exposure of hidden and sensitive files.
src-tauri/tauri.conf.json
{
"app": {
"security": {
"assetProtocol": {
"enable": true,
"scope": {
"requireLiteralLeadingDot": false,
"allow": ["**/*"]
}
}
}
}
}
Caution
Prefer narrow directories ($APPCACHE, $RESOURCE, a single app subfolder under $HOME, etc.) instead of broad $HOME/**/* or **/* unless you have a strong reason and understand the security tradeoffs.
Static config vs dynamically chosen paths
Entries in tauri.conf.json describe static allow/deny patterns. They do not replace runtime workflows where the user picks arbitrary folders or files (for example with the dialog plugin): those paths may need to be persisted across restarts using the persisted-scope plugin.
To persist asset / protocol-related scope with that plugin, enable its protocol-asset Cargo feature in src-tauri/Cargo.toml, for example:
tauri-plugin-persisted-scope = { version = "2", features = ["protocol-asset"] }
Register tauri_plugin_fs before tauri_plugin_persisted_scope as described in the plugin guide.
Troubleshooting
| Symptom | Things to check |
|---|---|
| “asset protocol not configured to allow the path” | Path must match an allow pattern; deny overrides allow. Use absolute patterns or $VAR/$HOME style variables that match how the path is resolved on disk. |
Works for normal folders but not under .cache / .config |
On Unix, default requireLiteralLeadingDot behavior: use a literal .segment in the pattern, or set requireLiteralLeadingDot: false in the object scope (see tauri#13788). |
| User picked a folder at runtime; still blocked after restart | You may need persisted-scope with the protocol-asset feature, not only tauri.conf.json entries. |
Broad ** seems wrong |
Try **/* for file-oriented globs; see Embedding Additional Files for similar ** vs **/* guidance in bundle resources. |
Scope like ["*/**"] never matches on Linux |
Resolved paths are absolute; use $... variables, a leading /, or another pattern that matches the real path (see above). |
The authoritative Rust types for assetProtocol and FsScope live in Tauri’s config.rs (AssetProtocolConfig, FsScope). The generated configuration reference may render nested FsScope fields in a compact or hard-to-read way; if something looks unclear there, cross-check this page and the file system plugin requireLiteralLeadingDot section (plugin config uses the same option name for its own scopes). If the reference still does not document those fields clearly, consider opening an issue on the tauri-docs repository so the config generator can be improved.
Capabilities
Tauri provides application and plugin developers with a capabilities system, to granually enable and constrain the core exposure to the application frontend running in the system WebView.
Capabilities define which permissions are granted or denied for which windows or webviews.
Capabilities can affect multiple windows and webviews and these can be referenced in multiple capabilities.
Security Tip
Windows and WebViews which are part of more than one capability effectively merge the security boundaries and permissions of all involved capabilities.
Capability files are either defined as a JSON or a TOML file inside the src-tauri/capabilities directory.
It is good practice to use individual files and only reference them by identifier in the tauri.conf.json but it is also possible to define them directly in the capabilities field.
All capabilities inside the capabilities directory are automatically enabled by default. Once capabilities are explicitly enabled in the tauri.conf.json, only these are used in the application build.
For a full reference of the configuration scheme please see the references section.
The following example JSON defines a capability that allows the main window use the default functionality of core plugins and the window.setTitle API.
src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
"core:path:default",
"core:event:default",
"core:window:default",
"core:app:default",
"core:resources:default",
"core:menu:default",
"core:tray:default",
"core:window:allow-set-title"
]
}
These snippets are part of the Tauri configuration file.
This is likely the most common configuration method, where the individual capabilities are inlined and only permissions are referenced by identifier.
This requires well defined capability files in the capabilities directory.
src-tauri/tauri.conf.json
{
"app": {
"security": {
"capabilities": ["my-capability", "main-capability"]
}
}
}
Inline capabilities can be mixed with pre-defined capabilities.
src-tauri/tauri.conf.json
{
"app": {
"security": {
"capabilities": [
{
"identifier": "my-capability",
"description": "My application capability used for all windows",
"windows": ["*"],
"permissions": ["fs:default", "allow-home-read-extended"]
},
"my-second-capability"
]
}
}
}
By default, all commands that you registered in your app (using the tauri::Builder::invoke_handler function) are allowed to be used by all the windows and webviews of the app. To change that, consider using AppManifest::commands.
src-tauri/build.rs
fn main() {
tauri_build::try_build(
tauri_build::Attributes::new()
.app_manifest(tauri_build::AppManifest::new().commands(&["your_command"])),
)
.unwrap();
}
Target Platform
Capabilities can be platform-specific by defining the platforms array. By default the capability is applied to all targets, but you can select a subset of the linux, macOS, windows, iOS and android targets.
For example a capability for desktop operating systems. Note it enables permissions on plugins that are only available on desktop:
src-tauri/capabilities/desktop.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "desktop-capability",
"windows": ["main"],
"platforms": ["linux", "macOS", "windows"],
"permissions": ["global-shortcut:allow-register"]
}
And another example of a capability for mobile. Note it enables permissions on plugins that are only available on mobile:
src-tauri/capabilities/mobile.json
{
"$schema": "../gen/schemas/mobile-schema.json",
"identifier": "mobile-capability",
"windows": ["main"],
"platforms": ["iOS", "android"],
"permissions": [
"nfc:allow-scan",
"biometric:allow-authenticate",
"barcode-scanner:allow-scan"
]
}
Remote API Access
By default the API is only accessible to bundled code shipped with the Tauri App. To allow remote sources access to certain Tauri Commands it is possible to define this in the capability configuration file.
This example would allow to scan for NFC tags and to use the barcode scanner from all subdomains of tauri.app.
src-tauri/capabilities/remote-tags.json
{
"$schema": "../gen/schemas/remote-schema.json",
"identifier": "remote-tag-capability",
"windows": ["main"],
"remote": {
"urls": ["https://*.tauri.app"]
},
"platforms": ["iOS", "android"],
"permissions": ["nfc:allow-scan", "barcode-scanner:allow-scan"]
}
Caution
On Linux and Android, Tauri is unable to distinguish between requests from an embedded <iframe> and the window itself.
Please consider usage of this feature very carefully and read more into the specific security implications for your targeted operating system in the reference section of this feature.
Security Boundaries
What does it protect against?
Depending on the permissions and capabilities it is able to:
- Minimize impact of frontend compromise
- Prevent or reduce (accidential) exposure of local system interfaces and data
- Prevent or reduce possible privilege escalation from frontend to backend/system
What does it not protect against?
- Malicious or insecure Rust code
- Too lax scopes and configuration
- Incorrect scope checks in the command implementation
- Intentional bypasses from Rust code
- Basically anything which was written in the rust core of an application
- 0-days or unpatched 1-days in the system WebView
- Supply chain attacks or otherwise compromised developer systems
Security Tip
The security boundaries are depending on window labels (not titles). We recommend to only expose of the window creation functionality to higher privileged windows.
Schema Files
Tauri generates JSON schemas with all the permissions available to your application through tauri-build, allowing autocompletion in your IDE. To use a schema, set the $schema property in your configuration file (either .json or .toml) to one of the platform-specific schemas located in the gen/schemas directory. Usually you will set it to ../gen/schemas/desktop-schema.json or ../gen/schemas/mobile-schema.json though you can also define a capability for a specific target platform.
Configuration Files
Simplified example of an example Tauri application directory structure:
tauri-app
├── index.html
├── package.json
├── src/
├── src-tauri/
│ ├── Cargo.toml
│ ├── capabilities/
│ │ └── <identifier>.json/toml
│ ├── src/
│ ├── tauri.conf.json
Everything can be inlined into the tauri.conf.json but even a little more advanced configuration would bloat this file and the goal of this approach is that the permissions are abstracted away whenever possible and simple to understand.
Core Permissions
A list of all core permissions can be found on the Core Permissions page.
Content Security Policy (CSP)
Tauri restricts the Content Security Policy (CSP) of your HTML pages. This can be used to reduce or prevent impact of common web based vulnerabilities like cross-site-scripting (XSS).
Local scripts are hashed, styles and external scripts are referenced using a cryptographic nonce, which prevents unallowed content from being loaded.
Caution
Avoid loading remote content such as scripts served over a CDN as they introduce an attack vector. In general any untrusted file can introduce new and subtle attack vectors.
The CSP protection is only enabled if set on the Tauri configuration file. You should make it as restricted as possible, only allowing the webview to load assets from hosts you trust, and preferably own. At compile time, Tauri appends its nonces and hashes to the relevant CSP attributes automatically to bundled code and assets, so you only need to worry about what is unique to your application.
This is an example CSP configuration taken from the api example of Tauri, but every application developer needs to tailor this to their own application needs.
tauri/examples/api/src-tauri/tauri.conf.json
"csp": {
"default-src": "'self' customprotocol: asset:",
"connect-src": "ipc: http://ipc.localhost",
"font-src": ["https://fonts.gstatic.com"],
"img-src": "'self' asset: http://asset.localhost blob: data:",
"style-src": "'unsafe-inline' 'self' https://fonts.googleapis.com"
},
Tip
When using Rust to develop your frontend, or if your frontend otherwise uses WebAssembly, remember to include 'wasm-unsafe-eval' as a script-src.
See script-src, style-src and CSP Sources for more information about this protection.
Tauri Ecosystem Security
Our Tauri organization ecosystem is hosted on GitHub and facilitates several features to make our repositories more resilient against adversaries targeting our source code and releases.
To reduce risk and to comply with commonly adopted best practices we have the following methods in place.
Build Pipelines
The process of releasing our source-code artifacts is highly automated in GitHub build pipelines using GitHub actions, yet mandates kickoff and review from real humans.
Signed Commits
Our core repositores require signed commits to reduce risk of impersonation and to allow identification of attributed commits after detection of possible compromise.
Code Review
All Pull Requests (PRs) merged into our repositories need approval from at least one maintainer of the project, which in most cases is the working group. Code is generally reviewed in PRs and default security workflows and checks are run to ensure the code adheres to common standards.
Release Process
Our working group reviews code changes, tags PRs with scope, and makes sure that everything stays up to date. We strive to internally audit all security relevant PRs before publishing minor and major releases.
And when its time to publish a new version, one of the maintainers tags a new release on dev, which:
- Validates core
- Runs tests
- Audits security for crates and npm
- Generates changelogs
- Creates artifacts
- Creates a draft release
Then the maintainer reviews the release notes, edits if necessary, and a new release is forged.
Future Work
This section describes topics we started or would like to tackle in the future to make Tauri apps even more secure. If you feel interested in these topics or have pre-existing knowledge we are always happy to welcome new contributors and advice via GitHub or other community platforms like Discord.
Binary Analysis
To allow pentesters, auditors and automated security checks do to their job properly it is very valuable to provide insight even from compiled binaries. Not all companies are open source or provide source code for audits, red-teams and other security testing.
Another often overlooked point is that providing inbuilt metadata empowers users of your application to audit their systems for known vulnerabilities at scale without dedicating their lifetime and efforts into it.
If your threatmodel depends on security by obscurity this section will be providing some tools and points which hopefully will make you reconsider.
For Rust there is cargo-auditable to create SBOMs and provide exact crate versions and dependencies of a binary without breaking reproducible builds.
For the frontend stack we are not aware of similar solutions, so extracting the frontend assets from the binary should be a straightforward process. Afterwards it should be possible to use tooling like npm audit or similar. There are already blog posts about the process but no simple tooling is available.
We are planning to provide such tooling or make it easier to extract assets, when compiling a Tauri app with certain features.
To use pentesting tools like Burpsuite, Zap or Caido it is necessary to intercept traffic from the webview and pass it through the testing proxy. Currently Tauri has no inbuilt method to do so but there is ongoing work to ease this process.
All of these tools allow to properly test and inspect Tauri applications without source code access and should be considered when building a Tauri application.
We are planning to further support and implement related features in the future.
WebView Hardening
In Tauri’s current threat model and boundaries we are not able to add more security constraints to the WebView itself and since it is the biggest part of our stack which is written in an memory unsafe language, we are planning to research and consider ways to further sandbox and isolate the webview processes.
Inbuilt and external sandboxing methods will be evaluated to reduce attack impact and to enforce the IPC bridge for system access. We believe that this part of our stack is the weak link but current generation WebViews are improving in their hardening and exploit resilience.
Fuzzing
To allow more efficient and simplify the process of fuzzing Tauri applications we aim to further implement our mock runtimes and other tooling to make it easier to configure and build for individual Tauri applications.
Tauri is supporting a multitude of Operating Systems and CPU architectures, usually apps have only few or no possible memory unsafe code. No pre-existing fuzzing tooling and libraries support these uncommon fuzzing use case, so we need to implement it and support existing libraries like libAFL to build Tauri fuzzing frameworks.
The goal is to make fuzzing accessible and efficient for Tauri application developers.
HTTP Headers
A header defined in the configuration gets sent along the responses to the webview. This doesn’t include IPC messages and error responses. To be more specific, every response sent via the get_response function in crates/tauri/src/protocol/tauri.rs ↗ will include those headers.
Header Names
The header names are limited to:
- Access-Control-Allow-Credentials ↗
- Access-Control-Allow-Headers ↗
- Access-Control-Allow-Methods ↗
- Access-Control-Expose-Headers ↗
- Access-Control-Max-Age ↗
- Cross-Origin-Embedder-Policy ↗
- Cross-Origin-Opener-Policy ↗
- Cross-Origin-Resource-Policy ↗
- Permissions-Policy ↗
- Service-Worker-Allowed ↗
- Timing-Allow-Origin ↗
- X-Content-Type-Options ↗
- Tauri-Custom-Header
Note
Tauri-Custom-Header is not intended for production use.
Note
The Content-Security-Policy (CSP) is not defined here.
How to Configure Headers
- with a string
- with an array of strings
- with an object/key-value, where the values must be strings
- with null
The header values are always converted to strings for the actual response. Depending on how the configuration file looks, some header values need to be composed. Those are the rules on how a composite gets created:
string: stays the same for the resulting header valuearray: items are joined by,for the resulting header valuekey-value: items are composed from: key + space + value. Items are then joined by;for the resulting header valuenull: header will be ignored
Example
src-tauri/tauri.conf.json
{
//...
"app":{
//...
"security": {
//...
"headers": {
"Cross-Origin-Opener-Policy": "same-origin",
"Cross-Origin-Embedder-Policy": "require-corp",
"Timing-Allow-Origin": [
"https://developer.mozilla.org",
"https://example.com",
],
"X-Content-Type-Options": null, // gets ignored
"Access-Control-Expose-Headers": "Tauri-Custom-Header",
"Tauri-Custom-Header": {
"key1": "'value1' 'value2'",
"key2": "'value3'"
}
},
// notice how the CSP is not defined under headers
"csp": "default-src 'self'; connect-src ipc: http://ipc.localhost",
}
}
}
Note
Tauri-Custom-Header is not intended for production use. For Tests: Remember to set Access-Control-Expose-Headers accordingly.
In this example Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy are set to allow for the use of SharedArrayBuffer ↗. Timing-Allow-Origin grants scripts loaded from the listed websites to access detailed network timing data via the Resource Timing API ↗.
For the helloworld example, this config results in:
access-control-allow-origin: http://tauri.localhost
access-control-expose-headers: Tauri-Custom-Header
content-security-policy: default-src 'self'; connect-src ipc: http://ipc.localhost; script-src 'self' 'sha256-Wjjrs6qinmnr+tOry8x8PPwI77eGpUFR3EEGZktjJNs='
content-type: text/html
cross-origin-embedder-policy: require-corp
cross-origin-opener-policy: same-origin
tauri-custom-header: key1 'value1' 'value2'; key2 'value3'
timing-allow-origin: https://developer.mozilla.org, https://example.com
Frameworks
Some development environments require extra settings, to emulate the production environment.
Note
In order to get headers to work for these frameworks, you may need to define them in both the framework’s configuration (for development mode) and the Tauri config (for build mode). This is because:
- The frameworks won’t include headers defined in their config files at build time.
- Tauri can’t inject headers into the framework’s dev server – it can only inject headers to the final build output.
JavaScript/TypeScript
For setups running the build tool Vite (those include Qwik, React, Solid, Svelte, and Vue) add the wanted headers to vite.config.ts.
vite.config.ts
import { defineConfig } from 'vite';
export default defineConfig({
// ...
server: {
// ...
headers: {
'Cross-Origin-Opener-Policy': 'same-origin',
'Cross-Origin-Embedder-Policy': 'require-corp',
'Timing-Allow-Origin': 'https://developer.mozilla.org, https://example.com',
'Access-Control-Expose-Headers': 'Tauri-Custom-Header',
'Tauri-Custom-Header': "key1 'value1' 'value2'; key2 'value3'"
},
},
})
Sometimes the vite.config.ts is integrated into the frameworks configuration file, but the setup stays the same. In case of Angular add them to angular.json.
angular.json
{
//...
"projects":{
//...
"insert-project-name":{
//...
"architect":{
//...
"serve":{
//...
"options":{
//...
"headers":{
"Cross-Origin-Opener-Policy": "same-origin",
"Cross-Origin-Embedder-Policy": "require-corp",
"Timing-Allow-Origin": "https://developer.mozilla.org, https://example.com",
"Access-Control-Expose-Headers": "Tauri-Custom-Header",
"Tauri-Custom-Header": "key1 'value1' 'value2'; key2 'value3'"
}
}
}
}
}
}
}
And in case of Nuxt to nuxt.config.ts.
nuxt.config.ts
export default defineNuxtConfig({
//...
vite: {
//...
server: {
//...
headers:{
'Cross-Origin-Opener-Policy': 'same-origin',
'Cross-Origin-Embedder-Policy': 'require-corp',
'Timing-Allow-Origin': 'https://developer.mozilla.org, https://example.com',
'Access-Control-Expose-Headers': 'Tauri-Custom-Header',
'Tauri-Custom-Header': "key1 'value1' 'value2'; key2 'value3'"
}
},
},
});
Next.js doesn’t rely on Vite, so the approach is different. Read more about it here ↗. The headers are defined in next.config.js.
next.config.js
module.exports = {
//...
async headers() {
return [
{
source: '/*',
headers: [
{
key: 'Cross-Origin-Opener-Policy',
value: 'same-origin',
},
{
key: 'Cross-Origin-Embedder-Policy',
value: 'require-corp',
},
{
key: 'Timing-Allow-Origin',
value: 'https://developer.mozilla.org, https://example.com',
},
{
key: 'Access-Control-Expose-Headers',
value: 'Tauri-Custom-Header',
},
{
key: 'Tauri-Custom-Header',
value: "key1 'value1' 'value2'; key2 'value3'",
},
],
},
]
},
}
Rust
For Yew and Leptos add the headers to Trunk.toml
Trunk.toml
#...
[serve]
#...
headers = {
"Cross-Origin-Opener-Policy" = "same-origin",
"Cross-Origin-Embedder-Policy" = "require-corp",
"Timing-Allow-Origin" = "https://developer.mozilla.org, https://example.com",
"Access-Control-Expose-Headers" = "Tauri-Custom-Header",
"Tauri-Custom-Header" = "key1 'value1' 'value2'; key2 'value3'"
}
Application Lifecycle Threats
Tauri applications are composed of many pieces at different points in time of the application lifecycle. Here we describe classical threats and what you SHOULD do about them.
All of these distinct steps are described in the following sections.
Note
The weakest link in your application lifecycle essentially defines your security. Each step can compromise the assumptions and integrity of all subsequent steps, so it is important to see the whole picture at all times.
Upstream Threats
Tauri is a direct dependency on your project, and we maintain strict authorial control of commits, reviews, pull requests, and releases. We do our best to maintain up-to-date dependencies and take action to either update or fork and fix. Other projects may not be so well maintained, and may not even have ever been audited.
Please consider their health when integrating them, otherwise, you may have adopted architectural debt without even knowing it.
Keep Your Applications Up-To-Date
When releasing your app into the wild, you are also shipping a bundle that has Tauri in it. Vulnerabilities affecting Tauri may impact the security of your application. By updating Tauri to the latest version, you ensure that critical vulnerabilities are already patched and cannot be exploited in your application. Also be sure to keep your compiler (rustc) and transpilers (nodejs) up to date, because there are often security issues that are resolved. This also is true for your development system in general.
Evaluate Your Dependencies
While NPM and Crates.io provide many convenient packages, it is your responsibility to choose trustworthy third-party libraries - or rewrite them in Rust. If you do use outdated libraries which are affected by known vulnerabilities or are unmaintained, your application security and good night’s sleep could be in jeopardy.
Use tooling like npm audit and cargo audit to automate this process, and lean on the security community’s important work.
Recent trends in the rust ecosystem like cargo-vet or cargo crev can help to further reduce likelihood of supply chain attacks. To find out on whose shoulders you stand, you can use the cargo supply chain tool.
One practice that we highly recommend, is to only ever consume critical dependencies from git using hash revisions at best or named tags as second best. This holds for Rust as well as the Node ecosystem.
Development Threats
We assume that you, the developer, care for your development environment. It is on you to make sure that your operating system, build toolchains, and associated dependencies are kept up to date and reasonable secured.
A genuine risk all of us face is what is known as “supply-chain attacks”, which are usually considered to be attacks on direct dependencies of your project. However, a growing class of attacks in the wild directly target development machines, and you would be well off to address this head-on.
Development Server
Tauri application frontends can be developed using a number of web frameworks. Each of these frameworks usually ship their own development server, which is exposing the frontend assets via an open port to the local system or network. This allows the frontend to be hot-reloaded and debugged in the WebView or Browser.
In practice this connection is often neither encrypted nor authenticated by default. This is also the case for the built-in Tauri development server and exposes your frontend and assets to the local network. Additionally, this allows attackers to push their own frontend code to development devices in the same network as the attacker. Depending on what kind of functionality is exposed this could lead to device compromise in the worst case.
You should only develop on trusted networks where you can safely expose your development device. If this is not possible you MUST ensure that your development server uses mutual authentication and encryption (e.g. mTLS) for connections with your development devices.
Note
The built-in Tauri development server does not support mutual authentication and transport encryption at the moment and should not be used on untrusted networks.
Harden Development machines
Hardening your development systems depends on various factors and on your personal threat model but some generic advice we recommend to follow:
- Never use administrative accounts for day to day tasks like coding
- Never use production secrets on development machines
- Prevent secrets to be checked into source code version control
- Use security hardware tokens or similar to reduce impact of compromised systems
- Keep your system up to date
- Keep your installed applications to a minimum
A more practical collection of procedures can be found in an awesome security hardening collection.
You can of course virtualise your development environment to keep attackers at bay, but this won’t protect you from attacks that target your project rather than just your machine.
Ensure Source Control Authentication and Authorization
If you are working like the majority of developers, using source code version control tools and service providers is an essential step during development.
To ensure that your source code can not be modified by unauthorized actors it is important to understand and correctly set up up access control for your source code version control system.
Also, consider requiring all (regular) contributors to sign their commits to prevent situations where malicious commits are attributed to non-compromised or non-maliocious contributors.
Buildtime Threats
Modern organizations use CI/CD to manufacture binary artifacts.
You need to be able to fully trust these remote (and third party owned) systems, as they have access to source code, secrets and are able to modify builds without you being able to verifiably prove that the produced binaries are the same as your local code. This means either you trust a reputable provider or host these systems on your own and controlled hardware.
At Tauri, we provide a GitHub Workflow for building on multiple platforms. If you create your own CI/CD and depend on third-party tooling, be wary of actions whose versions you have not explicitly pinned.
You should sign your binaries for the platform you are shipping to. While this can be complicated and somewhat costly to set up, end users expect that your app is verifiably from you.
If cryptographic secrets are properly stored on hardware tokens, a compromised build system won’t be able to leak involved signing keys, but could use them to sign malicious releases.
Reproducible Builds
To combat backdoor injection at build time, you need your builds to be reproducible, so that you can verify that the build assets are exactly the same when you build them locally or on another independent provider.
The first problem is that Rust is by default not fully reliably producing reproducible builds. It supports this in theory, but there are still bugs, and it recently broke on a release.
You can keep track of the current state in the rust project’s public bug tracker.
The next problem you will encounter is that many common frontend bundlers do not produce reproducible output either, so the bundled assets may also break reproducible builds.
This means that you cannot fully rely on reproducible builds by default, and sadly need to fully trust your build systems.
Distribution Threats
We have done our best to make shipping hot updates to the app as straightforward and secure as possible. However, all bets are off if you lose control of the manifest server, the build server, or the binary hosting service.
If you build your own system, consult a professional OPS architect and build it properly.
If you are looking for another trusted distribution solution for Tauri apps our partner CrabNebula has an offering: https://crabnebula.dev/cloud
Runtime Threats
We assume the webview is insecure, which has led Tauri to implement several protections regarding webview access to system APIs in the context of loading untrusted userland content.
Using the Content Security Policy will lockdown types of communication that the Webview can undertake. Furthermore, Capabilities can prevent untrusted content or scripts from accessing the API within the Webview.
We also recommend to setup an easy and secure way to report vulnerabilities similar to our process.
Permissions
Permissions are descriptions of explicit privileges of commands.
[[permission]]
identifier = "my-identifier"
description = "This describes the impact and more."
commands.allow = [
"read_file"
]
[[permission.scope.allow]]
my-scope = "$HOME/*"
[[permission.scope.deny]]
my-scope = "$HOME/secret"
It can enable commands to be accessible in the frontend of a Tauri application. It can map scopes to commands and defines which commands are enabled. Permissions can enable or deny certain commands, define scopes or combine both.
To grant or deny a permission to your app’s window or webview, you must reference the permission in a capability.
Permissions can be grouped as a set under a new identifier. This is called a permission set. This allows you to combine scope related permissions with command related permissions. It also allows to group or bundle operating specific permissions into more usable sets.
As a plugin developer you can ship multiple, pre-defined, well named permissions for all of your exposed commands.
As an application developer you can extend existing plugin permissions or define them for your own commands. They can be grouped or extended in a set to be re-used or to simplify the main configuration files later.
Permission Identifier
The permissions identifier is used to ensure that permissions can be re-used and have unique names.
Tip
With name we refer to the plugin crate name without the tauri-plugin- prefix. This is meant as namespacing to reduce likelihood of naming conflicts. When referencing permissions of the application itself it is not necessary.
<name>:defaultIndicates the permission is the default for a plugin or application<name>:<command-name>Indicates the permission is for an individual command
The plugin prefix tauri-plugin- will be automatically prepended to the identifier of plugins at compile time and is not required to be manually specified.
Identifiers are limited to ASCII lower case alphabetic characters [a-z] and the maximum length of the identifier is currently limited to 116 due to the following constants:
const IDENTIFIER_SEPARATOR: u8 = b':';
const PLUGIN_PREFIX: &str = "tauri-plugin-";
// https://doc.rust-lang.org/cargo/reference/manifest.html#the-name-field
const MAX_LEN_PREFIX: usize = 64 - PLUGIN_PREFIX.len();
const MAX_LEN_BASE: usize = 64;
const MAX_LEN_IDENTIFIER: usize = MAX_LEN_PREFIX + 1 + MAX_LEN_BASE;
Configuration Files
Simplified example of an example Tauri plugin directory structure:
tauri-plugin
├── README.md
├── src
│ └── lib.rs
├── build.rs
├── Cargo.toml
├── permissions
│ └── <identifier>.json/toml
│ └── default.json/toml
The default permission is handled in a special way, as it is automatically added to the application configuration, as long as the Tauri CLI is used to add plugins to a Tauri application.
For application developers the structure is similar:
tauri-app
├── index.html
├── package.json
├── src
├── src-tauri
│ ├── Cargo.toml
│ ├── permissions
│ └── <identifier>.toml
| ├── capabilities
│ └── <identifier>.json/.toml
│ ├── src
│ ├── tauri.conf.json
Note
As an application developer the capability files can be written in json/json5 or toml, whereas permissions only can be defined in toml.
Examples
Example permissions from the File System plugin.
plugins/fs/permissions/autogenerated/base-directories/home.toml
[[permission]]
identifier = "scope-home"
description = """This scope permits access to all files and
list content of top level directories in the `$HOME`folder."""
[[permission.scope.allow]]
path = "$HOME/*"
plugins/fs/permissions/read-files.toml
[[permission]]
identifier = "read-files"
description = """This enables all file read related
commands without any pre-configured accessible paths."""
commands.allow = [
"read_file",
"read",
"open",
"read_text_file",
"read_text_file_lines",
"read_text_file_lines_next"
]
plugins/fs/permissions/autogenerated/commands/mkdir.toml
[[permission]]
identifier = "allow-mkdir"
description = "This enables the mkdir command."
commands.allow = [
"mkdir"
]
Example implementation extending above plugin permissions in your app:
my-app/src-tauri/permissions/home-read-extends.toml
[[set]]
identifier = "allow-home-read-extended"
description = """ This allows non-recursive read access to files and to create directories
in the `$HOME` folder.
"""
permissions = [
"fs:read-files",
"fs:scope-home",
"fs:allow-mkdir"
]
Runtime Authority
The runtime authority is part of the Tauri Core. It holds all permissions, capabilities and scopes at runtime to enforce which window can access which command and passes scopes to commands.
Whenever a Tauri command is invoked from the webview the runtime authority receives the invoke request, makes sure that the origin is allowed to actually use the requested command, checks if the origin is part of capabilities and if scopes are defined for the command and applicable then they are injected into the invoke request, which is then passed to the proper Tauri command.
If the origin is not allowed to call the command, the runtime authority will deny the request and the Tauri command is never invoked.
Command Scopes
A scope is a granular way to define (dis)allowed behavior of a Tauri command.
Scopes are categorized into allow or deny scopes, where deny always supersedes the allow scope.
The scope type needs be of any serde serializable type. These types are plugin-specific in general. For scoped commands implemented in a Tauri application the scope type needs to be defined in the application and then enforced in the command implementation.
For instance, the Fs plugin allows you to use scopes to allow or deny certain directories and files and the http plugin uses scopes to filter URLs that are allowed to be reached.
The scope is passed to the command and handling or properly enforcing is implemented by the command itself.
Caution
Command developers need to ensure that there are no scope bypasses possible. The scope validation implementation should be audited to ensure correctness.
Examples
These examples are taken from the Fs plugin permissions:
The scope type in this plugin for all commands is a string, which contains a glob compatible path.
plugins/fs/permissions/autogenerated/base-directories/applocaldata.toml
[[permission]]
identifier = "scope-applocaldata-recursive"
description = '''
This scope recursive access to the complete `$APPLOCALDATA` folder,
including sub directories and files.
'''
[[permission.scope.allow]]
path = "$APPLOCALDATA/**"
plugins/fs/permissions/deny-webview-data.toml
[[permission]]
identifier = "deny-webview-data-linux"
description = '''
This denies read access to the
`$APPLOCALDATA` folder on linux as the webview data and
configuration values are stored here.
Allowing access can lead to sensitive information disclosure and
should be well considered.
'''
platforms = ["linux"]
[[permission.scope.deny]]
path = "$APPLOCALDATA/**"
[[permission]]
identifier = "deny-webview-data-windows"
description = '''
This denies read access to the
`$APPLOCALDATA/EBWebView` folder on windows as the webview data and
configuration values are stored here.
Allowing access can lead to sensitive information disclosure and
should be well considered.
'''
platforms = ["windows"]
[[permission.scope.deny]]
path = "$APPLOCALDATA/EBWebView/**"
The above scopes can be used to allow access to the APPLOCALDATA folder, while preventing access to the EBWebView subfolder on windows, which contains sensitive webview data.
These can merged into a set, which reduces duplicate configuration and makes it more understandable for anyone looking into the application configuration.
First the deny scopes are merged into deny-default:
plugins/fs/permissions/deny-default.toml
[[set]]
identifier = "deny-default"
description = '''
This denies access to dangerous Tauri relevant files and
folders by default.
'''
permissions = ["deny-webview-data-linux", "deny-webview-data-windows"]
Afterwards deny and allow scopes are merged:
[[set]]
identifier = "scope-applocaldata-reasonable"
description = '''
This scope set allows access to the `APPLOCALDATA` folder and
subfolders except for linux,
while it denies access to dangerous Tauri relevant files and
folders by default on windows.
'''
permissions = ["scope-applocaldata-recursive", "deny-default"]
These scopes can be either used for all commands, by extending the global scope of the plugin, or for only selected commands when they are used in combination with a enabled command inside a permission.
Reasonable read only file access to files in the APPLOCALDATA could look like this:
[[set]]
identifier = "read-files-applocaldata"
description = '''
This set allows file read access to the `APPLOCALDATA` folder and
subfolders except for linux,
while it denies access to dangerous Tauri relevant files and
folders by default on windows.'''
permissions = ["scope-applocaldata-reasonable", "allow-read-file"]
These examples only highlight the scope functionality itself. Each plugin or application developer needs to consider reasonable combinations of scope depending on their use cases.
create-tauri-app Version 3 Released
A new major version of create-tauri-app has been released. This version adds support for the alpha version of Tauri 2.0, the ability to initialize iOS and Android projects and removes some less commonly used templates to make the project more maintainable.
Tauri 2.0 Alpha & Mobile Support
The first alpha version of Tauri 2.0 was published almost 3 months ago which brought initial mobile support for Android and iOS. Previously there wasn’t an easy way to create a new project to test either the changes in the alpha version nor the mobile support. Well, that ends now!
Starting with version 3 of create-tauri-app, you can now pass --beta flag and it will bootstrap an app that uses tauri@2.0.0-beta. When adding the --beta flag it will automatically prompt you if you’d like to add mobile support. You can also use the --mobile flag to automatically make it mobile compatible.
To get started:
# pnpm
pnpm create tauri-app --alpha
# yarn
yarn create tauri-app --alpha
# npm
npm create tauri-app -- --alpha
# Cargo
cargo install create-tauri-app --locked
cargo create-tauri-app --alpha
# Bash
sh <(curl https://create.tauri.app/sh) --alpha
# Powershell
$env:CTA_ARGS="--alpha";iwr -useb https://create.tauri.app/ps | iex
Prompt Improvements
With version 2 of create-tauri-app we also focused on improving the flow and experience of the prompted questions.
Previously the second prompt would ask “Choose your package manager”. This was a bit vague and could leave some with unanswered questions:
- What is
cargo? - Is it a new Node.js package manager?
- Why choose it over
pnpmoryarn?
This would be even more vague if we decided to add a new frontend language (such as a webassembly Golang web application). We added a prompt asking to choose the package manager to ask which language would you prefer. It looks something like this:
? Choose which language to use for your frontend ›
Rust
❯ TypeScript / JavaScript (pnpm, yarn, npm)
After choosing the frontend language create-tauri-app will then prompt for package manager to use if the language has multiple (such as Node.js with npm, yarn, and pnpm).
Another prompt that we felt problematic was the template selection prompt. It contained a lot of templates to choose from and was only growing with time:
✔ Choose your package manager · pnpm
? Choose your UI template ›
vanilla
vanilla-ts
vue
❯ vue-ts
svelte
svelte-ts
react
react-ts
solid
solid-ts
next
next-ts
preact
preact-ts
angular
clojurescript
svelte-kit
svelte-kit-ts
We decided to split this up into 2 prompts. The first will ask which UI template to use:
✔ Choose your package manager · pnpm
? Choose your UI template ›
Vanilla
❯ Vue
Svelte
React
Solid
Angular
Next
SvelteKit
ClojureScript
Preact
And then the second will then ask any additional choices that are specific to that template (such as choosing between TypeScript or JavaScript for Vue):
✔ Choose your package manager · pnpm
✔ Choose your UI template · Vue - (https://vuejs.org)
? Choose your UI flavor ›
❯ TypeScript
JavaScript
Even with these refinements the list of templates was still quite large and would only grow over time. The next thing to look at was the list of templates themselves.
Removing Templates
When create-tauri-app version 2 was launched it quickly received PRs to add additional templates beyond what it originally launched with. While it was exciting to receive so much support from the community, it did bring up a couple of new challenges:
- It made it almost impossible to fit them in a single prompt
- Maintaining all the templates was becoming more difficult
It was a hard balance between showing how flexible Tauri is but also making sure that the project was maintainable and had the DX that we wanted.
We decided to focus on the most popular frontend frameworks and used guidance from community surveys like The State of JS and our own Tauri community feedback. With this we removed the next, next-ts, preact, preact-ts, clojurescript, svelte-kit and svelte-kit-ts templates and also closed PRs which aimed to add more templates.
Community-Maintained Templates & Previous Versions
We want to make sure that we offer a place for the Tauri community to provide their own templates for the frameworks they love. The templates section of awesome-tauri is just the place for that. We invite the community to submit a PR to the awesome-tauri repo with their templates so that they can be shared with the Tauri community. We’ll also be creating a section on the Tauri website to highlight and showcase these community templates.
If you’d still like to use the previous templates from version 2 of create-tauri-app they are still published to npm and crates.io. Here’s how you can use a previous version:
# pnpm
pnpm create tauri-app@2
# yarn
yarn create tauri-app@2
# npm
npm create tauri-app@2
# Cargo
cargo install create-tauri-app --version 2.8.0 --locked
cargo create-tauri-app
# Bash
sh <(curl https://create.tauri.app/v/2.8.0/sh)
# Powershell
iwr -useb https://create.tauri.app/v/2.8.0/ps | iex
However, as time goes, these templates will become out of date as Tauri and the frontend frameworks move forward. We’d recommend you look at the community templates in the awesome-tauri repo and welcome submissions if something is missing.
We hope that these changes make it easier for the community to try out the alpha and beta versions of Tauri 2.0 and also make the process to create a new Tauri app easier for everyone! We’d love to hear your feedback and invite you to join the conversation on the GitHub Discussion for this post.
Rust Security Advisory CVE-2024-24576
The Rust Security Response WG announced CVE-2024-24576, which affects the Rust Standard Library on Windows.
TL;DR: Upgrade your Rust version to
1.77.2.
How Does it Affect Tauri as a Library?
Some Tauri organization repositories use batch files (cmd.exe under the hood) for developer environment tooling such as build scripts. No reviewed repositories use batch files for runtime code.
We don’t see additional risks for the Tauri project based on this CVE.
Nevertheless, we will update our CI systems to use the latest Rust version.
Is My Tauri App Affected?
In general you are possibly affected if you fulfil all of the below criteria:
- You ship your app on Windows
- Your project enables the Tauri v1
shellfeature with"execute": trueor the v2shell-pluginwithallow-executepermission - You allow arguments in the
scopeelement of theshellfeature - You pass untrusted input to
cmd.exeor.bat/.cmdfiles and improperly validate the scope (🚩)
If any of these criteria are not fulfilled in your application you are likely NOT affected.
If you implement custom commands or logic written in your application that directly exposes the Rust Command with arguments provided at runtime, you may be affected. While not Tauri specific, this pattern could affect any Rust project.
Conclusion
Please upgrade your Rust version to 1.77.2 as soon as possible and distribute updates to your users.
This investigation and writeup was performed in cooperation with our partner CrabNebula ❤️.
Read more about this security advisory here. This affects many programming languages, this specific CVE is just the one filed for Rust.
Strengthening Tauri: Our Partnership with CrabNebula
As an open-source project, Tauri’s primary mission has always been to provide a secure, efficient framework for multi-platform application development. Understanding the concerns and needs of our community, we are excited to share insights into our partnership with CrabNebula and how it bolsters the stability and future of Tauri.
CrabNebula’s Contribution to Stability and Security
CrabNebula’s role in Tauri’s journey over the past year has been pivotal. By dedicating full-time engineers to work explicitly on Tauri’s development and maintenance, they are helping us enhance the framework’s stability and security. They are literally being paid to resolve bugs and issues, pushing forward on the 2.0 release, and offering their support in the many Discord discussions.
Specifically, we would like to call out some folks from CrabNebula for helping drive the community and the code forward: Daniel, Lucas, Elizabeth, Yu-Wei, Tillmann, Amr, Chip, Fabian-Lars, Alve, Atila, Eleftheria, Tejas, Lorenzo, Robin, David, Jason, and Te-Kai.
Their efforts in conducting thorough security audits of minor releases are particularly crucial. These audits not only help us identify and fix vulnerabilities but also reinforce our commitment to delivering a secure framework for all users. Collaborative features developed with Impierce and Kino AI under this partnership further expand Tauri’s capabilities, which will help it to remain cutting-edge and reliable.
A Partnership Model Focused on Open Source Values
Our collaboration with CrabNebula is grounded in open-source principles. It’s designed not just for mutual benefit but to serve as a sustainable model for future collaborations. We understand the importance of maintaining the integrity and independence of Tauri as an open-source project. This partnership respects these values, ensuring that Tauri continues to be driven by community needs and open-source innovation.
Long-Term Impact on the Tauri Ecosystem
The partnership is more than just a short-term alliance; it’s a strategic move to secure the long-term future of Tauri. By bringing additional resources and diverse perspectives, we’re enhancing the framework’s robustness. Importantly, involvement of companies using Tauri, facilitated by this partnership, gets cycled directly into the development process. This feedback loop is vital for addressing real-world usage challenges, because it is important to all of us that Tauri remains relevant and continues to evolve according to the needs of its users.
Creating Channels for Community Engagement
In line with our commitment to community engagement, we will be launching a #crabnebula channel on Tauri’s Discord. This will be a dedicated space for direct communication, collaboration, and feedback. We want to make sure that our community’s voice is heard and integrated into the ongoing development of Tauri.
Call to Action
To our developers, contributors, users, and donors - we invite you to engage with us on this journey. Your input is invaluable as we continue to develop Tauri in partnership with CrabNebula. Together, we are not just building a framework; we are seeking ways to enhance its longevity and relevance in the ever-changing world of technology.
If you like, go over to the CrabNebula blog and read their perspective on this partnership.
- Discord Tauri
- X Tauri
- Mastadon Tauri
- GitHub Tauri
- Website Tauri
- X CrabNebula
- Mastadon CrabNebula
- GitHub CrabNebula
- Website Crabnebula
Roadmap to Tauri 2.0
Tauri 1.0 was released in June 2022 and introduced an app toolkit for developers to build apps using HTML, CSS, and JavaScript with the security and performance of Rust. Tauri has been pivotal in redefining and asking the question: “What is an app?”
Version 1.0 launched with support for Linux, macOS, and Windows and has been updated with new features, DX improvements, and bug fixes to bring us to Tauri 1.4 that is available now.
But there’s one question the Tauri Working Group gets asked time and time again. We affectionately refer to it as “Mobile when?!?” and today we’d like to outline the path ahead of us to get to Tauri 2.0 and to answer that question.
What is Tauri 2.0?
In essence, the 2.0 release of Tauri is The Mobile Update. But 2.0 is so much more than just mobile. Here are a few of the features that will be included:
- Powerful Plugins: Many of the Tauri APIs have been shifted to use the Tauri plugin system. This allows us to make Tauri code more modular, more maintainable, but also enables us to make the plugin system more powerful for developers to build their own plugins.
- Swift and Kotlin Bindings for Plugins: Now you can write platform-specific code in Swift and Kotlin. Tauri has offered a bridge between Rust and JavaScript code since version 1.0. With Tauri 2.0, plugin developers will be able to write code in Swift and Kotlin to integrate more closely with the systems they’re developing for.
- Support for iOS and Android: You’ll be able to build Tauri apps and run them on iOS and Android.
We’ve already seen developers doing amazing things with the prerelease version of Tauri 2.0 and we’re excited to move forward to a stable version to get it in the hands of everyone.
Path to Tauri 2.0 Stable
Right now, we are in the 2.0 alpha phase. Here are the 3 key milestones to get us to Tauri 2.0 stable:
Below are the steps within each of those milestones that the Tauri Working Group are driving towards.
Beta
To enter a beta phase Tauri 2.0 must be feature-complete and working with no known major issues. This means that the Tauri Working Group are satisfied with the public Tauri APIs and don’t anticipate any breaking changes (although they are possible as we receive community feedback).
Once we’ve entered beta then we will lock down the code base and move onto an auditing phase. No new features will be targeted for Tauri 2.0 after this point.
Security is very important to Tauri. We work with external auditors to review Tauri code so that it can be as secure as possible for Tauri developers and their users. A similar approach was taken with Tauri 1.0 in collaboration with Radically Open Security (Tauri 1.0 Security Audit Report).
More details on the security audit for 2.0 are to come in the future.
Release Candidate
Once all of the audit findings are resolved then we will move on to the release candidate phase. This is where we’ll ask the Tauri community to give it a test drive, see if there are any bugs, and to provide feedback in preparation for the stable release.
The RC phase will be time-locked so that early adopters can help us discover pain points and low-hanging fruit that can be resolved quickly. This will also include a documentation sprint in order to align what we know with what we show. More details on this will be shared as we get get closer to the release candidate phase.
Stable
Tauri 2.0 will be released and generally available for everyone to build amazing things with. We will also continue fixing bugs and releasing updates in line with our current approach of publishing patches and minor updates.
Where We Are
There are a lot of moving parts in moving towards a stable release. The two main parts are the findings and fixes from the security audit alongside the feedback and adjustments from the community. These two pieces are incredibly important and we want to be sure we can prioritize those without sacrificing the security and quality of Tauri.
Because of those priorities we don’t yet have hard timelines for a Tauri 2.0 stable release. We have internal targets that we’re aiming for to keep us on track, but we want to be sure that we’re flexible to accommodate feedback.
What we can share right now is that we’re roughly targeting the stable release of Tauri 2.0 in early 2024. We’re driving sharply ahead to enter the beta phase as soon as possible.
As we make progress towards Tauri 2.0 we’ll be sure to share updates to the community. The primary way to keep up to date is to watch for the Tauri releases as they move through the beta, release candidate, and lastly stable phases. You can also keep an eye on Twitter, Mastodon, and Discord.
Getting Involved
While we’re working towards Tauri 2.0 stable there are a lot of ways for the community to get involved. The more involvement and feedback we have, the better Tauri 2.0 will be for everyone. Here are just a few ways to get involved:
- Test prerelease versions of Tauri and give feedback via Discord and GitHub issues.
- Contribute to documentation and translations on https://v2.tauri.app.
- Help in the Tauri community by supporting others in Discord and GitHub issues and giving feedback for major issues that arise.
- Begin planning content around Tauri 2.0 (although we recommend waiting until at least 2.0 beta). Reach out to the Tauri Working Group on Discord if you would like to collaborate on content ideas such as videos, blogs, courses, or anything else.
We hope this provides a bit of transparency about where we’re at, where we’re headed, and what you can do to help us get there. Give us your feedback by joining us on Discord and joining the GitHub Discussion for this post. Happy building!
Tauri 1.0 Release
After 9 months of betas and 4 months of release candidates, Tauri version 1.0 is now available!
What is Tauri?
Tauri is an app construction toolkit that lets you build software for all major desktop operating systems using web technologies. The core libraries have been written for you in Rust and the user interface can be written using virtually any frontend framework. It includes an optional and tree-shakeable JavaScript API for comfortable low-level system access, a desktop binary bundler with code signing and artifact verification, a secure updater to keep your users on the latest version, an extensive plugin system, and support for OS-level integrations such as notifications and app trays.
Tauri is as simple to use as it is easy to extend. For those new to the Rust programming language, Tauri provides a comfortable learning environment that will grow with you. Once you have installed Rust, creating your first app is a mere running of create-tauri-app. But you don’t have to use Node.js at all, if you would prefer to remain in the safety and comfort of 100% Rust.
See our Quick Start guides to start building with Tauri.
Tauri Philosophy
We built Tauri for the security-focused, privacy-respecting, and environmentally-conscious software engineering community.
Security
The entire project has been horizontally and vertically audited by an independent third party, and we maintain a very strict approach to updating the core. We want you to be confident that major versions are as safe to use as they are ergonomic.
Hoodie by jprovost
Privacy
Tauri allows you to build “local first” applications without a webserver, so your users don’t have to share their data with big tech. Using local databases and rust based cryptography have never been easier.
Johannes Schickling at Worker Conf 2022 (photo by{' '} @TejasKumar via Twitter)
Environment
The apps you make are lean and performant, which reduces electricity, storage space, and general natural resource consumption. Every byte saved is a leaf on a tree that gets to grow.
To illustrate this, we compiled some numbers on the ecological impact of your app’s size. As you can see, even small increases in size have a hefty impact on the environment!
| App Size | Unit Time (100Mb/s) | Downloads | Transit | Total Time (100Mb/s) | Electricity Use (kWh) | CO2 Produced (kg) | Trees Needed 🌳 |
|---|---|---|---|---|---|---|---|
| 3 MB | 240 milliseconds | 1,000 | 3 GB | 24 minutes | 0.3 | 0.18 | 1 |
| 3 MB | 240 milliseconds | 100,000 | 300 GB | 1.7 days | 30 | 18 | 1 |
| 3 MB | 240 milliseconds | 10,000,000 | 30 TB | 167 days | 3,000 | 1,800 | 11 |
| 200 MB | 16 seconds | 1,000 | 200 GB | 4.45 hours | 20 | 12 | 1 |
| 200 MB | 16 seconds | 100,000 | 20 TB | 18.5 days | 2,000 | 1,200 | 7 |
| 200 MB | 16 seconds | 10,000,000 | 2 PB | 5 years | 200,000 | 120,000 | 720 |
| 600 MB | 48 seconds | 1,000 | 0.6 TB | 13 hours | 60 | 36 | 1 |
| 600 MB | 48 seconds | 100,000 | 60 TB | 54.2 days | 6,000 | 3,600 | 22 |
| 600 MB | 48 seconds | 10,000,000 | 6 PB | 14.8 years | 600,000 | 360,000 | 2,160 |
The transmission of 1 GB of information takes an estimated 0.1kWh, which is equal to 0.06 kilograms of CO2. (https://www.emergeinteractive.com/insights/detail/does-irresponsible-web-development-contribute-to-global-warming/)
Although the carbon absorption capacity can vary, it is generally considered that a tree can store about 167 kg of CO2 per year, or 1 ton of CO2 per year for 6 mature trees (https://climate.selectra.com/en/news/co2-tree)
Community
We know that open source software is a means of fostering equality and collaboration, which is why we placed the ownership of the code at the Commons Conservancy. You can rest assured knowing that the code base will never be rug-pulled or locked behind open-core pay-to-play feature gates. We believe in open collaboration and safe spaces for all. We have an open working group, accessible to any competent contributors. And we love you all. ❤️
Accolades
Here are some of the things people are saying about Tauri:
“Spacedrive had to feel native across all platforms, all while being lightweight, instant to launch and extremely fast to use. This just wasn’t possible with a web-based UI — until now, thanks to Tauri.” - Jamie Pine, Spacedrive Founder
“Tauri has the potential to unlock a new generation of desktop software that feels native to users but is as easy to build as web apps.”
- Johannes Schickling, Prisma Founder
“Tauri stands to reduce the disastrously negative environmental costs of bloated and memory-hogging applications on the internet by orders of magnitude. Any rough approximation of monetary value that could result in, would easily reach hundreds of billions in cost savings for our modern era of grossly underutilized local compute and storage resources.”
- Joseph Jacks, OSS Capital Founder / GP
“With its security-focused design and low memory footprint, Tauri is the electron alternative we’ve been waiting for. Tauri has allowed us to build a more secure, more performant desktop app while using the same web technologies, which we love. Thanks to the team for their amazing work! P.S.: Can’t wait for mobile support!”
- Martin Kleinschrodt, Padloc Founder
Feedback
You can visit our code base, file a bug-report, request a feature, or join the discussion on GitHub. There’s lots of things that people make, and visiting the awesome-tauri repo on GitHub is a great place to discover and share. If you need support or just want to hang out, you can join our Discord server.
Tauri is one of the top 200 projects on GitHub in all programming languages.
People love to discuss what is great and terrible about Tauri on orange websites:
Tauri entered at the top of the charts for the 2021 edition of State of JS:
Engineers at big companies seem to be eying up Tauri for future projects.
What’s Next?
Fresh off the heels of the 1.0 release, the team is already setting our sights on the next steps for Tauri. While we continuously work on improving our documentation, we’re also working on:
- Mobile support for both iOS and Android
- Alternative renderers
- IPC enhancements to enable improved debugging
- Runtime plugins
- Support for additional bindings in other languages
We’re also inspired by the community to see which features are being used and what new features will enable them to develop even more amazing applications. Your feedback is the most important thing to Tauri’s future innovation!
Thank You
A special thanks to all our contributors who volunteered their precious time to make Tauri awesome and all our sponsors whose generous donations made Tauri possible (and financed a large portion of our audit!)!
The support of industry giants has been really helpful keeping the lights on. Here’s an alphabetical list:
- Cloudflare for sponsoring unlimited workers for the OSS updater service (coming soon)
- DigitalOcean for comping the droplets that run our bots and search
- GitHub for the extra minutes of CI
- Netlify for our website hosting
- NLNET who has financially supported Tauri development via grants
- PACKT who will be publishing our books
Here are a few notable contributors we’d like to thank explicitly:
| GitHub Profile | Contribution | Repository |
|---|---|---|
| @malyn | Fixed http stream | wry |
| @wravery | windows-rs support, webview2-rs | tao, wry |
| @liushuyu | Added headers feature to webkit2gtk | wry |
| @emirror-de | System tray support | tao |
| @lorenzolewis | tauri.app updates | tauri-docs |
| @probablykasper | Support for more accelerators, restructured documentation | tao, tauri-docs |
| @grbd | Added an example to use tauri as a C++ DLL | tauri |
| @youngsing | Added macOS vibrancy | tauri-plugin-vibrancy |
| @lemarier | Updater, menus, system tray, iOS, clipboard api, bytes-stream & ++ | wry, tao, tauri |
| @JonasKruckenberg | Tauri plugin upgrades and documentation overhaul | tauri-plugin-*, tauri-docs |
| @ImmaZoni | Code signing guides for macOS and Windows | tauri-docs |
| @chippers | Isolation pattern, shell scope, compile-time code generation and several other security features | tauri |
| @fabianlars | Community support, AppImage fixes, code review | all repos, mainly tauri, tauri-docs |
| @amrbashir | TAO and WRY features and fixes, overall OS guru | tao, wry |
| @wusyong | TAO and WRY founder and researcher | tao, wry |
| @nklayman | custom protocol | tauri |
We’d like to wrap up by highlighting comments from just a small handful of core Tauri contributors:
What feature are you most excited about?
The customizations we offer for the window but that’s because it is what I mostly worked on. I am also excited about how Tauri will change the mindset of some people and help them build secure apps by default.
What is your proudest moment/contribution with Tauri?
Probably when I removed about 20 lines of code in favor of only 3 lines. I wrote both and that’s why it felt special, because it was an indicator of how much I’ve grown as a developer.
What feature are you most excited about?
Not needing to use
--lockedwhen installing the CLI.
What is your proudest moment/contribution with Tauri?
Building the Isolation Pattern
What feature are you most excited about?
File drag & drop.
What is your proudest moment/contribution with Tauri?
Quality/stability: Tracking down and fixing a segmentation fault: https://github.com/h4llow3En/mac-notification-sys/pull/40
What feature are you most excited about?
Is “All of them” a valid answer?
What is your proudest moment/contribution with Tauri?
Hmm, probably when I was asked to join the team. Fixing AppImages again and again and again is a close second…
What feature are you most excited about?
The auto-updater is pretty great but plugins are very dear to me and definitely the most promising feature of Tauri!
What is your proudest moment/contribution with Tauri?
Moderating the tauri-awesome repo. Seeing so many strangers build cool things with and for the work you’ve been doing. That’s a really great feeling.
What inspired you to join Tauri?
I was making a few Tauri apps, and just found some features/improvements I wanted to go for.
What feature are you most excited about?
It may sound silly but I love customizing stuff, so the possibility to make almost anything with our windows appearance is neat.
What is your proudest moment/contribution with Tauri?
Creating the foundations of Tauri docs as we know them today and trying to provide clean and easy to understand docs.
What feature are you most excited about?
Pretty much everything, getting Tauri out of a proof of concept to something stable is a huge milestone.
What is your proudest moment/contribution with Tauri?
TAO and all under laying features (menus, trays, etc..), benchmarks and the proof of concept for iOS.
What feature are you most excited about?
Overall resource efficiency. We’ve all been where we have a handful of “native” web apps running on our machine and it grinds to a halt. I’m ready for those small bundle sizes!
What is your proudest moment/contribution with Tauri?
The overall tauri.app website. It was in a really good place when I joined, but I knew I could help boost it up to the next level. Even things like picking a title for a sidebar can take a long time with all the discussions, but at the end of the day we all have the best output from putting our heads together.
What feature are you most excited about?
Plugins!
What are you most excited about now that the launch is through?
MOBILE and the upcoming egui integration launch
What feature are you most excited about?
Auto-updater. It’s really hard to get something that complex right and Tauri has done a fantastic job.
What is your proudest moment/contribution with Tauri?
Getting the custom protocol based asset loader to work, especially on Windows.
secdude
What feature are you most excited about?
Conditional compilation of features by default.
What is your proudest moment/contribution with Tauri?
🤷 v1 I guess
What feature are you most excited about?
Auto-updater I think. A built-in OTA feature feels pretty handy.
What is your proudest moment/contribution with Tauri?
Published wry crate and particular in this commit: https://github.com/tauri-apps/wry/commit/722e1212a4795f5f81638667cbd31bc53a5d27ed
Announcing Tauri 1.1.0
After 113 pull requests and nearly two months of work, the Tauri team is pleased to announce the 1.1.0 release. The changes were internally audited and no security issues were found.
You can update the dependencies with:
-
npm
npm install @tauri-apps/cli@latest @tauri-apps/api@latest -
yarn
yarn upgrade @tauri-apps/cli @tauri-apps/api --latest -
pnpm
pnpm update @tauri-apps/cli @tauri-apps/api --latest -
cargo
cargo update
What’s New in 1.1.0
Security patch
This release includes a patch for a security vulnerability reported by @martin-ocasek. The readDir function was able to return entries outside the configured scope when a symlink is found. The patch is also available in Tauri 1.0.6. See the issue on GitHub for more details.
Icon Generation
We have been recommending to use the tauricon project to generate icons for your Tauri application using a single source PNG. Several issues have been reported, and we decided to “Rewrite It In Rust” to enhance its stability. This allowed us to move this functionality to the main Tauri CLI, so now you can use the tauri icon command.
cargo-binstall Support for Tauri CLI
The Tauri CLI can now be installed using cargo-binstall, a mechanism to download and install pre-built Rust binaries. The binaries are available for the main targets and can be installed with:
$ cargo install cargo-binstall
$ cargo binstall tauri-cli
$ cargo tauri dev # run any Tauri command!
Create System Trays at Runtime
The system tray APIs (previously only available in tauri::Builder::system_tray) can now be used at runtime with tauri::SystemTray giving you control over its lifetime and even create multiple trays.
Here’s a quick example on how to use it:
use tauri::{Builder, CustomMenuItem, SystemTray, SystemTrayEvent, SystemTrayMenu};
Builder::default()
.setup(|app| {
let handle = app.handle();
SystemTray::new()
.with_id("main")
.with_menu(
SystemTrayMenu::new().add_item(CustomMenuItem::new("quit", "Quit"))
)
.on_event(move |event| {
let tray_handle = handle.tray_handle_by_id("main").unwrap();
if let SystemTrayEvent::MenuItemClick { id, .. } = event {
if id == "quit" {
tray_handle.destroy().unwrap();
}
}
})
.build(&handle)
.expect("unable to create tray");
});
TOML Configuration Support
In the 1.0 releases Tauri supports the JSON configuration format by default, and JSON5 when the config-json5 Cargo feature is enabled, meaning the following configurations are valid:
tauri.conf.json
{
"build": {
"devPath": "http://localhost:8000",
"distDir": "../dist"
}
}
{
build: {
// devServer URL (comments are allowed!)
devPath: 'http://localhost:8000',
distDir: '../dist',
},
}
The 1.1.0 release includes TOML support behind the config-toml Cargo feature. Now you can define your Tauri configuration in a Tauri.toml file:
Tauri.toml
[build]
dev-path = "http://localhost:8000"
dist-dir = "../dist"
Dependency Updates
This release includes some dependency updates that must be handled in your app if you implement platform-specific functionalities using these crates. The most important updates are:
windowsupdated to 0.39.0webview2-comupdated to 0.19.1raw-window-handleupdated to 0.5.0
Make sure you also update plugins such as window-vibrancy and window-shadows to latest.
Contributors to 1.1.0
The Tauri team thanks the following contributors for the 1.1.0 release:
- Berrysoft
- keraf
- jsoref
- A-kirami
- olivierlemasle
- mateo-gallardo
- rockerBOO
- Flecart
- brian14708
- koriwi
- paul-soporan
- shniubobo
- horochx
- RubenKelevra
- LIMPIX31
- AxlLind
Other Changes
There are a lot of smaller changes and bug fixes in this release. You can see a summary of the release notes in the following sections. The complete changelog can be found on the releases page.
New
tauri iconcommandexistsAPI in thefsmodule- Option to disable the dev watcher with
tauri dev --no-watch - Automatically use any
.taurignorefile as ignore rules for dev watcher and app path finder - Add support to cargo-binstall for the Tauri CLI
- TOML configuration format (Tauri.toml)
- Theme APIs on Linux
- Create system trays at runtime
beforeBundleCommandconfigurationbeforeDevCommandandbeforeBuildCommandnow has an option to configure the current working directoryapi::Command::encodingmethod to set the stdout/stderr encoding- Added
native-tls-vendoredandreqwest-native-tls-vendoredCargo features to compile and statically link to a vendored copy of OpenSSL on Linux - Implement
raw_window_handle::HasRawDisplayHandleforAppandAppHandle
Fixes
- CLI parser ignoring inner subcommands.
- Updater breaking the app icon in Finder.
- Fix root of codegen output when using the
CodegenContextAPI.
Security
- Fix
fs.readDirrecursive option reading symlinked directories that are not allowed by the scope
Improvements
- Validate updater signature against configured public key
- Return an error if a sidecar is configured with the same file name as the application.
- Keep the created windows in a RefCell instead of a Mutex, avoiding deadlocks
- Prompt for
beforeDevCommandandbeforeBuildCommandintauri init. - Use
cargo metadatato detect the workspace root and target directory. - Allow configuring the
before_dev_commandto force the CLI to wait for the command to finish before proceeding. - Avoid re-downloading AppImage build tools on every build.
- Retain command line arguments in
api::process::restart - Enhance the dialog style on Windows via the manifest dependency
Microsoft.Windows.Common-Controls v6.0.0.0. - Rerun codegen if assets or icons change
- Only rewrite temporary icon files when the content change, avoid needless rebuilds.
Announcing Tauri 1.2.0
The Tauri team is happy to announce the 1.2.0 release. It includes a security fix, so we encourage new and existing users to update to one of the fixed versions. Other changes were internally audited and no security issues were found.
Make sure to update both NPM and Cargo dependencies to the 1.2.0 release. You can update the dependencies with:
-
npm
npm install @tauri-apps/cli@latest @tauri-apps/api@latest -
yarn
yarn upgrade @tauri-apps/cli @tauri-apps/api --latest -
pnpm
pnpm update @tauri-apps/cli @tauri-apps/api --latest -
cargo
cargo update
What’s in 1.2.0
Security patch
This release includes a patch for a security vulnerability reported by MessyComposer. Due to incorrect escaping of special characters in paths selected via the file dialog and drag and drop functionality, it was possible to partially bypass the fs scope definition. It was not possible to traverse into arbitrary paths, as the issue was limited to neighboring files and sub folders of already allowed paths. A successful bypass requires the user to select a pre-existing malicious file or directory during the file picker dialog and an adversary controlled logic to access these files. This means the issue by itself can not be abused and requires further intentional or unintentional privileges. The patch is also available in 1.0.7 and 1.1.2. See the advisory for more details.
Rust version update
This release includes a minimum supported Rust version bump. Tauri now requires at least Rust 1.59 to compile. This was necessary due to several dependency updates that demanded this change.
Custom protocol headers on Linux
The Linux webview binding has been updated and it now has support to custom protocol headers when running on webkit2gtk version 2.36 or above. This fixes CORS issues on production when manually fetching a build asset.
Enhanced titlebar configuration on macOS
We finally merged one of the most awaited pull requests, introducing the titlebar style configuration. Your application can now define a transparent or overlay titlebar, hide the window title text and define the window to accept first mouse events so it can be focused immediately after receiving a click event to be dragged.
Window with overlay titlebar style
Window with transparent titlebar style (uses the window background color)
Other changes
There are a lot of smaller changes and bug fixes in this release. You can see a summary of the release notes in the following sections. The complete changelog can be found on the releases page.
New
- Allow configuring the user agent when creating a window (#5317)
- Reimplemented the option to create unfocused windows (#5338)
- Added the acceptFirstMouse window option (macOS) (#5374)
- Added the tabbingIdentifier window option (macOS) (#5399)
- Enhanced the app-specific directory APIs (#5272)
- Added show and hide methods on the app module (macOS) (#3689)
- Expose set_title for MacOS tray (#5182)
- hotreload support for frontend static files (#5256)
- Add a configuration option for the bundle publisher (#5283)
Enhancements
- Validate the package name (#5262)
- Drop the WebContext on WebView drop (#5240)
- Set the correct mimetype when streaming files through asset: protocol (#5210)
Fixes
- Fix HTML template tags in custom protocol (#5247)
- Fix scope check when reading resource files on macOS (#5218)
- Fix incorrect return type on fs/exists (#5252)
- Initialize Monitor instances with the correct classes for position and size fields instead of plain object (#5313)
- Fix dialog.save return type (#5373)
- Use correct code ja-JP for japanese instead of jp-JP (#5346)
- Clear environment variables on the WiX light.exe and candle.exe commands to avoid “Windows Installer Service could not be accessed” error. Variables prefixed with TAURI are propagated. (#4819)
- Fix regression in SystemTray::with_menu_on_left_click (#5235)
- Fix regression introduce in tauri@1.1 which prevented removing tray icon when the app exits on Windows (#5245)
- Fix access to the WebviewWindow.getByLabel function in a tauri://window-created event listener (#5458)
- Fix a deadlock when modifying the menu in the on_menu_event closure. (#5257)
- Fixes
__TAURI_PATTERN__object freeze (#5307)
Announcing Tauri 1.3.0
The Tauri team is excited to announce the 1.3 release. This version includes security improvements, new features and important bug fixes.
Upgrading
Make sure to update both NPM and Cargo dependencies to the 1.3.0 release. You can update the dependencies with:
-
npm
npm install @tauri-apps/cli@latest @tauri-apps/api@latest -
yarn
yarn upgrade @tauri-apps/cli @tauri-apps/api --latest -
pnpm
pnpm update @tauri-apps/cli @tauri-apps/api --latest -
cargo
cargo update
What’s in 1.3.0
NSIS
The Tauri CLI can now create Windows application installers using NSIS. This new bundle target is also available on macOS and Linux as an experimental feature, so you can cross-compile your Windows installer. Documentation on the latter will be published soon.
Tauri 1.3 Audit
The internal audit was performed by @tweidinger and @chippers, who are involved in most security topics at the Tauri project. It was performed during paid time at CrabNebula and we are grateful to be able to spend parts of our work time contributing to the open source project and making it a more secure environment ❤️.
We manually audited over 45 PRs. Some PRs (e.g. #5544) lead us to diving into very old RFCs (RFC6068 and RFC3966), NSIS documentation (e.g. #6039) and many other external resources. We documented questions, notes and findings in markdown files and shared these notes with the responsible developers to ensure appropriate fixes.
The changes from a security perspective and findings of the audit are summarized in the following sub-sections.
External API Access #5918
This was by far the most impactful and time consuming PR we investigated. This PR introduces a streamlined way for applications to allow external domains access to the Tauri IPC layer1 and usage majorly impacts the security model of a Tauri application. Security impact2 depends on exposure3 of the feature, enabled Tauri commands and the capabilities of an adversary4.
We consider this new feature similar to driving a very fast race car without any safety features enabled and urge developers to very very carefully consider if they really need this exposure.
Before this addition was merged, a semi-known vulnerability was (ab)used by application developers to achieve the same functionality. To make the whole community aware of this risk we published a security advisory to give a heads up. Applications are affected if they allow users to navigate to arbitrary domains or have an open redirect vulnerability5. If you implement such a feature you should update to the 1.3 release as fast as possible.
The initial PR changes allowed wildcards (https://*) and glob patterns, which we believe are helpful but shouldn’t be exposed to all Tauri developers. We concluded that the risk of over-exposure, like the allow list toggle to enable all Tauri API endpoints, does not justify this permissive exposure. The final implementation allows to configure specified (sub)domains6 (eg: example.com) to gain remote access to the Tauri IPC.
The few edge use cases, which require wildcards or even further exposure can be implemented by custom Rust code which is able to dynamically modify the IPC access. We now expose this remote IPC scope in a similar fashion as the fs or http scope.
Assuming a fully trusted web service on https://trusted.example it is now possible to configure the security scope to allow certain windows or even plugins access to custom implemented commands and optionally the inbuilt Tauri API:
"security": {
"dangerousRemoteUrlIpcAccess": [
{
"windows": ["main", "settings"],
"domain": "trusted.example",
"plugins": ["trusted-plugin"],
"enableTauriAPI": false
},
],
}
Shared domains MUST NOT be used for this in any circumstances. We do not limit access to paths or specific files. You can only scope with trusted (sub)domains6. Another very risky catch is that developers must be sure that the domain ownership does not change over the lifetime of the application. Domain takeover could lead to compromised user devices.
Browser Arguments #5799
Due to certain webview features not enabled nor being accessible, a community contribution introduced the possibility to add additional arguments to the webview process, which is created in a new window.
This feature was exposed to the frontend in the window endpoint. We found that this exposure was highly risky, as most webviews have very impactful features and flags that can be allowed via the process arguments.
All of the following threat model assumptions are based on the Tauri window creation being allowed in the allowlist of the tauri.conf and therefore exposed to the frontend. This PR affects Windows only, therefore there is no impact on the other supported operating systems.
An adversary with the capabilities to create windows and pass command line arguments to the webview can elevate their privileges to escape the strict sandboxing of Tauri and the webview.
The flags allow to enable several dangerous webview features, from loading profiles outside of the current default profile folder (stealing browser sessions from the device) to disabling security measurements of the webview (eg: certificate validation, sandboxing, webdriver/headless mode, device management endpoints, …).
We found an old but gold and still unique documentation reference at https://peter.sh/experiments/chromium-command-line-switches/, which helped us understand possible risks on Windows, as the Webview2 uses the same flags.
The feature was then changed to be only exposed on the rust side. Tauri application developers can use this to implement custom commands to invoke webview windows with use case specific arguments.
Possible ZipSlip #4674
We found that the components to extract remote bundler files like the Webview2 installer were manually extracting single files with the extract_zip function, which uses ZipFile::name() instead of ZipFile::enclosed_name() as recommended in the documentation. Files which had names like ../../../../foo.sh could be extracted outside of the intended directory on the filesystem. This kind of vulnerability is called ZipSlip.
As the function was only used on verified and trusted files the impact here was nearly zero. Regardless we changed the implementation to facilitate the proper extraction method.
Bundler Hardening #6039
The bundler was not escaping content passed to the handlebars::Handlebars::render(), which could cause unwanted code execution during the bundler phase. This was also a low impact issue but was promptly fixed.
Other changes
New
additional_browser_argsoption when creating windows #5799- Add
is_minimized()window method. #5618 - Add
titlegetter on window. #5515 - content protection APIs #5513
- Added
Builder::device_event_filterandApp::set_device_event_filtermethods. #5562 - Add
WindowsAttributes::app_manifestto specify the application manifest on Windows. #5730 - Add support for Cargo’s workspace inheritance. #5775 #6144
- Added window’s
url()getter. #5914 - Added
Window::on_navigation. #5686 - Allow setting the text of the dialog buttons. #4383
- Implement
SystemTray::with_tooltipandSystemTrayHandle::set_tooltipfor Windows and macOS. #5938 - Add dylib support to
tauri.bundle.macOS.frameworks. #5732
Enhancements
- On Windows, the
msiinstaller’sLaunch Appcheckbox will be checked by default. #5871 - Add
--pngoption for theiconcommand to generate custom icon sizes. #5246 - On Windows, change webview theme based on Window theme for more accurate
prefers-color-schemesupport. #5874 - Remove default features from Cargo.toml template. #6074
- Add a method to the
WindowBuilderstruct to recreate windows from tauri.conf.json configurations.#6073 - Improve the error message when
rustccouldn’t be found. #6021 - Added support for pre-release identifiers and build numbers for the
.msibundle target. Only one of each can be used and it must be numeric only. The version must still be semver compatible according to https://semver.org/. #6096 - Add
--ciflag and respect theCIenvironment variable on thesigner generatecommand. In this case the default password will be an empty string and the CLI will not prompt for a value. #6097 - Skip the password prompt on the build command when
TAURI_KEY_PASSWORDenvironment variable is empty and the--ciargument is provided or theCIenvironment variable is set. d4f89af18d69fd95a4d8a1ede8442547c6a6d0ee
Fixes
- Fix
tauri infopanicking when parsing crates version on a newly created project without aCargo.lockfile. #5873 - Fix building apps with unicode characters in their
productName. #5872 - Sync
__TAURI_METADATA__.__windowsacross all windows. #5615 - Fix resize glitch when double clicking a custom titlebar in the top resize area. #5966
- Disable cursor mouse events on Linux. #6025
- Fix serialization of js
Mapwhen used ininvoke. #6099
Footnotes
-
Inter-Process Communication, in this instance the communication between the Tauri core and the frontend code run inside the webview. ↩
-
Security Impact: What is the theoretical biggest impact of this threat combination? This highly depends on correct scoping of Tauri API endpoints and hardening of custom implemented Tauri commands. ↩
-
Exposure: Describes the exposed scope items of this feature to either an user or adversary. It is possible to restrict exposure to only certain domains, windows or only to custom implemented commands. ↩
-
Adversary Capabilities: Which kind of privileges has the adversary? Can range from tricking user into entering malicious input to code execution in the frontend via cross-site-scripting (which is the highest privilege for frontend code in our case). Common capabilities are described in the OWASP documentation. ↩
-
An application can be exploited if it parses user input for making an URL redirection decision, which is then not properly validated. Wikipedia Source ↩
-
see the Reqwest reference ↩ ↩2
Announcing Tauri 1.4.0
The Tauri team is excited to announce the 1.4 release. This version includes several new features and important bug fixes such as CLI completions, unit testing capabilities and Windows installer improvements.
Upgrading
Make sure to update both NPM and Cargo dependencies to the 1.4.0 release. You can update the dependencies with:
-
npm
npm install @tauri-apps/cli@latest @tauri-apps/api@latest -
yarn
yarn upgrade @tauri-apps/cli @tauri-apps/api --latest -
pnpm
pnpm update @tauri-apps/cli @tauri-apps/api --latest -
cargo
cargo update
What’s in 1.4.0
CLI completions
The Tauri CLI now can generate shell completions for Bash, Zsh, PowerShell and Fish. See the documentation for more information.
Disabling window controls
The window’s maximize, minimize and close buttons now can be disabled via configuration or API calls. Check out set_maximizable, set_minimizable and set_closable for the Rust APIs and setMaximizable, setMinimizable and setClosable for the JavaScript APIs.
NSIS improvements
The 1.4.0 release includes several NSIS bundle enhancements:
- Custom language files
- Custom installer template (.nsi file)
- Support for the dutch, japanese, korean, persian, swedish and turkish languages
- If your application is installed via WiX, the installer will prompt the user to uninstall it
- Improved support to updater install modes
See the installer customization guide and installer internationalization for more information.
MSRV change
Tauri 1.4 still has a minimum supported Rust version of 1.60, but due to some dependency incompatibility issues we are no longer pinning the patch version of the time, ignore, and winnow crates. If you are still using Rust 1.60, you will need to pin these versions manually with cargo update.
Unit tests
The tauri crate now exposes the test module under the test Cargo feature. This module is still unstable but allows you to unit test your application by creating a tauri::App instance that can execute without spawning windows. See the documentation for more information and examples.
Other changes
Starting on v1.4.0, our changelog format has been improved. Check out the entire list of changes:
Audit
The internal1 audit was performed by Tillmann @tillmann-crabnebula and Chip @chip-crabnebula, who are also involved in security topics at the project under their private handles (@tweidinger and @chippers).
It was performed during paid time at CrabNebula Ltd. and we are grateful to be able to spend parts of our work time contributing to the open source project and making it a more secure environment ❤️.
For this release we manually audited a selection of PRs instead of all PRs coming into the release. The new approach means the reviewers and developers need to decide on their own if a PR is introducing any security relevant change. A review can be triggered by anyone involved in the change, by adding a label to the PR.
For the first time we also audited after the official release due to time constraints. This resulted in a security patch release, fixing the only impactful issue (CVE-2023-34460) discovered during auditing. In general this release was more focused on fixing and improving the NSIS features and introduced less new features and security relevant changes.
Footnotes
- It is internal in the sense that we are also involved in the project itself but performed with the help of an external entity. Calling it external security audit would create false impressions. ↩
Announcing Tauri 1.5.0
The Tauri team is excited to announce the 1.5 release. This version includes several new features and important bug fixes such as improved resources bundling, code signing enhancements, notarytool migration on macOS and Bun support.
Upgrading
Make sure to update both NPM and Cargo dependencies to the 1.5.0 release. You can update the dependencies with:
-
npm
npm install @tauri-apps/cli@latest @tauri-apps/api@latest -
yarn
yarn upgrade @tauri-apps/cli @tauri-apps/api --latest -
pnpm
pnpm update @tauri-apps/cli @tauri-apps/api --latest -
cargo
cargo update
What’s in 1.5.0
Notarytool
At WWDC 2021 Apple introduced notarytool, a new tool for interacting with the Apple notary service. Before the 1.5 release, Tauri used altool to notarize your application, but that tool has been deprecated and will stop working for notarization on 2023-11-01. You must upgrade your Tauri CLI to 1.5 before that.
If you are using API keys for authentication with the notary service, notarytool no longer automatically searches for your APi key .p8 file. We recommend users to define its path via the APPLE_API_KEY_PATH environment variable, though to avoid breaking changes we perform the same lookup done by altool to find your key file in case you did not set the environment variable. In the future, this might change, so please adjust your publish pipelines accordingly.
Bun support
The Tauri CLI now supports the Bun package manager.
We would like to thank @colinhacks for submitting the pull requests for this feature!
Code signing improvements
Starting on Tauri 1.5, our bundler now signs all executables (including sidecars, app executables and NSIS uninstaller) and macOS frameworks. We also improved our notarization algorithm adding support to the APPLE_TEAM_ID environment variable to properly define the team ID associated with your account in case you belong to multiple teams.
We would like to thank @tr3ysmith for submitting the pull requests for this feature!
macOS frameworks
This release comes with enhanced macOS frameworks support by code signing all custom frameworks you inject via tauri.conf.json > tauri > bundle > macOS > frameworks and defining the @rpath value fixing a crash when updating your app.
We would like to thank @tr3ysmith for submitting the pull requests for this feature!
Mixed content on Windows
We now offer a configuration option to switch our custom protocol on Windows to use the http scheme instead of https. This reduces the security of your application on Windows since it allows connecting to insecure endpoints such as ws://url, but it matches the behavior on Linux and macOS custom protocols. To enable it, set the tauri.conf.json > tauri > security > dangerousUseHttpScheme to true.
Other changes
Check out the entire list of changes:
Announcing Tauri 1.6.0
The Tauri team is happy to announce the 1.6 release. This version includes several new features and important bug fixes such as improved code signing on macOS, updater enhancements and an event loop crash on all platforms.
Upgrading
Make sure to update both NPM and Cargo dependencies to the 1.6.0 release. You can update the dependencies with:
-
npm
npm install @tauri-apps/cli@latest @tauri-apps/api@latest -
yarn
yarn upgrade @tauri-apps/cli @tauri-apps/api --latest -
pnpm
pnpm update @tauri-apps/cli @tauri-apps/api --latest -
cargo
cargo update
What’s in 1.6.0
Event loop crash
We finally got a good stack trace and got a fix for a long standing crash on all platforms. This crash was a challenge to fix since it only happened when the application is running for a long time, so we thank everyone that made sure the fix works.
Code signing improvements
Tauri now detects nested dylib, app, xpc and frameworks inside your macOS app bundle and codesigns each of them. This ensures your app can use some external libraries and be codesigned and notarized.
Updater enhancement
The auto updater now keeps the command line arguments on Windows.
Other changes
Check out the entire list of changes:
Announcing Tauri 1.7.0
The Tauri team is happy to announce the 1.7 release. This version includes several bug fixes, performance improvements and features backported from the upcoming v2 release.
Upgrading
Make sure to update both NPM and Cargo dependencies to the 1.7.0 release. You can update the dependencies with:
-
npm
npm install @tauri-apps/cli@latest @tauri-apps/api@latest -
yarn
yarn upgrade @tauri-apps/cli @tauri-apps/api --latest -
pnpm
pnpm update @tauri-apps/cli @tauri-apps/api --latest -
cargo
cargo update
What’s in 1.7.0
Shell API performance improvement
The shell’s Command::execute API has been optimized to only use the IPC a single time instead of streaming data, improving usage of verbose shell scripts.
Feature backport from v2
Thanks to community effort we have backported a few bundler features from v2 into the v1 release.
Custom Windows codesign script
By default the Windows packaging uses SignTool, which only works on Windows so it’s not useful when cross compiling. In this release we have backported the custom sign command feature, which allows using osslsigncode, relic and other alternatives that can run on Unix systems and support hardware tokens, Azure Key Vault and more.
RPM bundle
RPM packaging have been available to Tauri v2 users for a while, and it is now also available on the v1 channel.
DMG configuration
DMG installers are now configurable: you can change the position of the icons and the window size to fit better within a custom background.
Other changes
Check out the entire list of changes:
Migration to webkit2gtk-4.1 on Linux port
Hello everybody! We just released Tauri v2.0.0-alpha3 recently. While it doesn’t bring any major feature, it does bring some huge impacts on Linux port. We will use WebKit2GTK–4.1 in 2.0 from now on.
What does this mean?
If you are using Tauri version 1.x, there’s nothing to worry about. Everything you need is still the same. But if you are using Tauri version 2.0 alpha version starting from alpha.3, you will need to install the new WebKit2GTK package with API version 4.1. We will update the prerequisites in our site soon. But if you want to know how to install such version, here are some instructions from wry:
# On Arch Linux / Manjaro:
sudo pacman -S webkit2gtk-4.1
# On Debian / Ubuntu:
sudo apt install libwebkit2gtk-4.1-dev
# On Fedora:
sudo dnf install webkit2gtk4.1-devel
Will this bring breaking changes to my code?
The main difference between version 4.0 and 4.1 are the soup library. WebKit2GTK-4.0 uses soup2 and WebKit2GTK-4.1 uses soup3. So if you didn’t use any soup2-specific APIs, your applications should continue to work fine.
The reason behind this change is because we aim to add flatpak support, but Gnome runtime uses webkit2gtk-4.1. There are also some subtle bugs like this that only happen in soup2 and they can be fixed by upgrading to soup3.
What other breaking changes we are going to expect?
The major one will be the MSRV. With Tauri v2.0.0-alpha.3 released, MSRV is bumped to 1.64. We will also update windows-rs in the future. This Rust version should satisfy the latest version of windows-rs. We do plan to update our MSRV with minor releases after 2.0. This could ease the friction to stick to any fixed Rust version while updating dependencies.
Tauri 2.0.0-alpha.4 Released
A new alpha release for the 2.0 has been published. This release includes all changes from the upcoming Tauri 1.3 release, an important breaking change on the HTTP client and native mobile capabilities for Tauri plugins.
Updating dependencies
Make sure to update both NPM and Cargo dependencies to the latest alpha release. You can update the NPM dependencies with:
-
npm
npm install @tauri-apps/cli@next @tauri-apps/api@next -
yarn
yarn upgrade @tauri-apps/cli@next @tauri-apps/api@next -
pnpm
pnpm update @tauri-apps/cli@next @tauri-apps/api@next -
cargo
cargo add tauri@2.0.0-alpha.4 cargo add tauri-build@2.0.0-alpha.2 --build cargo install tauri-cli --version "^2.0.0-alpha" --locked
Recreate the mobile projects to use the new features:
rm -r src-tauri/gen
tauri android init
tauri ios init
HTTP Client Breaking Change
The default HTTP client using attohttpc has been removed due to issues with the development server proxy on Windows. All reqwest-* feature flags have been removed because reqwest is now the client we use.
Native Mobile Functionality for Tauri Plugins
A Tauri plugin now can access iOS via Swift and Android APIs via Kotlin or Java code, simplifying usage of platform interfaces such as camera or geolocation. To bootstrap the iOS and Android projects on an existing plugin, run tauri plugin ios add and tauri plugin android add. New plugins automatically include all the configuration needed to write native mobile code.
Here’s an example of a plugin that takes a string value and resolves an object:
Android plugin:
ExamplePlugin.kt
package com.plugin.example
import android.app.Activity
import app.tauri.annotation.Command
import app.tauri.annotation.TauriPlugin
import app.tauri.plugin.JSObject
import app.tauri.plugin.Plugin
import app.tauri.plugin.Invoke
@TauriPlugin
class ExamplePlugin(private val activity: Activity): Plugin(activity) {
@Command
fun ping(invoke: Invoke) {
val value = invoke.getString("value") ?: ""
val ret = JSObject()
ret.put("value", value)
invoke.resolve(ret)
}
}
iOS plugin:
ExamplePlugin.swift
import UIKit
import WebKit
import Tauri
class ExamplePlugin: Plugin {
@objc public func ping(_ invoke: Invoke) throws {
let value = invoke.getString("value")
invoke.resolve(["value": value as Any])
}
}
@_cdecl("init_plugin_example")
func initPlugin(name: SRString, webview: WKWebView?) {
Tauri.registerPlugin(webview: webview, name: name.toString(), plugin: ExamplePlugin())
}
Rust code to initialize the plugin:
use tauri::{
plugin::{Builder, TauriPlugin},
Manager, Runtime,
};
#[cfg(target_os = "ios")]
tauri::ios_plugin_binding!(init_plugin_example);
pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("example")
.setup(|app, api| {
#[cfg(target_os = "android")]
api.register_android_plugin("com.plugin.example", "ExamplePlugin")?;
#[cfg(target_os = "ios")]
api.register_ios_plugin(init_plugin_example)?;
Ok(())
})
.build()
}
Frontend code to call the plugin command:
import { invoke } from '@tauri-apps/api/tauri';
invoke('plugin:example|ping', { value: 'Tauri' }).then(({ value }) =>
console.log('Response', value)
);
Check out the upcoming camera plugin and path plugin.
Announcing the Tauri v2 Beta Release
Tauri v2 has been in progress for over a year and it is now ready to take the next step towards being stable! We have just released Tauri v2.0.0-beta.0 which represents a major milestone from our roadmap.
The v2 release introduces mobile support to Tauri and also comes with several new features that have been requested by the community. Let’s get a high level overview of the major changes:
Mobile
Developing an application for desktop and mobile has never been easier. Tauri v2 is a huge statement on cross platform development now that we support Android and iOS. You can bring your existing desktop implementation and seamlessly port it to mobile, with access to native APIs and the great developer experience of the Tauri CLI.
Permissions
The v1 allowlist is a good tool for securing your frontend from accessing unnecessary APIs, but its configuration is not fine grained and it lacks multiwindow support. The 2.0.0-beta.0 release includes a new approach for command access based on Access Control List. It is now possible to allow commands and define scopes for specific windows or even remote URLs.
New Features
v2 includes many of the most requested features by the Tauri community:
Revamped IPC
The v1 Inter-Process Communication (IPC) which is responsible for delivering messages between the Rust and JavaScript layers uses a very rudimentary webview interface which forces us to serialize all messages to strings and is super slow to deliver responses. The new v2 IPC uses custom protocols, which is more reminiscent in function and performance to how the webview handles regular HTTP based communication, see the pull request for more information.
Additionally, there is a new channel API so you can quickly send data from Rust to your frontend.
Multiwebview
Tauri now supports adding multiple webviews to a single window. This is also a highly anticipated feature request. Note this is still an unfinished feature that is hidden behind an unstable Cargo feature flag while we review the API design together with the community.
Menu and tray icon JavaScript APIs
Previously you could only configure window menus and tray icons via Rust code. Now you can do so on the JavaScript side too, which is a lot easier! We also added APIs to manage the macOS application menu specifically.
Context Menus
One of the most requested features is native context menus. It is finally available with both Rust and JavaScript APIs powered by muda.
Window APIs
Several new window APIs have been implemented, making your app much more configurable.
Mobile APIs
The v2 release comes with some mobile native API support by default. Currently there is support for notifications, dialogs, NFC, barcode reading, biometric authentication, clipboard and deep link. More APIs will be added soon after the stable release.
Audit
We are currently being audited to ensure v2 is safe, similar to what we did for the v1 stable release.
Stability
The API is not stable yet, but no major changes are expected. As soon as the audit is completed and the changes are done, we will promote to a Release Candidate and a v2 stable release soon after that. Stay tuned!
Tauri 2.0 Release Candidate
We are very proud to finally announce the first release candidate for the new major version of Tauri.
After over half a year of beta versions, following over a year of alpha versions we are finally at the point where we consider Tauri 2 stabilized and do no longer expect breaking changes.
We want to use a comparably short release candidate time frame to focus on our documentation and important bug fixes, which have been reported by our awesome community and working group members.
A simplified TL;DR can be found at the end of this post.
The Road to Stable and Beyond
With this release candidate we want to communicate our expectations and timeline for the stable release.
We have been asked countless times “Wen Tauri 2.0?” and always gave broad answers. Especially in open source projects overpromising can be a quick way to burn out developers and maintainers or lead to angry comments from disappointed adopters.
This is one of the reasons for the long alpha and beta stage and why we waited with the release candidate, as we strive to get things right and simple to use.
Another reason is that we made the mistake of overpromising this major version with “mobile as a first class citizen” and realized over the past months that we can only build the foundation for mobile on our own and need to iterate on this together with the community and our adopters to get it right.
This doesn’t mean that mobile is broken and unsupported. We have mobile plugins in our official plugin repository and have seen developers who have built cool apps on Android and iOS with Tauri.
Our partner CrabNebula also provided us with feedback on how easy (or complicated) the developer experience was when they built or supported mobile applications for customers. They even contributed multiple mobile plugins (NFC, Barcode Scanner, Biometric, Haptics, Geolocation) as part of their work.
We see improvements to be made in the development experience for mobile and we acknowledge that not all of our desktop features and plugins are ported or available on mobile yet.
This causes us to say that we don’t want to raise expectations that Tauri 2.0 will be the “mobile as a first class citizen” release but we want to make clear that you can develop production ready mobile applications with Tauri NOW.
What you can expect from stable after this release candidate is:
- Clearer and comprehensive documentation
- Less critical bugs preventing productive usage
We plan to release the stable version for 2.0 in the end of August. This will, at the time of writing, allow for a ~4 week release candidate cycle.
After the stable release our focus will be shifting to providing feature parity wherever possible and to improve the development process for mobile. This will happen in minor releases of Tauri.
Feature parity and plugin development will be aligned with major versions of Tauri but will be mostly independent from Tauri core features and happen in our plugin-workspace repository.
Developer experience is a very important topic for us. If you have improvement suggestions or want to improve the status quo on your own please do not hesitate to reach out with PRs, issues or friendly conversations on our discord server.
Breaking Changes
Before we enter the “no more breaking changes” expectation phase we discussed and planned some from our perspective necessary breaking changes a while ago.
These changes affect a lot of developers, so we wanted to bundle them and make it as painless as possible to upgrade from the latest beta to release candidate or stable.
For app developers we have breaking changes in how core plugins are referenced in the permissions.
You should be able to automatically migrate from the latest beta to release candidate. For this to succeed you must be sure to be on the latest (RC not beta) version of the Tauri CLI.
Automated Migrate
-
npm
npm install @tauri-apps/cli@next npm run tauri migrate -
yarn
yarn upgrade @tauri-apps/cli@next yarn tauri migrate -
pnpm
pnpm update @tauri-apps/cli@next pnpm tauri migrate -
cargo
cargo install tauri-cli --version "^2.0.0-rc" --locked cargo tauri migrate
Otherwise please read the detailed section below explaining the changes and how to manually migrate.
For downstream consumers of Tauri as a library or app developers fiddling with the internals of Tauri we have a bigger refactor you should check out.
Tauri Core Plugins
With Tauri 2.0 we migrated most of the 1.x core functionality into separate plugins, which allows us to iterate on these independently of Tauri’s core and lowers the barrier for first contributors on functionality.
This migration also included keeping some functionality inside Tauri as pseudo plugins. Fully qualified plugins need to implement the Plugin Trait and need to be individual crates following the tauri-plugin-<plugin name> naming scheme. For core plugins, the second condition was not possible as we would have circular dependencies on Tauri. So we created pseudo plugins, which are always initialized by Tauri itself and only implement the plugin trait. These are for example window, path or webview. Right now these are allowed in the capabilities of your Tauri application in the following way:
...
"permissions": [
"path:default",
"event:default",
"window:default",
"app:default",
"image:default",
"resources:default",
"menu:default",
"tray:default"
]
...
This has multiple problems:
- Any plugin crate which has a colliding name will break our build process (e.g.
tauri-plugin-windowcrate) and our cli for adding plugins (e.g.cargo tauri add window) - We can’t use any core pseudo plugin naming that is already used by existing plugins (e.g. if we would ever want to create
tauri-plugin-mobile-coreand it is already used we will encounter the first problem) - It is unclear for developers what is a core plugin and what is a dedicated plugin when looking at capabilities
Our approach is to use a fixed namespace for core plugins, which is documented and enforced by the Tauri core. All plugins starting with core: or the plugin name core are now considered core pseudo plugins and will only be initialized if they are in the Tauri codebase.
This will cause a breaking change to all capabilites enabling Tauri core features. The above example will be changed to look like this:
...
"permissions": [
"core:path:default",
"core:event:default",
"core:window:default",
"core:app:default",
"core:image:default",
"core:resources:default",
"core:menu:default",
"core:tray:default"
]
...
We also added a new special core:default permission set which will contain all default permissions of all core plugins, so you can simplify the permissions boilerplate in your capabilities config.
...
"permissions": [
"core:default"
]
...
We consider the core default exposure to be reasonably secure and safe to enable by default, with limited impact in case of a compromised frontend.
To migrate from the latest beta version you need to prepend all core permission identifiers in your capabilities with core: or switch to the core:default permission and remove old core plugin identifiers.
Development Server for Mobile
We introduced changes to the network exposure of the built-in development server PR #10437 and PR #10456. With the changes shipped in the 2.0.0-rc.0 release of the Tauri CLI, we can connect to your development server running on localhost when targetting Android and iOS (previously this was only possible when developing a desktop application).
This means you no longer need to expose your development server on the public network.
Note
When running your app on a physical iOS device we actually need to bind the development server on a TUN address provided by the device.
This kind of connection is currently only possible when Xcode is opened and connected to your device, so we do not use this interface by default - we have to bind your development server to your public network address while we find out a way to connect to the device ourselves.
To use the iOS device’s address instead of the public network, run tauri ios dev --force-ip-prompt to select the iOS device’s TUN address (ends with ::2).
The IP address your frontend must listen to is provided by the TAURI_DEV_HOST environment variable.
Here’s an example of a Vite configuration migration:
- 2.0.0-beta:
import { defineConfig } from 'vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';
import { internalIpV4Sync } from 'internal-ip';
const mobile = !!/android|ios/.exec(process.env.TAURI_ENV_PLATFORM);
export default defineConfig({
plugins: [svelte()],
clearScreen: false,
server: {
host: mobile ? '0.0.0.0' : false,
port: 1420,
strictPort: true,
hmr: mobile
? {
protocol: 'ws',
host: internalIpV4Sync(),
port: 1421,
}
: undefined,
},
});
- 2.0.0-rc:
import { defineConfig } from 'vite';
import Unocss from 'unocss/vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';
const host = process.env.TAURI_DEV_HOST;
export default defineConfig({
plugins: [svelte()],
clearScreen: false,
server: {
host: host || false,
port: 1420,
strictPort: true,
hmr: host
? {
protocol: 'ws',
host: host,
port: 1430,
}
: undefined,
},
});
Note
This means the internal-ip NPM package is no longer required, you can directly use the TAURI_DEV_HOST value instead.
Rust API Surface Refactor
With a coordinated effort between multiple working group members we partially changed our Rust API exposure. This affects only consumers of our Rust API and should have no breaking change impact for Tauri application developers.
This was motivated by a recent security advisory CVE-2024-35222, as the fix needed to introduce additional fields to a structure that was directly publicly exposed and caused breaking changes to some projects and internal usage.
We concluded that this overexposure will hinder us in the future and will cause unnecessary breaking changes, so we decided that going from beta to RC will be the last chance for us to implement this until we start down the road of Tauri 3.0.
We reduced the amount of publicly exposed components, which are meant for internal use. Additionally, we made our publicly exposed structures either non-exhaustive or transformed them into exposing builder patterns or constructors. In some cases we added a new extend field to allow dynamic additions in the future. Finally, we made sure to document which modules of Tauri are considered unstable.
This will help us to provide (security) fixes or changes without breaking interfaces that are considered stable.
Please take a closer look at the introduced and discussed changes in the #10158 pull request.
External Security Audit
TL;DR
The audit concluded some time ago and all issues were fixed and retested. Report is here. Please upgrade to the release candidate to ensure fixes for the reported issues.
We have been quiet on this front for some time as we have been busy fixing and discussing issues discovered during the beta versions.
We never marketed version 2 beta releases as production ready but were aware of some apps deployed into production. This caused us to announce and distribute a security patch for one of the findings (CVE-2024-35222) which was also independently discovered by a Tauri community member.
All other findings were fixed in multiple beta versions but we did not create advisories for these. We concluded a full heads up could wait until the release candidate, as the findings mainly affect the development phase or have no critical severity.
With the release candidate we will add the full report to our repository. Please take your time to read the report and learn more about the awesome work of @gronke and @pcwizz from RadicallyOpenSecurity.
The whole audit was funded by the great folks at NLNet and we are super grateful to be in the privileged position to get fully funded external security audits.
Call to Action
All of the above topics share a common theme. These would not have been possible without the continuous support of the community, our working group and other movements working towards improving the status quo.
Before we are going to release Tauri 2.0 we want to make sure that your voices are heard, your PRs are acknowledged and the documentation is helpful for YOU so that you can build the next generation of cross platform apps.
Currently we have over 30 people in our working group on Github but even more involved in our Discord. These awesome people are mostly working on Tauri in their free time with very few exceptions. We currently see a number of issues, PRs and discussions being unsolved and open for longer than we would like to.
To improve this situation we ask YOU to get involved into the Tauri project.We have all kinds of situations where we are able to accept event the tiniest contribution.
If you are familiar with Tauri and have used it already during your journey, please take your time to check out the Github Discussions, Github Issues and our Discord Support. Maybe you have already solved the issues your fellow newcomers to Tauri are experiencing right now.
If you think that some of these problems you have seen are generic and should be documented somewhere we probably have the perfect place for it in our official documentation.
To contribute improvements or additions we are open for PRs in the tauri-docs repository. Please make sure you’ve read the guidelines for contribution though.
If you are in the position to understand and translate the current documentation into your native language we appreciate content translations to our documentation.
If you have followed our project for a while but never made a contribution we would be happy to understand what has prevented you from doing so and how we could improve this. Please reach out to us in our Discord or in our Github Discussions.
Too Long Didn’t Read
- Tauri 2.0 Release Candidate out now!
- Some migration from beta is needed. Check out
tauri migrate. - External Security Audit for 2.0 is available here
- All findings are fixed and fixes were verified
- Documentation is our focus until stable release
- Tauri is looking for more contributors and community involvement
Tauri 2.0 Stable Release
We are very proud to finally announce the stable release for the new major version of Tauri. Welcome to Tauri 2.0!
What is Tauri?
Definition
Tauri is a framework for building tiny and fast binaries for all major desktop (macOS, linux, windows) and mobile (iOS, Android) platforms.
Developers can integrate any frontend framework that compiles to HTML, JavaScript, and CSS for building their user experience while leveraging languages such as Rust, Swift, and Kotlin for backend logic when needed.
In a Tauri application the frontend is written in your favorite web frontend stack. This runs inside the operating system WebView and communicates with the application core written mostly in Rust.
No Rust Skills Needed!
You don’t need to write Code in Rust, Swift or Kotlin in most cases. Tauri already offers an extensive JavaScript API.
When Should I Use Tauri?
If you check any of the boxes below, you should use Tauri:
- Do you want a single UI codebase for all platforms?
- Do you want to reach as many users as possible on their platform (eg. Windows, MacOS, Linux, Android, iOS)?
- Are you a frontend web developer and want to write native applications?
- Are you a Rust developer looking to write applications with a nice looking UI with the option to do it in Rust?
- Do you have an existing team of web developers and want to expand to native application markets with low upfront investment?
- Do you have an existing team of rustaceans and want everything written in Rust?
How Popular is Tauri?
On GitHub the Tauri repository has ~4,878 Pull Requests and ~3,570 Issues closed and around 1000 discussions, at the time of writing. To get a more detailed insight take a look at the OSSinsight analysis of the Tauri repository.
Our Discord Server currently has ~17,700 members. We are seeing a lot of individual user support, questions on Tauri itself, questions directly to the working group or just discussions between fellow Tauri app developers.
We are very happy about the positive and supportive community and grateful to all the community members answering or helping others in Discord or GitHub.
We maintain a curated list of Tauri related projects, applications, plugins, guides and more at awesome-tauri. Check this out if you want to get inspiration, see what others are building and ideally create a PR to add your project.
Of course this is only a representative sample set and we don’t know exactly who else is building on Tauri.
How Did We Get to 2.0?
In June 2022 we released Tauri 1.0 with a great impact on the desktop operating system market and how cross platform applications can be built.
In the end of 2022 we released our initial alpha version of 2.0 to get initial feedback and to test out how mobile interaction should be defined.
After the initial alpha we spent close to two years refining and changing the architecture of Tauri in public. After we saw the broad picture clear enough ourselves we released the beta in Februrary this year. At the same time we collaborated and worked with external security auditors to check our decisions, architecture changes and much more.
This August we published the release candidate version of 2.0 to iron out major bugs and to get more feedback from productive use. At the same time the external audit was concluded and made public.
The release candidate time frame was considerably shorter and consisted mainly of high impact bugfixes and documentation improvements. Some breaking changes we had to make during the release candidate phase were bundled up until the end and are now included in the stable release. Take a look at the migration section if your main concern is upgrading from a previous version.
In total we spent over two years working on improvements, new features, bugfixes, documentation, rewrites and a lot of discussions.
This all happened while we released 8 minor versions of the Tauri 1.x branch and backported security fixes and other important bug fixes in several patch releases.
Who Made This Release Possible?
This release and Tauri itself is only possible due to massive amount of contributions from Lucas, who has provided a constant stream of code changes over the years ❤️.
Obviously, Lucas is not the only individual working and contributing to Tauri, but we feel he deserves a very special mention for carrying, starting, and supporting the project and its community throughout the years.
We have had major contributions to the Tauri repository in 2.0 from Amr, Fabian-Lars, Tony, Chip, Jason, YuWei, icb , Simon, Oliver Lemasle and many more contributors (source data).
We received an increasing number of drive-by contributors (one or very few PRs). We are grateful for these, but naming everyone would make this a very long list here.
We have a lot(!) of repositories in our organization, which are supporting the success of Tauri and without community and working group contributions Tauri would not be where it is now. A big thank you to everyone involved!
Another special shout out and thanks for their constant involvement in the community goes to Fabian-Lars and Simon. If you have been involved in Tauri’s Discord or Github discussions you likely know their name or avatar.
If you ever searched on Google or YouTube for Tauri, you have probably seen one of Jacob’s streams. If that’s not the case please make sure to check it out and subscribe as his sessions are beyond just educational.
Another special place in our heart has the Tauri Board, highlighting Daniel Yvetot-Thompson for the numerous hours, sweat, blood and dedication to make Tauri known and sustainable.
One important thing we should not forget, is that we acquired support from a stable partner of this open source project.
CrabNebula granted multiple people mentioned above and others that are not mentioned here, the privilege to work on the Tauri ecosystem not only in their private time, but also during work time. You can find the partnership announcement on our blog and we have been more than happy about this collaboration over the last year.
In 2024 alone they spent over 2,870 work hours on this project, which massively pushed the progress and allows us to announce the stable 2.0 release today.
If you were not aware of CrabNebula yet, make sure to check out their products and services and consider the symbiotic relationship with Tauri if you are interested in not only improving your workflows, but also supporting the Tauri ecosystem.
What Makes 2.0 Great?
With this major release we improved and changed several aspects of how and where you can build, develop and publish your Tauri app. In the following sections we have more detailed insight. This does not cover everything, but should give you a decent impression on what you can expect from Tauri.
Getting Started Experience
One thing you are always going to go through when starting with a new framework or tool is the initial onboarding or getting started process.
We value developer experience (DX) and try to make this initial process as seamless as building and distributing your final application.
For this we created another project, which is called create-tauri-app or in short CTA. This tool allows developers to start from scratch and get to a running Tauri app in a few minutes instead of hours.
-
Bash
sh <(curl https://create.tauri.app/sh) -
PowerShell
irm https://create.tauri.app/ps | iex -
Fish
sh (curl -sSL https://create.tauri.app/sh | psub) -
npm
npm create tauri-app@latest -
Yarn
yarn create tauri-app -
pnpm
pnpm create tauri-app -
deno
deno run -A npm:create-tauri-app -
bun
bun create tauri-app -
Cargo
cargo install create-tauri-app --locked cargo create-tauri-app
Of course you need to install some prerequisites on your development system before you can start building your application. For this we have extensive guides with operating system specific sections in our official documentation.
This whole onboarding experience has been improved and now also bootstraps mobile development templates for iOS and Android.
Hot-Module Replacement
After the initial onboarding you will regularly develop and debug your Tauri application. We considered what would improve your development process already in 1.x of Tauri and extended the Hot-Module Replacement (HMR) to mobile devices and emulators.
This means that all changes to the frontend of your application do not require a rebuild of your whole application and you can live preview how it will look like in the device or operating system your are developing for.
Your browser does not support the video tag.
Plugins
With Tauri 2.0 we built a more advanced plugin system. We transferred a lot of our previous functionality into our official plugins (see plugins-workspace), to allow the community an easier entry into contributing to Tauri. We also hope to attract more maintainers for plugins and to speed up the process of implementing new features.
This move to plugins has another benefit. We are going to be able to define a definition of done for Tauri’s core. We hope to stabilize the core functionality and offer a stable framework, where the moving parts are mostly plugins offering access to system specific functionality.
You no longer need to understand all of Tauri to improve or implement specific features. The plugins usually do not depend on other plugins, with some exceptions. This means to implement a new file system access functionality it is only required to contribute to the fs plugin instead of Tauri itself.
As this release also targets mobile platforms, the plugin system also supports mobile plugins. You can write or re-use native code in Swift on iOS and Kotlin on Android and directly expose functions to the Tauri frontend using Annotations (@Command on Android), implementing a Subclass (YourPluginClass: Plugin) on iOS, or by invoking the Swift or Kotlin code from a Rust based Tauri command. Check out the documentation on how to write your own plugin.
As we are releasing Tauri as 2.0, the official plugins will follow the major version of Tauri to make compatibility with Tauri’s major version visible at a glance. Not all plugins are as stable as Tauri itself though.
Each plugin’s stableness is defined per plugin and documented (soon) in the plugin documentation. The plugin API can possibly break in minor versions, but we will try to keep these changes to a minimum, especially for plugins considered stable.
Tip
You can pin your plugin versions to only patch updates if you need absolute stable interfaces. We generally try to backport security updates and will announce advisories on GitHub.
Automatically launch your app at system startup.
Allows your mobile application to use the camera to scan QR codes, EAN-13 and other types of barcodes.
Prompt the user for biometric authentication on Android and iOS.
Read and write to the system clipboard.
Parse arguments from the command line interface.
Set your Tauri application as the default handler for an URL.
Native system dialogs for opening and saving files along with message dialogs.
Access the file system.
Get and track the device's current position, including information about altitude, heading, and speed (if available).
Register global shortcuts.
Haptic feedback and vibrations on Android and iOS
Access the HTTP client written in Rust.
Use a localhost server in production apps.
Configurable logging.
Read and write NFC tags on Android and iOS.
Send native notifications to the user.
Open files and URLs in external applications.
Read information about the operating system.
Persist runtime scope changes on the filesystem.
Move windows to common locations.
Access the current process.
Access the system shell to spawn child processes.
Ensure that a single instance of your Tauri app is running at a time.
Tauri Plugin providing an interface for the frontend to communicate with SQL databases through sqlx.
Persistent key value storage.
Encrypted, secure database.
In-app updates for Tauri applications.
File uploads through HTTP.
Open a WebSocket connection using a Rust client in JavaScript.
Persist window sizes and positions.
Mobile Support
A very much awaited part of this release is the mobile operating system support. The previous version of Tauri allowed to have a single UI code base for desktop operating systems but now this extends to iOS and Android.
We have investigated and experimented with different solutions to support mobile and decided on using the operating system native language (Swift and Kotlin) to build an interface for the Rust code and to allow developers to write part of their functionality in these languages.
This means you can re-use existing logic of your Swift or Kotlin app that interacts with the system and expose it to Rust or the frontend. Right now this works as mentioned above via the plugin system.
We support development with an emulator or a real device and provide a lot of tooling to make the process as seamless as possible. We are not completely happy about the developer experience at the moment but are actively improving to bring it up to par with the desktop experience.
On mobile not all of the official plugins are supported. Some are by design not a good fit for mobile and some are just not implemented to support mobile yet. If you would like to contribute on this part check the last section of this post.
The Allowlist is Dead, Long Live the Allowlist
Yes, there is no allowlist anymore, as we hit the limits of this system pretty quickly. We made it exclusive for Tauri core features and it did not even cover all of Tauri’s APIs. Our new system not only covers all of Tauri’s core API surface, it also supports app and plugin developers to implement their own access control and scoping with a unified approach.
The new system we implemented is using permissions - “On-off toggles for Tauri commands”, scopes - “Parameter validation for Tauri commands” and capabilities - “Attaching permissions and scopes to Windows and WebViews”, to create a flexible but simple to use access control system.
It allows the creation of named permission or scoping files and to re-use and combine them with other named permissions or scopes. This makes it possible to build more fine grained descriptive sets containing several simple or complex permissions and scopes.
As a plugin developer you can abstract away several base permissions into a default permission. This can be based on your default security assumptions and threat model. All official Tauri plugin default permissions are reasonably secure by default.
As an app developer you can use, extend or reduce plugin permissions. Of course you can also build permissions and scopes for your own application.
With this addition, Tauri’s core is now able to understand if a command invoke message from a frontend WebView is allowed to reach the command function. It is also able to attach the configured scope to the message.
The command implementation is responsible for interpreting and enforcing the scope. You can read more about our Threat Model and approach to security in our documentation.
External Security Audit
The major changes and architecture of v2 was independently audited by Radically Open Security during the beta and release candidate period. Please take your time to read the report and learn more about the awesome work of @gronke and @pcwizz.
The whole audit was funded by the great folks at NLNet via funding from NGI and we are super grateful to be in the privileged position to get fully funded external security audits for major releases.
The results of this audit caused us to rewrite parts of how our dev server is exposed, specifically for mobile development. Without the help and guidance of the auditors this rewrite would not have been possible ❤️.
Additionally, we hardened our iFrame API exposure, fixed scope validation and resource identifier access for the fs and http plugin, improved our inter-process communication stability, and many other security related fixes and improvements.
Inter Process Communication (IPC) Rewrite
With the rewrite of our IPC layer we now support a long wished feature of Raw Payloads and generally changed how it works under the hood.
Previously all IPC payloads were json serialized and deserialized which caused an overhead. This was noticeable once more than a few kilobytes were transfered between frontend and backend.
The new system supports Raw Requests. These speed up the transfer of large data from backend to frontend and vice versa, where you can either use raw bytes directly or use your own (de)serialization process (eg. bson, protobuf, avro and others).
For directly reading files from the filesystem into the WebView we still recommend the convertFileSrc functionality, as it is most likely still faster if you do not need to process the data on the Rust backend.
Distribution Guides
With Tauri 2.0 the distribution diversity greatly increased. Partially, due to the mobile ecosystem and partially due to our community contributions.
We have official guides on how to ship to the Apple Appstore, Google Play, Microsoft Store, CrabNebula Cloud, Flathub, Snapcraft, AUR and more distribution formats in our distribution docs.
Github Action
Our GitHub action (tauri-action) is in progress to support automated building for the mobile operating systems but does not support it yet.
Changelog
This section contains all changes going from 1.x in a concise list.
Show the Full List
Added
-
Added Mobile support.
-
Added multiwebview support behind the unstable feature flag. See WindowBuilder and WebviewBuilder for more information.
-
Added
rustls-tlscargo feature flag -
Added
shadowoption when creating a webview window,WebviewWindow::set_shadowmethod in Rust and equivalent API in JS. -
Added
tauri::Webview,tauri::WebviewBuilder,tauri::WebviewWindow,tauri::WebviewWindowBuilderstructs in Rust and equivalent classes in Js. The oldtauri::Windowandtauri::WindowBuilderbehaviors have moved totauri::WebviewWindowandtauri::WebviewWindowBuilder. -
Added
tauri::scope::fsmodule -
Added
tauri::App/AppHandle::default_window_iconmethod. -
Added
tauri::ipcmodule with IPC primitives. -
Added
tauri::ipc::Channeltype and equivalent JSChanneltype to send data across the IPC. -
Added
incognitooption when creating a webview window. -
Added
windowEffectsoption when creating a webview window andWebviewWindow::set_effectsto try and change effects at runtime. -
Added
tauri::path::PathResolver -
Added
tauri::Manager::pathmethod to access the newPathResolver -
Added
visibleOnAllWorkspacesoption when creating a webview window. -
Added
tauri::App/AppHandle::primary_monitorandApp/AppHandle::available_monitorsmethods. -
Added
tauri::plugin::Builder::on_navigationandtauri::plugin::Plugin::on_navigation. -
Added
tauri::WebviewWindow::navigatemethod -
Added
tauri::RunEvent::Openedon macOS and iOS for deep link support. -
Added file associations support in bundler.
-
Added
tauri::App/AppHandle::cleanup_before_exitto manually call the cleanup logic. You should always exit the tauri app immediately after this function returns and not use any tauri-related APIs. -
On Linux, add
tauri::WebviewWindow::default_vboxmethod to get a reference to thegtk::Boxthat contains the menu bar and the webview. -
Added
linux-libxdocargo feature flag (disabled by default) to enable linking tolibxdowhich is used to makeCut,Copy,PasteandSelectAllnative menu items work on Linux. -
On macOS, add
tauri::WebviewWindow::ns_viewmethod to get a pointer to theNSWindowcontent view. -
Added
tauri::Builder::register_asynchronous_uri_scheme_protocolto allow resolving a custom URI scheme protocol request asynchronously to prevent blocking the main thread. -
Included drop and hover position for drag and drop events.
-
Added
tauri::WebviewWindow::set_progress_barmethod -
Added
tauri::WebviewWindow::set_always_on_bottommethod andalwaysOnTopoption when creating a webview window. -
Added
tauri::WebviewWindowBuilder::on_page_loadmethod. -
Added
common-controls-v6cargo feature flag (enabled by default). -
Added
Window::destroyto force close a window. -
Added
tauri::EventIdtype -
Added
tauri::WindowBuilder::on_downloadto handle download request events. -
Added
tauri::WebviewWindowBuilder::parentwhich is a convenient wrapper around parent functionality for Windows, Linux and macOS. -
Added
tauri::WebviewWindowBuilder::owneron Windows only. -
Added
tauri::WebviewWindowBuilder::transient_forandtauri::WebviewWindowBuilder::transient_for_rawon Linux only. -
Added
tauri::WebviewWindow::start_resize_draggingandtauri::ResizeDirectionenum. -
Added
tauri::WebviewWindowBuilder::proxy_urlmethod. -
Added
tauri::WebviewEventenum -
Added
tauri::RunEvent::WebviewEventvariant. -
Added
tauri::Builder::on_webview_eventandtauri::Webview::on_webview_eventmethods. -
Added
tauri::imagemodule which includestauri::image::Imageandtauri::image::JsImagetypes andtauri::image::include_img!macro. -
Added
tauri::is_devfunction to determine whether the app is running in development mode or not. -
Added
tauri::Assets::setupmethod ontauri::Assetstrait that lets you run initialization code for your custom asset provider. -
Added
tauri::Rectstruct. -
Added
tauri::WebviewWindow::set_zoommethod -
Added
zoomHotkeysoption when creating a webview window. -
Added
window.isTauriJS global function to check whether running in tauri or not. -
Added
spectafeature flag which addsspectasupport forAppHandle,State,Window,WebviewandWebviewWindowtypes. -
Added
tauri::App/AppHandle/WebviewWindow::cursor_positiongetter to get the current cursor position. -
Added
tauri::App/AppHandle/WebviewWindow::monitor_from_point(x,y)getter to get the monitor from a given point.. -
Added
tauri::RunEvent::Reopento handle click on dock icon on macOS. -
Added
defaultWindowIconto the JSappmodule to retrieve the default window icon in JS. -
Added
tauri::WebviewWindow::set_title_bar_styleto set title bar at runtime on macOS. -
Add APIs to enable setting window size constraints separately:
- Added
tauri::WindowBuilder::inner_size_constraintsandtauri::WebviewWindowBuilder::inner_size_constraints - Added
tauri::WindowSizeConstraintsstruct - Added
tauri::Window::set_size_constraintsandtauri::WebviewWindow::set_size_constraints
- Added
Enhancements
-
Use custom protocols on the IPC implementation to enhance performance.
-
Enhance centering a newly created window, it will no longer jump to center after being visible.
-
The
custom-protocolCargo feature is no longer required on your application and is now ignored. To check if running on production, use#[cfg(not(dev))]instead of#[cfg(feature = "custom-protocol")]. -
Improved the JS
pathAPIs to return simplified paths on Windows when possible, i.e removing UNC (\\?\) prefix. -
Improved the error message that is shown when deserializing the Tauri plugin config.
-
Set the gtk application id to the
identifierdefined intauri.conf.jsonto ensure the app uniqueness. This can be disabled by settingenableGtkAppIdoption tofalse. -
On Windows, handle resizing undecorated windows natively which improves performance and fixes a couple of annoyances with previous JS implementation:
- No more cursor flickering when moving the cursor across an edge.
- Can resize from top even when
data-tauri-drag-regionelement exists there. - Upon starting rezing, clicks don’t go through elements behind it so no more accidental clicks.
-
Mark
AppHandle::restartandprocess::restartas diverging functions
Bug Fixes
- No longer unpacking and flattening the
payloadover the IPC so that commands with arguments calledcmd,callback,error,optionsorpayloadaren’t breaking the IPC. - Fix calling
set_activation_policywhen the event loop is running. - Fix can not prevent closing a window from another webview.
- On Windows, fix decorated window not transparent initially until resized.
- Resolve symlinks on the filesystem scope check.
- Fix the JS
basename(path, 'ext')API implementation removing all occurances ofextwhere it should only remove the last one. - Fix window white flashing on exit on Windows
- Apply
minWidth,minHieght,maxWidthandmaxHeightconstraints separately, which fixes a long standing bug where these constraints were never applied unless width and height were constrained together.
Changed
- The window creation and setup hook are now called when the event loop is ready.
- Renamed the
default-tlsfeature tonative-tlsand. - Changed the plugin setup hook to take a second argument of type
PluginApi - Changed
tauri::Windowstruct behavior and moved its old behavior to the newtauri::WebviewWindowtype. - Moved
tauri::api::pathmodule totauri::path - Moved all functions from
tauri::api::pathto be methods ontauri::path::PathResolver - Renamed
system-trayfeature flag totray-icon. - Changed
tauri::App::handleandtauri::Manager::app_handlemethods to return a reference to anAppHandleinstead of an owned value. - Changed
tauri::Builder::register_uri_scheme_protocolto return ahttp::Responseinstead ofResult<http::Response>. To return an error response, manually create a response with status code >= 400. - The custom protocol on Windows and Android now uses the
httpscheme instead ofhttps. - Changed
tauri::Env.argstotauri::Env.args_osand now usesOsStringinstead ofString - Changed
TAURI_AUTOMATIONenv var toTAURI_WEBVIEW_AUTOMATION - Changed
tauri::Builder::invoke_systemto take references instead of owned values. - Changed
tauri::Builder::invoke_system,tauri::Builder::on_page_loadhooks to take atauri::Webviewargument instead of atauri::Window. - Moved the
tauri::commandmodule items to thetauri::ipcmodule so its import name does not clash with thetauri::commandmacro. - Changed
tauri::App::run_iterationto take a callback and removed its return value. - Changed
AppHandle::exitandAppHandle::restartto triggerRunEvent::ExitRequestedandRunEvent::Exit - Renamed
tauri::WebviewWindowBuilder::owner_windowtotauri::WebviewWindowBuilder::owner_rawandtauri::WebviewWindowBuilder::parent_windowtotauri::WebviewWindowBuilder::parent_raw. - Renamed the
window-data-urlfeature flag towebview-data-url. - Changed
tauri::WebviewWindow::closeto trigger a close requested event instead of forcing the window to be closed. Usetauri::WebviewWindow::destroyto force close. - Renamed
icon-icoandicon-pngfeature flags toimage-icoandimage-pngrespectively. - Removed
tauri::Iconenum, use the newtauri::Imagetype instead. All APIs that previously acceptedtauri::Iconhave changed to accepttauri::Imageinstead. - Changed
tauri::Contextstruct andtauri::Assetstrait to have aR: Runtimegeneric. - Renamed
tauri::Context::assets_muttotauri::Context::set_assets - Changed
tauri::Contexttype to not have<A: Assets>generic so the assets implementation can be swapped withContext::set_assets. - Changed
tauri::Context::assetsto return&dyn Assetsinstead of&Ageneric. - Renamed
tauri::FileDropEventenum totauri::DragDropEventand renamed its variants. Also renamed the js events - Renamed
tauri::WindowEvent::FileDropenum variant totauri::WindowEvent::DragDrop - Renamed file drop emitted events to
tauri://drag-enter,tauri://drag-over,tauri://drag-drop, andtauri://drag-leave - Renamed
tauri::WebviewWindow::disable_file_drop_handlertotauri::WebviewWindow::disable_drag_drop_handler. - Changed
tauri::WebviewWindow::urlgetter to return a result. - Changed
tauri::Env.args_os, to include the binary path, previously it was skipped. - Renamed
getAllandgetCurrenttogetAllWindowsandgetCurrentWindowin the JSwindowmodule but you probably wantgetAllWebviewWindowsandgetCurrentWebviewWindowfrom thewebviewWindowmodule.
Removed
- The
reqwest-*Cargo features were removed UpdaterEvent- Removed
tauri::apimodule and moved them into standalone plugins inplugins-workspacerepo. - Removed
tauri::scope::IpcScope - Removed
tauri::scope::ipcmodule and all its types. - Removed
tauri::scope::FsScope, usetauri::scope::fs::Scope - Removed
tauri::scope::GlobPattern, usetauri::scope::fs::Pattern - Removed
tauri::scope::FsScopeEvent, usetauri::scope::fs::Event - Removed
tauri::scope::HttpScope - Removed
tauri::scope::ShellScope - Removed
tauri::scope::ShellScopeAllowedCommand - Removed
tauri::scope::ShellScopeAllowedArg - Removed
tauri::scope::ExecuteArgs - Removed
tauri::scope::ShellScopeConfig - Removed
tauri::scope::ShellScopeError - Removed
linux-protocol-headerscargo feature flag, now enabled by default. - Removed
tauri::path::Errorandtauri::path::Resultand added its variants totauri::Error - Removed
tauri::path::Resultandtauri::plugin::Resultaliases, you should usetauri::Resultor your ownResulttype. - Changed
tauri::Builder::on_page_loadhandler to take references. The page load hook is now triggered for load started and finished events, to determine what triggered it seetauri::PageLoadPayload::eventfield. - Removed
tauri::GlobalWindowEventstruct, and unpacked its fields to be passed directly totauri::Builder::on_window_event. - Removed
tauri::EventHandlertype. - Renamed
tauri::Context::default_window_icon_muttotauri::Context::set_default_window_iconand changed it to acceptOption<T>.
Config restructure
Restructured Tauri config per RFC#5:
- Moved
package.productName,package.versionandtauri.bundle.identifierfields to the top-level. - Removed
packageobject. - Renamed
tauriobject toapp. - Moved
tauri.bundleobject to the top-level. - Renamed
build.distDirfield tofrontendDist. - Renamed
build.devPathfield todevUrland will no longer accepts paths, it will only accept URLs. - Moved
tauri.patterntoapp.security.pattern. - Removed
tauri.bundle.updaterobject, and its fields have been moved to the updater plugin underplugins.updaterobject. - Moved
build.withGlobalTauritoapp.withGlobalTauri. - Moved
tauri.bundle.dmgobject tobundle.macOS.dmg. - Moved
tauri.bundle.debobject tobundle.linux.deb. - Moved
tauri.bundle.appimageobject tobundle.linux.appimage. - Removed all license fields from each bundle configuration object and instead added
bundle.licenseandbundle.licenseFile. - Renamed
AppUrltoFrontendDistand refactored its variants to be more explicit. - Renamed
tauri.window.fileDropEnabeldtoapp.window.dragDropEnabled
Migration
As we try to make the migration from previous Tauri versions as smooth as possible, we have documentation available to guide you through the process.
If you are migrating from a 1.x release please check out this migration guide.
For upgrading from a 2.0 beta or release candidate version check out this migration guide.
The Tauri v2 CLI includes a migrate command that automates most of the process and helps you finish the migration:
-
npm
npm install @tauri-apps/cli@next npm run tauri migrate -
yarn
yarn upgrade @tauri-apps/cli@next yarn tauri migrate -
pnpm
pnpm update @tauri-apps/cli@next pnpm tauri migrate -
cargo
cargo install tauri-cli --version "^2.0.0" --locked cargo tauri migrate
Rust Migration
We can not automatically migrate your Rust code, so make sure to go through the documentation and rust docs of the 2.0 version.
Call To Action
If you are familiar with Tauri and have used it already during your journey, please take your time to check out the Github Discussions, Github Issues. Maybe you have already solved the issues your fellow newcomers to Tauri are experiencing right now.
If you think that some of these problems you have seen are generic and should be documented somewhere we probably have the perfect place for it in our official documentation.
To contribute improvements or additions we are open for PRs in the tauri-docs repository. Please make sure you’ve read the guidelines for contribution though.
If you are in the position to understand and translate the current documentation into your native language we appreciate content translations to our documentation.
The repositories surrounding Tauri are also looking for contributors, especially we would love more maintainers and contributors to the plugin-workspace.
The plugins are now a major part of the development and user experience of Tauri and all kind of help is welcome there. From discussing new plugin ideas, collaborating with others to write new plugins, contributing PRs to fix bugs in existing plugins or documenting weird workarounds and knowledge in the plugin readme or code.
Roadmap
You probably expect solid plans for the future and new cool ideas from us. We currently have some in mind but have not committed to a roadmap beyond 2.x yet.
We mainly want to focus on improving this major version with a better developer experience, better documentation and less impactful bugs. We want to improve especially the mobile development experience and make the whole flow from idea to published application as seamless as possible.
Things on our radar for the future we feel we should mention at least:
- Providing or Bundling Chromium Embedded Framework (CEF) for Linux as an alternative to WebKit2GTK
- Servo as Tauri WebView (POC in Wry)
If you want to collaborate on these ideas, please let us know and we will figure it out together.
Tauri Board Elections 2024
The Tauri Programme is celebrating its third anniversary of Tauri becoming a programme within The Commons Conservancy. We are hard at work bringing v2 to a stable release, and now the next round of Tauri Board Director elections is upon us! Want to get involved in other ways and help Tauri towards v2? We would love your contributions especially to help evolve the documentation!
Board Elections
The Tauri Board of Directors is the central decision-making body for the Tauri Programme and is responsible for its overall health and stability. Additional details can be found on the Tauri Governance page.
In order to provide continuity from one year to another, the elections of seats are staggered over the course of 2 years. This means that one year a portion of the seats are elected, and the following year the remaining seats are elected. A Tauri Director seat is an elected position with a term of 2 years. The Board has a minimum of 3 Directors and a maximum of 7. This year there are 2 seats open for election.
Applying for Candidacy
There are 3 steps to express interest and apply for candidacy:
- Learn about the role of a Tauri Board Director on the Governance page.
- Prepare a written introduction about yourself that covers who you are, your history and relevance for Tauri, and what you would like to bring to the Board.
- Apply prior to July 5th, 2024 by emailing board@tauri.app, messaging the
@boardrole on the Tauri Discord, or by directly messaging Jacob Bolda on Discord (@jacobbolda) or email (jacob@tauri.app).
Voting will take place starting on July 7th through July 12th, 2024 where Tauri Working Group Members will cast their votes. We’re expecting to announce the results on or before July 16, 2024. If elected, we’ll ask you to sign this pledge if you haven’t done so previously.
If you have any questions or would like more information please reach out by emailing board@tauri.app, messaging the @board role on the Tauri Discord, or by directly messaging Jacob Bolda on Discord (@jacobbolda) or email (jacob@tauri.app).
Interested In Getting Involved?
If joining the Board isn’t for you, we are always looking to enable involvement at any level within Tauri. The documentation for v2 is a large focus of the remaining effort. See the issues within the tauri-apps/tauri-docs repo. Additionally reach out and follow along within Discord. Add a @notify-* role to stay apprised of news and questions from the team, or follow along and ask questions in the #dev or #docs channels under the CONTRIBUTORS section.
Prepared for some more responsibility? A Domain in the Working Group represents a specific area of interest.
- Development: Developing and maintaining the Tauri software
- Community: Looks after the broader community resources and the public presence of Tauri
- Governance & Guidance: Involved with all things organizational in nature
- Operations: Responsible for all the tooling and infrastructure Tauri needs to get work done
This gives clear entry points for a new member of the Working Group to jump into right away. It also allows us to continue growing our core competency of core Tauri development while giving additional focus to all areas which support the Tauri organization as a whole. Each of these domains will be represented by Domain Members and Domain Leads, but membership is not mutually exclusive.
All domains within Tauri are equally important to providing the best experience possible, as well as the wonderful support of the community. ❤️
With your help, we can continue to improve and catalyze the growth and sustainability of the organization. You can learn more in the Governance and Guidance repo on GitHub.
Tauri Board Elections 2025
As we continue to be amazed by all the applications you’ve created with Tauri v2, it’s been 4 years since Tauri has become a Programme within The Commons Conservancy! This means we’re preparing for a new round of Tauri Board Director elections for the next term.
Board Elections
The Tauri Board of Directors is the central decision-making body for the Tauri Programme and is responsible for its overall health and stability. Additional details can be found at the Tauri Governance page.
In order to provide continuity from one year to another, the elections of seats are staggered over the course of 2 years. This means that one year a portion of the seats are elected, and the following year the remaining seats are elected. A Tauri Director seat is an elected position with a term of 2 years. The Board has a minimum of 3 Directors and a maximum of 7.
This year there are 5 seats open for election.
Applying for Candidacy
There are 3 steps to express interest and apply for candidacy:
- Learn about the role of a Tauri Board Director on the Governance page.
- Prepare a written introduction about yourself that covers who you are, your history and relevance to Tauri, and what you would like to bring to the Board. (Examples from previous years can be found at https://github.com/tauri-apps/governance-and-guidance).
- Apply prior to July 7th, 2025 by emailing board@tauri.app or messaging the
@boardrole on the Tauri Discord.
Voting will take place starting on July 7th through July 14th, 2025 where Tauri Working Group Members will cast their votes. We’re expecting to announce the results on or before July 19, 2025. If elected, we’ll ask you to sign this pledge if you haven’t done so previously.
If you have any questions or would like more information please reach out by emailing board@tauri.app, messaging the @board role on the Tauri Discord.
Interested In Getting Involved?
If joining the Board isn’t for you but still want to help, here are some ways to do so! (Thank you ❤️)
Reach out on our Discord by enabling the roles you’re interested in like “Contribute to Tauri Code” or “Contribute to Documentation”. This reveals the Contributors channels where you can chat with other contributors. While you’re there, consider enabling Discord notification roles to stay apprised of news and questions from the team.
Or on GitHub maybe you can help with these good first issues?
Additionally we’re very grateful to all the teams and individuals who sponsor us on GitHub or open collective!
Tauri Board Elections 2026
As we continue to be amazed by all the applications you’ve created with Tauri v2, it’s been 5 years since Tauri has become a Programme within The Commons Conservancy! This means we’re preparing for a new round of Tauri Board Director elections for the next term.
Board Elections
The Tauri Board of Directors is the central decision-making body for the Tauri Programme and is responsible for its overall health and stability. Additional details can be found at the Tauri Governance page.
In order to provide continuity from one year to another, the elections of seats are staggered over the course of 2 years. This means that one year a portion of the seats are elected, and the following year the remaining seats are elected. A Tauri Director seat is an elected position with a term of 2 years. The Board has a minimum of 3 Directors and a maximum of 7.
This year there are 3 seats open for election.
Applying for Candidacy
There are 3 steps to express interest and apply for candidacy:
- Learn about the role of a Tauri Board Director on the Governance page.
- Prepare a written introduction about yourself that covers who you are, your history and relevance to Tauri, and what you would like to bring to the Board. (Examples from previous years can be found at https://github.com/tauri-apps/governance-and-guidance).
- Apply prior to July 7th, 2026 by emailing board@tauri.app or messaging the
@boardrole on the Tauri Discord.
Voting will take place starting on July 7th through July 14th, 2026 where Tauri Working Group Members will cast their votes. We’re expecting to announce the results on or before July 19, 2026. If elected, we’ll ask you to sign this pledge if you haven’t done so previously.
If you have any questions or would like more information please reach out by emailing board@tauri.app, messaging the @board role on the Tauri Discord.
Interested In Getting Involved?
If joining the Board isn’t for you but still want to help, here are some ways to do so! (Thank you ❤️)
Reach out on our Discord by enabling the roles you’re interested in like “Contribute to Tauri Code” or “Contribute to Documentation”. This reveals the Contributors channels where you can chat with other contributors. While you’re there, consider enabling Discord notification roles to stay apprised of news and questions from the team.
Or on GitHub maybe you can help with these good first issues?
Additionally we’re very grateful to all the teams and individuals who sponsor us on GitHub or open collective!
Tauri Board Elections & Governance Update
The Tauri Programme is celebrating it’s two year anniversary of Tauri becoming a programme within The Commons Conservancy as well as the one year milestone of the Tauri 1.0 release. This also means we’re preparing for the next round of Tauri Board Director elections to welcome in the next chapter of Tauri.
We wanted to celebrate these milestones but also use this as a chance to reflect on how we’ve grown since the Tauri 1.0 launch and how to continue evolving Tauri. The Tauri Working Group has been building the next iteration of the governance model for the past several months to make it more accessible for new and existing contributors, and ultimately sustainable for the future of Tauri.
Board Elections
The Tauri Board of Directors is the central decision-making body for the Tauri Programme and is responsible for the overall health and stability of the Tauri Programme. Additional details can be found on the Tauri Governance page.
In order to provide continuity from one year to another, the elections of seats are staggered over the course of 2 years. This means that one year a portion of the seats are elected, and the following year the remaining seats are elected. A Tauri Director seat is an elected position with a term of 2 years. The Board has a minimum of 3 Directors and a maximum of 7. This year there are 5 seats open for election.
Diversity
This year we’d like to focus on diversifying the Tauri Board. We’re looking for candidates that may be a developer who’s worked on Tauri, a stakeholder in Tauri’s future, experienced individuals from industry, or a person with a passion for regulatory and legal aspects within open source. If any or all of these are of interest to you then we’d invite you to apply as a candidate.
Applying for Candidacy
There are 3 steps to express interest and apply for candidacy:
- Learn about the role of a Tauri Board Director on the Governance page.
- Prepare a written introduction about yourself that covers who you are, your history and relevance for Tauri, and what you would like to bring to the Board.
- Apply prior to July 2nd, 2023 by emailing board@tauri.app, messaging the
@boardrole on the Tauri Discord, or by directly messaging Daniel Thompson-Yvetot on Discord (@Denjell) or email (denjell@tauri.app).
Voting will take place starting on July 5th through July 12th, 2023 where Tauri Working Group Members will cast their votes. We’re expecting to announce the results on or before July 16, 2023. If elected, we’ll ask you to sign this pledge if you haven’t done so previously.
If you have any questions or would like more information please reach out by emailing board@tauri.app, messaging the @board role on the Tauri Discord, or by directly messaging Daniel Thompson-Yvetot on Discord (@Denjell) or email (denjell@tauri.app).
Governance Update
Tauri has always had a Working Group that’s responsible for the day-to-day direction and execution, but as we grew it became clear that we needed to evolve the Working Group. We also wanted to give new Working Group members a clear places to jump in and get started. We thought of how we could achieve this while building and iterating on the existing framework. With these goals in mind, we created two new concepts within the Working Group: Domains and Domain Leads.
Domains
A Domain in the Working Group represents a specific area of interest. We’re starting with these 4 domains:
- Development: Developing and maintaining the Tauri software
- Community: Looks after the broader community resources and the public presence of Tauri
- Governance & Guidance: Involved with all things organizational in nature
- Operations: Responsible for all the tooling and infrastructure Tauri needs to get work done
This gives clear entry points for a new member of the Working Group to jump into right away. It also allows us to continue growing our core competency of core Tauri development while giving additional focus to all areas which support the Tauri organization as a whole. Each of these domains will be represented by Domain Members and Domain Leads, but membership is not mutually exclusive.
Domain Leads
Within a domain, there is a position for 2-3 Domain Leads. These are core individuals in the Working Group that are critical to their respective Domain. They help by setting the direction and priorities for their domain while also serving as key leaders for the Working Group as a whole.
Leads are appointed twice a year, in the spring and in the fall. Since this governance update is being rolled out mid-term we’re appointing interim leads that have been key members of the Working Group. This fall we’ll reflect on the initial experience and host a new round to appoint the Domain Leads. We’ll announce information for that process when we’re closer to “appointment season”.
We hope that these changes provide the foundation to continue the journey the Tauri Working Group has been on while also catalyzing the continued growth and sustainability of the organization. You can learn more about these updates in the Governance and Guidance repo on GitHub. Give us your feedback on the GitHub Discussion for this post.
Tauri Community Growth & Feedback
Tauri has had an amazing past year. We launched Tauri 1.0, announced the alpha version of Tauri Mobile and gathered a lot of valuable feedback from our community and users in the 2022 Tauri Community Survey.
Tauri Community Survey Results
This year, we had over 600 responses to the Tauri Community Survey (over 3x more than the previous survey’s responses). We’d like to extend a very special thank you to Wu Yu Wei and DK Liao for translating the survey from English into Simplified and Traditional Chinese so that we could include more people from the community and their feedback in the survey. You can download the public data for the survey here.
We’ve heard your feedback and have started a couple of projects to directly address it. The first one we’d like to talk about is search.
Search Improvements on Tauri.app
Without searching, can you ever find something? And if your telescope is cracked, can you see the planets or stars? We know that our search lens was dusty and scratched; it felt sometimes like a roll of the dice, and some folks even resorted to using ChatGPT to find answers.
Search has been a project that we’ve taken a few runs at over the years, but we’ve also learned that it’s not quite as easy as it first seems. Ken from the Tauri Working Group did inspirational work with the previous tauri-search project. He created a lot of the foundation and research in the previous project for us to understand what goes into search.
With the next iteration of search, we had three goals in mind:
- Keep it maintainable
- Keep it working
- Keep it open source
Search Engine
First, we needed to choose a backend search engine to store and serve the search index. When evaluating search engines, we wanted to make sure we used something that shared our values of open source software and a small footprint. After comparing and researching players in the search market (and also learning from our previous approach with Meilisearch), we decided on Meilisearch because we knew it fit both of those goals.
Meilisearch have a passion for open source software and even has their search engine built in Rust which has a tiny footprint and great performance. They’ve recently announced Meilisearch 1.0 and now also have a cloud offering for those who would like a managed instance.
We decided to partner up with Meilisearch to use their engine and their Meilisearch Cloud offering to host our search engine. They graciously sponsored a hosted plan that they manage for us. This lets us focus on building Tauri, knowing that the maintenance and upkeep of the search engine are in trusted hands.
Search Ingestion & Indexing
The next piece of the puzzle is to actually get the content indexed and ingested into the search engine. Fabian from the Tauri Working Group set up the project using the docs-scraper project from Meilisearch.
Previously, we had a setup that would take our markdown documentation and JavaScript AST and use that to build the search index. Although it led to much faster indexing times, it meant we had a tightly coupled dependency between search indexing and the way we rendered content on our website. This would sometimes lead to the search results getting out of sync with the content on the live website. In order to update the website or optimize the indexer, someone would need to have knowledge of both, making it more difficult to maintain.
With the current version of the scraper, we can handle all of the configuration and tweaking of results with a single JSON file and let the scraper take care of the rest. We set up a GitHub action that would perform the scraping as part of our CI/CD pipeline and then send those results to our Meilisearch Cloud instance.
Search Frontend
The final step was to create the frontend UI that people visiting tauri.app would interact with. Amr from the Tauri Working Group created the meilisearch-docsearch project to help with this. This repo is compatible with Meilisearch 1.0 (we’re using it now on tauri.app).
It’s inspired by the algolia/docsearch and meilisearch/docs-searchbar.js projects that provided a very solid foundation to begin with. The beauty of open source is that we can learn from each other and use that to give back to the ecosystem.
To talk through some of the details, I’ll hand it over to Amr:
The meilisearch/docs-searchbar.js project was good, but I always felt it could use some improvements to get feature parity with algolia/docsearch. I also felt we could help with an update to help with UI/UX.
The main pain points with meilisearch/docs-searchbar.js were:
- On mobile screens, it needed UI/UX improvements so that the search results wouldn’t go off-screen.
- On desktop, the search results would normally appear under the search input, which in the case of tauri.app was placed on the top-right. This caused a bad UX because you’d have to keep moving your eyes between the page content in the middle and the search results in the top-right.
- It is missing a common keybinding.
ctrl/command + Kto start the search,ctrl/command + Kis pretty common in the JS ecosystem documentation sites. It also doesn’t have the ability to select text on the page and then trigger a search directly from that text.
I have been always a big fan of algolia/docsearch UI/UX. It checked all the features on my list, and I always wanted to have that for tauri.app. In fact, several months ago, I tried to change the meilisearch/docs-searchbar.js CSS on our end to improve point 1 and 2 above but I stopped mid-way because of the difficulty of building on top of existing css and fighting for highest specifity (plus CSS is hard 😉). Other projects also couldn’t benefit from our modifications in an easy way.
Later, we were discussing how to improve the search UI and UX, and we decided that we could improve on the base Meilisearch UI. That project turned into meilisearch-docsearch.
Seeing It In Action
The good news is that all of these changes are live! You can see the new search on tauri.app. We’d love to hear your feedback on what works and what could use improvement in the GitHub Discussion for this blog post. We invite you to not only report bugs, but also if your search result wasn’t expected or should be higher up on the list of results.
We’d like to wrap up by extending a special thank you to Ken for the original Tauri Search project, Amr for the meilisearch-docsearch project, Fabian for writing the revised index scraper and continuous testing, Meilisearch for their partnership and the Meilisearch Cloud instance and finally the Tauri community for their continual feedback to help us drive Tauri and the community forward.
Next Steps
Over the next year, the Tauri Working Group is excited to continue working towards Tauri 2.0. We also have a website rewrite in the works that we’ll be launching in beta this spring. If you’d like to get involved, you can reach out to us in the Tauri Discord and follow us on Mastodon and Twitter.
Announcing tauri-egui 0.1.0
The Tauri team is pleased to announce the first release of tauri-egui.
egui is a GUI library written in Rust. It leverages an OpenGL context via glutin.
tauri-egui is a Tauri plugin that connects with the Tauri runtime event loop to allow you to create glutin windows via our glutin fork and use egui through our egui-tao integration.
Setup
The first step is to add the crate to your dependencies in Cargo.toml:
[dependencies]
tauri-egui = "0.1"
Now you need to enable the plugin:
fn main() {
tauri::Builder::default()
.setup(|app| {
app.wry_plugin(tauri_egui::EguiPluginBuilder::new(app.handle()));
Ok(())
})
}
Create an egui layout
To use egui, all you need to do is implement the tauri_egui::eframe::App trait to render elements using the egui API. In the following example, we will create a login layout.
- Define the struct that will be used to render the layout:
use std::sync::mpsc::{channel, Receiver, Sender};
use tauri_egui::{eframe, egui};
pub struct LoginLayout {
heading: String,
users: Vec<String>,
user: String,
password: String,
password_checker: Box<dyn Fn(&str) -> bool + Send + 'static>,
tx: Sender<String>,
texture: Option<egui::TextureHandle>,
}
impl LoginLayout {
pub fn new(
password_checker: Box<dyn Fn(&str) -> bool + Send + 'static>,
users: Vec<String>,
) -> (Self, Receiver<String>) {
let (tx, rx) = channel();
let initial_user = users.iter().next().cloned().unwrap_or_else(String::new);
(
Self {
heading: "Sign in".into(),
users,
user: initial_user,
password: "".into(),
password_checker,
tx,
texture: None,
},
rx,
)
}
}
- Implement
tauri_egui::eframe::Appto use the egui APIs:
impl eframe::App for LoginLayout {
// Called each time the UI needs repainting
// see https://docs.rs/eframe/latest/eframe/trait.App.html#tymethod.update for more details
fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
let Self {
heading,
users,
user,
password,
password_checker,
tx,
..
} = self;
let size = egui::Vec2 { x: 320., y: 240. };
// set the window size
frame.set_window_size(size);
// adds a panel that covers the remainder of the screen
egui::CentralPanel::default().show(ctx, |ui| {
// our layout will be top-down and centered
ui.with_layout(egui::Layout::top_down(egui::Align::Center), |ui| {
// we will start adding elements here in the next sections
});
});
}
}
- Define some helper functions we will use:
fn logo_and_heading(ui: &mut egui::Ui, logo: egui::Image, heading: &str) {
let original_item_spacing_y = ui.style().spacing.item_spacing.y;
ui.style_mut().spacing.item_spacing.y = 8.;
ui.add(logo);
ui.style_mut().spacing.item_spacing.y = 16.;
ui.heading(egui::RichText::new(heading));
ui.style_mut().spacing.item_spacing.y = original_item_spacing_y;
}
fn control_label(ui: &mut egui::Ui, label: &str) {
let original_item_spacing_y = ui.style().spacing.item_spacing.y;
ui.style_mut().spacing.item_spacing.y = 8.;
ui.label(label);
ui.style_mut().spacing.item_spacing.y = original_item_spacing_y;
}
- Load an image, allocate it as a texture and add it to the UI (requires the
pngdependency):
let texture: &egui::TextureHandle = self.texture.get_or_insert_with(|| {
let mut reader = png::Decoder::new(std::io::Cursor::new(include_bytes!("icons/32x32.png")))
.read_info()
.unwrap();
let mut buffer = Vec::new();
while let Ok(Some(row)) = reader.next_row() {
buffer.extend(row.data());
}
let icon_size = [reader.info().width as usize, reader.info().height as usize];
// Load the texture only once.
ctx.load_texture(
"icon",
egui::ColorImage::from_rgba_unmultiplied(icon_size, &buffer),
egui::TextureFilter::Linear,
)
});
logo_and_heading(
ui,
egui::Image::new(texture, texture.size_vec2()),
heading.as_str(),
);
- Add the user selection ComboBox:
ui.with_layout(egui::Layout::top_down(egui::Align::Min), |ui| {
control_label(ui, "User");
egui::ComboBox::from_id_source("user")
.width(ui.available_width() - 8.)
.selected_text(egui::RichText::new(user.clone()).family(egui::FontFamily::Monospace))
.show_ui(ui, move |ui| {
for user_name in users {
ui.selectable_value(user, user_name.clone(), user_name.clone());
}
})
.response;
});
- Add an entry for password input:
ui.style_mut().spacing.item_spacing.y = 20.;
let textfield = ui
.with_layout(egui::Layout::top_down(egui::Align::Min), |ui| {
ui.style_mut().spacing.item_spacing.y = 0.;
control_label(ui, "Password");
ui.horizontal_wrapped(|ui| {
let field = ui.add_sized(
[ui.available_width(), 18.],
egui::TextEdit::singleline(password).password(true),
);
field
})
.inner
})
.inner;
- Add a submit button:
let mut button = ui.add_enabled(!password.is_empty(), egui::Button::new("Unlock"));
button.rect.min.x = 100.;
button.rect.max.x = 100.;
- Handle submit:
if (textfield.lost_focus() && ui.input().key_pressed(egui::Key::Enter)) || button.clicked()
{
if password_checker(&password) {
let _ = tx.send(password.clone());
password.clear();
frame.close();
} else {
*heading = "Invalid password".into();
textfield.request_focus();
}
}
Now that we have created the layout, let’s put it on a window and show it in the Tauri application:
use tauri::Manager;
fn main() {
tauri::Builder::default()
.setup(|app| {
app.wry_plugin(tauri_egui::EguiPluginBuilder::new(app.handle()));
// the closure that is called when the submit button is clicked - validate the password
let password_checker: Box<dyn Fn(&str) -> bool + Send> = Box::new(|s| s == "tauri-egui-released");
let (egui_app, rx) = LoginLayout::new(
password_checker,
vec!["John".into(), "Jane".into(), "Joe".into()],
);
let native_options = tauri_egui::eframe::NativeOptions {
resizable: false,
..Default::default()
};
app
.state::<tauri_egui::EguiPluginHandle>()
.create_window(
"login".to_string(),
Box::new(|_cc| Box::new(egui_app)),
"Sign in".into(),
native_options,
)
.unwrap();
// wait for the window to be closed with the user data on another thread
// you don't need to spawn a thread when using e.g. an async command
std::thread::spawn(move || {
if let Ok(signal) = rx.recv() {
dbg!(signal);
}
});
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application")
}
Here’s how it will look on all platforms:
To customize the look and feel of your egui application, check out the Context#set_style API.
Announcing the Tauri Mobile Alpha Release
Tauri mobile is here! The first alpha release 2.0.0-alpha.0 has been published.
Updating dependencies
Make sure to update both NPM and Cargo dependencies to the 2.0.0-alpha.0 release. You can update the dependencies with:
-
npm
npm install @tauri-apps/cli@next @tauri-apps/api@next -
yarn
yarn upgrade @tauri-apps/cli@next @tauri-apps/api@next -
pnpm
pnpm update @tauri-apps/cli@next @tauri-apps/api@next -
cargo
cargo add tauri@2.0.0-alpha.0 cargo add tauri-build@2.0.0-alpha.0 --build cargo install tauri-cli --version "^2.0.0-alpha" --locked
Preview
You can adapt your existing desktop application to run on mobile or start a fresh project. Tauri runs on the connected device or starts an emulator if available.
Getting started
Read the complete guide on the next documentation website.
Known issues
- TLS support has been moved behind a Cargo feature until we figure out how to cross compile OpenSSL on Windows.
- Currently running on a device is not supported when using Xcode 14.
Tauri Programme Turns 1 and Board Elections
The one year anniversary for Tauri becoming a programme within The Commons Conservancy is upcoming on the 16th of July! On that anniversary, two of our Directors on the Tauri Board will be at the end of their first half-term. The Board will hold an election on the 15th of July to decide the Directors for the next two year term.
The Tauri Board has a minimum of three, and a maximum of seven people. Right at the start we’ve had seven people come on board. Meaning we can’t add any more people during this election. So if you’re applying it means you’ll compete with the two project founders for a seat on the Tauri Board.
Honestly those are big shoes to fill! So to avoid unnecessary disappointment, in this election we decided to add a requirement: You must be currently part of a working group to apply as a candidate.
If you’re still with me, then here are some additional details:
- Please notify the board before July 15th 00:00 UTC if you would like to apply as a candidate.
- You can mention
@boardon Discord, or DMBeanow#5887if you want your application to be kept private within the Board. - Optionally, you can include a short motivation for your application.
- If there are multiple candidates, the Tauri Board will vote for their preferred candidates.
- The Directors running for office again will have half a vote deducted from votes in their favor (one for each consecutive term served).
- After voting on July 15th we’ll share the results.
All this is governed by our statutes and core regulations if you’re interested in seeing the fine print.
We’ll be back soon with an update.
Update: Election results
The results are in, so here is the reveal!
The existing Directors applied for another term and there were no additional applicants. Meaning no vote was necessary to select between candidates. For the Chair position Daniel ran as the only candidate.
The Tauri Board then voted unanimously in favor of the following:
- The Board appoints Daniel and Lucas for an additional full term (2 years) as Board Directors, starting the 16th of July.
- The Board appoints Daniel as Chairperson for the next term (1 year), starting the 16th of July.
Another election will be held around the same time July next year, now with extra time to apply and for the Board to vote. We’ll announce the specifics in due time.
Experimental Tauri Verso Integration
What is Verso?
So first off, what is Verso? Verso is a browser based on Servo, a web browser rendering engine written in Rust
Why using Verso instead of Servo directly?
I believe there’re quite a lot of people having thought about using Servo but got intimidated by the complex APIs and just gave up, which frankly I was one of them, so the goal of building the Verso webview is to make it easy enough to understand and use so that people will actually start to experiment and use it
Servo itself is made to be relatively easy to embed compared to other browsers, but the APIs are still way too low level and it’s quite daunting to use, you can take a look at the minimal example for running Servo with Winit at (note this is not even a fully functional example): https://github.com/servo/servo/blob/8d39d7706aee50971e848a5e31fc6bfd7ef552c1/components/servo/examples/winit_minimal.rs
And compared to that, Verso’s API looks like this, which is much easier and ergonomic to use
use std::env::current_exe;
use std::thread::sleep;
use std::time::Duration;
use url::Url;
use verso::VersoBuilder;
fn main() {
let versoview_path = current_exe().unwrap().parent().unwrap().join("versoview");
let controller = VersoBuilder::new()
.with_panel(true)
.maximized(true)
.build(versoview_path, Url::parse("https://example.com").unwrap());
loop {
sleep(Duration::MAX);
}
}
It’s not to say Servo’s API is bad though, as they need to support a lot more use cases while we just need it for building applications with Tauri
tauri-runtime-verso
So let’s talk about the integration with Tauri!
We choose to integrate Verso and Tauri through a new custom runtime tauri-runtime-verso for this time, this is similar to our default runtime tauri-runtime-wry.
With this approach, you can easily swap out the runtime and use Tauri like what you’ll normally do:
use tauri_runtime_verso::{
INVOKE_SYSTEM_SCRIPTS, VersoRuntime, set_verso_path, set_verso_resource_directory,
};
fn main() {
// You need to set this to the path of the versoview executable
// before creating any of the webview windows
set_verso_path("../verso/target/debug/versoview");
// Set this to verso/servo's resources directory before creating any of the webview windows
// this is optional but recommended, this directory will include very important things
// like user agent stylesheet
set_verso_resource_directory("../verso/resources");
tauri::Builder::<VersoRuntime>::new()
// Make sure to do this or some of the commands will not work
.invoke_system(INVOKE_SYSTEM_SCRIPTS.to_owned())
.run(tauri::generate_context!())
.unwrap();
}
Just note that it’s not as feature rich and powerful as the current backends used by Tauri in production yet, but it still has a lot to it, and we have built an example show casing it at https://github.com/versotile-org/tauri-runtime-verso/tree/main/examples/api
Features you can see from the video:
- We have all the functions the
tauri-cliprovides - We’re using a modern framework, in this case
React - We have our official log and opener plugins, they work exactly the same as if you’re using Tauri with the other backends
- Windowing functions work, including size, position, maximize, minimize, close, …
Vite’s css hot reload works as well- The
data-tauri-drag-regionattribute works
Future works
Right now, Verso and tauri-runtime-verso are still in active development so we’ll need to see as we go, but we do have something planned to do next
Pre-built Verso executable
Releasing an easy to use pre-built Verso executable to help people get started with it quicker and easier, as currently you need to compile Verso yourself to get started
Also if possible, as a long term goal, we would like an evergreen shared Verso, similar to WebView2 on Windows which you would place it on the system and it would update itself automatically, and shared between multiple apps so you don’t have to ship the browser inside your app to reduce the bundle size significantly
More windowing and webview features support
We currently only support a small subset of features in Tauri, and we would like to expand this to include more things, and we have currently planned to support window decorations, window titles and transparency
Initialization script without temporary files
Currently Servo can only take an userscript directory to run on document start which is ok but for the Tauri’s use case, we would like to do this programmatically without the help of files, as that could result in left over temporary files that we never clean up
We have a PR merged in Servo just a few days ago and we should just need to use in Verso and then the tarui-runtime-verso so this is a coming soon!
Customization unique to the Verso runtime
Tauri is largely made with the assumption of the underlying webview libraries, so there’re very little ways to use many Verso specific futures right now, for example, setting the verso executable path and resources directory are being done through global variables, which is not really applicable to window specific features (for example setting rounded corners), so we would like to add support for that next
Thank you
At the end we want to thank NLNet for making this project possible by supporting it financially through grants!
Create Tauri app
-
Bash
sh <(curl https://create.tauri.app/sh) -
PowerShell
irm https://create.tauri.app/ps | iex -
Fish
sh (curl -sSL https://create.tauri.app/sh | psub) -
npm
npm create tauri-app@latest -
Yarn
yarn create tauri-app -
pnpm
pnpm create tauri-app -
deno
deno run -A npm:create-tauri-app -
bun
bun create tauri-app -
Cargo
cargo install create-tauri-app --locked cargo create-tauri-app






































