release-hub checks for signed updates, downloads the artifact for the current target,
and hands installation off to the platform-specific path for that package type.
The primary workflow is manifest-first: your app points at an HTTPS endpoint that serves
release metadata plus a minisign signature for each artifact. GitHub Releases support is
still available, but now as an optional source adapter instead of the crate's core model.
- Manifest-first update checks from HTTPS endpoints
- Minisign verification before install
- Pluggable release sources through
ReleaseSource - Target-aware artifact resolution from a single release manifest
- Download progress callbacks during install
- Configurable headers, proxy, timeout, and executable path overrides
- macOS: installs
.app.tar.gzand.app.zipbundles by replacing the app bundle - Windows: launches
.exeand.msiinstallers, including configured installer arguments - Linux: replaces
.AppImagefiles in place and launches.deb/.rpminstalls throughpkexec
Updater::relaunch() is currently implemented only on macOS and Windows.
Add to your Cargo.toml:
[dependencies]
release-hub = "*"use release_hub::{Config, UpdaterBuilder};
use url::Url;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = Config {
endpoints: vec![Url::parse("https://updates.example.com/latest.json")?],
pubkey: "RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3".into(),
..Default::default()
};
let updater = UpdaterBuilder::new("MyApp", "1.0.0", config).build()?;
if let Some(update) = updater.check().await? {
update
.download_and_install(|chunk| eprintln!("downloaded {chunk} bytes"))
.await?;
}
Ok(())
}Config::endpoints is the default source. Each endpoint should return release metadata
for the latest version and provide a minisign signature for every platform artifact.
{
"version": "1.0.1",
"notes": "Bug fixes and stability improvements.",
"pub_date": "2026-04-21T12:00:00Z",
"platforms": {
"darwin-aarch64": {
"url": "https://updates.example.com/MyApp-aarch64.app.tar.gz",
"signature": "untrusted comment: signature from minisign secret key\nRW..."
},
"linux-x86_64": {
"url": "https://updates.example.com/MyApp-x86_64.AppImage",
"signature": "untrusted comment: signature from minisign secret key\nRW..."
},
"windows-x86_64": {
"url": "https://updates.example.com/MyApp-x86_64.msi",
"signature": "untrusted comment: signature from minisign secret key\nRW..."
}
}
}The updater selects the entry matching the current target, downloads the artifact, verifies it with the configured public key, and then runs the install path for that artifact type.
Downloaded installer artifacts must follow these naming rules so release-hub can
recognize the package type and, when using GitHub Releases, match the asset to the
current target.
Installer filenames must end with one of the supported package extensions:
- macOS:
.app.tar.gz,.app.zip - Linux:
.AppImage,.deb,.rpm - Windows:
.msi,.exe
If the filename does not end with one of these extensions, the installer format cannot be resolved.
When using GitHubSource, the release asset name must contain the target marker for
the platform it serves. Canonical target markers are:
darwin-aarch64linux-x86_64windows-x86_64
GitHub asset matching also accepts the same marker with - and _ swapped, such as
linux_x86_64 or windows_x86_64.
The rest of the filename is flexible, but the asset name must include a recognizable target marker and end with a supported installer extension.
Each installer asset must have a paired detached minisign signature asset using one of these filenames:
<installer-name>.sig<installer-name>.minisig
Examples:
MyApp-darwin-aarch64.app.tar.gzMyApp-darwin-aarch64.app.tar.gz.sigMyApp-linux-x86_64.AppImageMyApp-linux-x86_64.AppImage.minisigMyApp-windows-x86_64.msiMyApp-windows-x86_64.msi.sig
When using manifest endpoints directly, the filename itself does not need to include
the target marker because target selection happens through the platforms map. The
artifact URL must still point to a file with a supported installer extension.
Use GitHubSource when your release metadata lives in GitHub Releases but you still
want the same updater flow. The GitHub adapter expects the target asset plus a paired
.sig or .minisig asset on the release.
use release_hub::{Config, GitHubSource, UpdaterBuilder};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = Config {
pubkey: "RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3".into(),
..Default::default()
};
let updater = UpdaterBuilder::new("MyApp", "1.0.0", config)
.source(Box::new(GitHubSource::new("owner", "repo")))
.build()?;
let _ = updater;
Ok(())
}For private repositories or to avoid anonymous rate limits, build the source with a personal access token:
use release_hub::{Config, GitHubSource, UpdaterBuilder};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let token = std::env::var("GITHUB_TOKEN")?;
let config = Config {
pubkey: "RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3".into(),
..Default::default()
};
let source = GitHubSource::with_auth_token("owner", "repo", token)?;
let updater = UpdaterBuilder::new("MyApp", "1.0.0", config)
.source(Box::new(source))
.build()?;
let _ = updater;
Ok(())
}header(...)andheaders(...)let you attach authentication or cache-control headersproxy(...)andno_proxy()control HTTP routingtimeout(...)sets a request timeout for manifest fetches and downloadsexecutable_path(...)overrides the detected install target when your app needs itinstaller_arg(...)andinstaller_args(...)append extra Windows installer arguments
.app.tar.gz/.app.zip: extracted and swapped into place on macOS.exe/.msi: written to a temporary path and launched on Windows.AppImage: written tocurrent_executable.newand atomically renamed on Linux.deb: installed withpkexec dpkg -i.rpm: installed withpkexec rpm -U
- Source: tauri-apps/tauri-plugin-updater
- Author: The Tauri Programme
- License: MIT OR MIT/Apache 2.0
- Usage: Implement updater for Dioxus apps or any other Rust GUI applications
- Copyright: Copyright (c) 2015 - Present - The Tauri Programme within The Commons Conservancy.
- Key Modifications:
- Adapt for universal Rust crate
- Remove Tauri-specific runtime integration
- Add manifest-based endpoint sources and pluggable release-source adapters
Detailed Info: For complete attribution information, please refer to the NOTICE file
Licensed under either of:
- Apache License, Version 2.0, (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.