Skip to content

Auto-Updater

Taurify includes support for auto updates by providing APIs for your application to securely update itself by fetching new releases on CrabNebula Cloud, installing updates and restarting itself.

Signing Keys

To securely deliver updates, Taurify signs your application and assets generating a signature that is verified by the updater. To generate a new keypair, use the CLI keypair generate command:

sh frame="none" pnpm taurify keypair generate

The command will prompt you for the keypair password. Do not lose that password, you will need to define it as the PRIVATE_KEY_PASSWORD environment variable to sign your update packages.

After generating the keys, the CLI writes the private key and its password in the key file and the public key is written to taurify.json. The private key must be defined as the PRIVATE_KEY environment variable and must be treated as a secret, DO NOT share it, if it is compromised you will need to replace it immediately.

Triggering Updates

To trigger a new update, you can use either the taurify build or the taurify update commands.

taurify build

The build command triggers a new application builds. Your entire application is updated, meaning you can leverage latest Taurify changes and new APIs.

taurify update

The update command triggers a new over-the-air update. It is a faster update mechanism where only your application assets are delivered to your existing users.

Installing Updates

To configure the updater for your application, install the @crabnebula/taurify-api package:

sh frame="none" pnpm add @crabnebula/taurify-api

Use the check API to fetch an update if there is one:

import { check } from "@crabnebula/taurify-api/updater";
import { relaunch } from "@crabnebula/taurify-api/process";
try {
const update = await check();
if (update) {
console.log("found update", update);
let contentLength = 0;
let downloaded = 0;
update.downloadAndInstall((event) => {
switch (event.event) {
case "Started":
contentLength = event.data.contentLength;
console.log("download started, total bytes:", contentLength);
break;
case "Progress":
downloaded += event.data.chunkLength;
console.log(
"download progress",
Math.round((downloaded / contentLength) * 100)
);
break;
case "Finished":
console.log("Installation complete, restarting...");
setTimeout(async () => {
// the update can either be an app update, or an over-the-air update
if (update.kind === "app") {
// for app updates we must restart the app
await relaunch();
} else {
// for over-the-air updates we can just reload the application
window.location.reload();
}
}, 2000);
break;
}
});
} else {
// there is no updates
}
} catch (e) {
console.error("failed to update", e);
}