updater
import { updater } from "@tynd/core/client";Auto-update checker + signed binary downloader. Verifies Ed25519 signatures over the raw downloaded bytes.
check(opts): Promise<UpdateInfo | null>
Fetch the manifest and return metadata if a newer version is available.
interface UpdaterCheckOptions {
endpoint: string; // URL of the update.json manifest
currentVersion: string; // semver
}
interface UpdateInfo {
version: string;
notes: string | null;
pubDate: string | null; // ISO-8601 if the manifest has one
url: string;
signature: string; // base64 Ed25519
platform: string; // e.g. "windows-x86_64"
}
const info = await updater.check({
endpoint: "https://releases.example.com/update.json",
currentVersion: "1.0.0",
});
if (info) console.log(`Update available: ${info.version}`);Returns null when already up to date.
downloadAndVerify(opts): Promise<UpdaterDownloadResult>
Streams the artifact to a temp file while hashing, then verifies the Ed25519 signature over the full downloaded bytes.
interface UpdaterDownloadOptions {
url: string;
signature: string; // base64 Ed25519
pubKey: string; // raw 32-byte Ed25519 pubkey, base64
progressId?: string; // scopes onProgress events to this download
}
interface UpdaterDownloadResult {
path: string;
size: number;
}
const off = updater.onProgress(({ phase, loaded, total }) => {
console.log(`${phase}: ${loaded}/${total ?? "?"}`);
});
const { path, size } = await updater.downloadAndVerify({
url: info.url,
signature: info.signature,
pubKey: UPDATER_PUB_KEY,
progressId: "update-download",
});
off();Rejects with a signature check failed error if verification fails.
onProgress(fn): () => void
Fires during download + verification. Throttled ~50 ms.
interface UpdaterProgress {
id?: string;
phase: "download" | "verified";
loaded: number;
total: number | null;
}
const off = updater.onProgress((p) => {
console.log(p.phase, p.loaded, p.total);
});install(opts): Promise<UpdaterInstallResult>
Swaps the downloaded binary for the running one and optionally relaunches.
interface UpdaterInstallOptions {
path: string;
relaunch?: boolean; // defaults to true
}
interface UpdaterInstallResult {
installed: boolean;
path: string; // final on-disk path of the running binary
relaunch: boolean;
}
const result = await updater.install({ path, relaunch: true });Platform semantics
- Windows — delegates to a short cmd script (
timeout /t 2 /nobreak > nul & move /y <new> <current> & start ""). Lets the current.exeunlock, then swaps + relaunches. - Linux (AppImage + any single-file binary) —
fs::rename+ chmod +x + spawn + exit. Linux keeps the old inode mapped while the exe is live. - macOS — not yet implemented.
.appbundles are directories; callers manage the swap manually using the returnedpath.
Returns just before the current process exits. Don’t rely on any state after install resolves.
Manifest format (Tauri-compatible)
{
"version": "1.2.3",
"notes": "Bug fixes & perf.",
"pub_date": "2026-04-19T12:00:00Z",
"platforms": {
"windows-x86_64": {
"url": "https://.../MyApp-1.2.3-setup.exe",
"signature": "<base64 Ed25519>"
},
"darwin-aarch64": {
"url": "https://.../MyApp-1.2.3.dmg",
"signature": "<base64 Ed25519>"
},
"linux-x86_64": {
"url": "https://.../MyApp-1.2.3.AppImage",
"signature": "<base64 Ed25519>"
}
}
}Platform key: <os>-<arch>, where os ∈ { windows | darwin | linux } (macos → darwin for GitHub Releases / Tauri parity) and arch ∈ { x86_64 | aarch64 }.
Trust model
- Manifest served plain HTTPS (no meta-signature).
- Each platform entry carries an Ed25519 signature over the raw artifact bytes.
- Public key is baked into the app — a compromised manifest server can only redirect to a URL whose bytes still verify against the local pubkey.
Signing workflow
tynd keygen --out release/updater
tynd sign release/MyApp-1.2.3-setup.exe \
--key release/updater.key \
--out release/MyApp-1.2.3-setup.exe.sigBake the pubkey into your app source:
export const UPDATER_PUB_KEY = "cFpG...RVDv/RQ=";Not yet handled
- macOS
.appswap (extract from.dmg/.tar.gz). - Periodic auto-check — roll your own
setInterval. - Delta updates (binary diff).
- Rollback on failure.
See the Auto-Updates guide.
Related
tynd keygen— generate the keypair.tynd sign— sign a file.