Skip to content

Tauri v2 with Auto-Updater

Let’s setup auto-updates with Tauri v2. For this guide, you will need a working Tauri project (v2), in a GitHub repository and integrated with CrabNebula Cloud. If you haven’t done that yet, the Publish Tauri with GitHub Actions guide will help you.

Required Dependencies

crate namedescriptionversion
tauri-plugin-updaterTauri plugin for auto-updates^2.0.0
tauri-plugin-dialogTauri plugin for dialogs^2.0.0
tauri-plugin-processTauri plugin for handling processes like app relaunch^2.0.0

To add them with cargo you can run:

cargo add tauri-plugin-updater tauri-plugin-dialog

Tauri Capabilities

Before starting to implement auto-updates, some capabilities must be enabled in your app. Usually capabilities are under /src-tauri/capabilities/main.json, adjust accordingly if your setup diverged from the defaults. Finally, add the necessary permissions so they match the JSON below:

/src-tauri/capabilities/main.json
{
"identifier": "main",
"description": "permissions for desktop app",
"local": true,
"windows": ["main"],
"permissions": [
"dialog:default",
"updater:default",
"process:default",
"process:allow-restart"
]
}

Secret and Public Keys

To secure auto-updates, you need to generate a secret and public key pair. You can use the tauri-plugin-updater CLI to generate them:

npm run tauri signer generate -- -w ~/.tauri/myapp.key

The above commands will generate a prompt to add a password to your key, make note of that for a while.

The stdout will yield back:

terminal
Please enter a password to protect the secret key.
Password:
Password (one more time):
Deriving a key from the password in order to encrypt the secret key... done
Your keypair was generated successfully
Private: /path/.tauri/myapp.key (Keep it secret!)
Public: /path/.tauri/myapp.key.pub
---------------------------
Environment variables used to sign:
`TAURI_SIGNING_PRIVATE_KEY` Path or String of your private key
`TAURI_SIGNING_PRIVATE_KEY_PASSWORD` Your private key password (optional)
ATTENTION:
If you lose your private key OR password, you'll not be able to sign your
update package and updates will not work.
---------------------------

In your CI integration, you must add 2 environment variable secrets:

  • TAURI_SIGNING_PRIVATE_KEY with the content of myapp.key.
  • TAURI_SIGNING_PRIVATE_KEY_PASSWORD with the password you set.

And the contents of myapp.key.pub must be added to your tauri.conf.json:

/src-tauri/tauri.conf.json
"bundle": {
"createUpdaterArtifacts": true
},
"plugins": {
"updater": {
"active": true,
"endpoints": [
"CrabNebula Cloud updater endpoint"
],
"dialog": true,
"pubkey": "contents of myapp.key.pub"
}
}

Get Updater Endpoint from CrabNebula Cloud

Navigate to CrabNebula Cloud and login. At the Get started section you will find the Configure Tauri Updates card. Clicking on “Configure” will offer you a snippet with the endpoint.

Get Started section on CrabNebula Cloud

The endpoint URL follows this template:

https://cdn.crabnebula.app/update/your-org/your-app/{{target}}-{{arch}}/{{current_version}}

Do not replace the curly brackets, those are variables that will be used by Tauri itself when defining the right endpoint to hit. CrabNebula will take care of the rest.

Add the Plugins to Your App

Now it’s time to wire things up and use it within your app. The infrastructure is in place, we need to connect to it and to provide a decent user experience. First, we will add the plugins to our Tauri app.

/src-tauri/src/lib.rs
use tauri_plugin_dialog;
pub fn run() {
builder
.plugin(tauri_plugin_updater::Builder::new().build())
.plugin(tauri_plugin_dialog::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

And now it’s time to make use of that from the front-end side. We will create a method that will ping the endpoint for updates. If a new version is available it will download it and gracefully restart the app.

/src/updater.ts
import { check } from "@tauri-apps/plugin-updater";
import { ask, message } from "@tauri-apps/plugin-dialog";
import { relaunch } from "@tauri-apps/plugin-process";
export async function checkForAppUpdates() {
const update = await check();
if (update?.available) {
const yes = await ask(
`
Update to ${update.version} is available!
Release notes: ${update.body}
`,
{
title: "Update Now!",
kind: "info",
okLabel: "Update",
cancelLabel: "Cancel",
}
);
if (yes) {
await update.downloadAndInstall();
await relaunch();
}
}
}

Lastly, we let this run early and non-blocking.

import { checkForAppUpdates } from "./updater";
function App() {
onMount(async () => {
await checkForAppUpdates();
});
return <h1>Hello world</h1>;
}

Final Thoughts

With this setup, you now have auto-updates and CI/CD in your app through CrabNebula Cloud. This is recommended to make sure your users always have the best and most secure experience. If you have any issues, feel free to reach out at the CrabNebula Discord or the Tauri Discord.