Updater
Actualiza automáticamente tu app de Tauri con un servidor de actualización o un JSON estático.
Plataformas Soportadas
Sección titulada “Plataformas Soportadas”Este plugin requiere una versión de Rust de al menos 1.77.2
| Plataforma | Nivel | Notas |
|---|---|---|
| windows | ||
| linux | ||
| macos | ||
| android | ||
| ios |
Configuración
Sección titulada “Configuración”Instala el plugin updater de Tauri para comenzar.
Usa el gestor de paquetes de tu proyecto para agregar la dependencia:
npm run tauri add updateryarn run tauri add updaterpnpm tauri add updaterdeno task tauri add updaterbun tauri add updatercargo tauri add updater-
Ejecuta el siguiente comando en la carpeta
src-tauripara agregar el plugin a las dependencias del proyecto enCargo.toml:cargo add tauri-plugin-updater --target 'cfg(any(target_os = "macos", windows, target_os = "linux"))' -
Modifica
lib.rspara inicializar el 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");} -
Puedes instalar los bindings de JavaScript utilizando tu gestor de paquetes de JavaScript preferido:
npm install @tauri-apps/plugin-updateryarn add @tauri-apps/plugin-updaterpnpm add @tauri-apps/plugin-updaterdeno add npm:@tauri-apps/plugin-updaterbun add @tauri-apps/plugin-updater
Firmar actualizaciones
Sección titulada “Firmar actualizaciones”El actualizador de Tauri necesita una firma para verificar que la actualización provenga de una fuente de confianza. Esto no se puede desactivar.
Para firmar tus actualizaciones necesitas dos claves:
- La clave pública, que se establecerá en el
tauri.conf.jsonpara validar los artefactos antes de la instalación. Esta clave pública se puede cargar y compartir de forma segura siempre que tu clave privada esté protegida. - La clave privada, que se usa para firmar tus archivos de instalador. NUNCA debes compartir esta clave con nadie. Además, si pierdes esta clave NO podrás publicar nuevas actualizaciones para los usuarios que ya tienen la app instalada. ¡Es importante guardar esta clave en un lugar seguro!
Para generar las claves, la CLI de Tauri proporciona el comando signer generate. Puedes ejecutar esto para crear las claves en la carpeta personal:
npm run tauri signer generate -- -w ~/.tauri/myapp.keyyarn tauri signer generate -w ~/.tauri/myapp.keypnpm tauri signer generate -w ~/.tauri/myapp.keydeno task tauri signer generate -w ~/.tauri/myapp.keybunx tauri signer generate -w ~/.tauri/myapp.keycargo tauri signer generate -w ~/.tauri/myapp.keyCompilación (Building)
Sección titulada “Compilación”Al compilar tus artefactos de actualización, necesitas tener la clave privada que generaste anteriormente en tus variables de entorno. ¡Los archivos .env no funcionan!
export TAURI_SIGNING_PRIVATE_KEY="Path or content of your private key"# optionally also add a passwordexport TAURI_SIGNING_PRIVATE_KEY_PASSWORD=""Ejecuta esto en PowerShell:
$env:TAURI_SIGNING_PRIVATE_KEY="Path or content of your private key"<# optionally also add a password #>$env:TAURI_SIGNING_PRIVATE_KEY_PASSWORD=""Después de eso, puedes ejecutar el build de Tauri como de costumbre y Tauri generará los paquetes de actualización y sus firmas.
Los archivos generados dependen del valor de configuración createUpdaterArtifacts configurado a continuación.
{ "bundle": { "createUpdaterArtifacts": true }}En Linux, Tauri creará la AppImage normal dentro de la carpeta target/release/bundle/appimage/:
myapp.AppImage- El paquete estándar de la app. El actualizador lo reutilizará.myapp.AppImage.sig- La firma del paquete del actualizador.
En macOS, Tauri creará un archivo .tar.gz a partir del paquete de aplicación dentro de la carpeta target/release/bundle/macos/:
myapp.app- El paquete estándar de la app.myapp.app.tar.gz- El paquete del actualizador.myapp.app.tar.gz.sig- La firma del paquete de actualización.
En Windows, Tauri creará los instaladores normales MSI y NSIS dentro de las carpetas target/release/bundle/msi/ y target/release/bundle/nsis:
myapp-setup.exe- El paquete estándar de la app. El actualizador lo reutilizará.myapp-setup.exe.sig- La firma del paquete de actualización.myapp.msi- El paquete estándar de la app. El actualizador lo reutilizará.myapp.msi.sig- La firma del paquete de actualización.
{ "bundle": { "createUpdaterArtifacts": "v1Compatible" }}En Linux, Tauri creará un archivo .tar.gz a partir de la AppImage dentro de la carpeta target/release/bundle/appimage/:
myapp.AppImage- El paquete estándar de la app.myapp.AppImage.tar.gz- El paquete del actualizador.myapp.AppImage.tar.gz.sig- La firma del paquete de actualización.
En macOS, Tauri creará un archivo .tar.gz a partir del paquete de aplicación dentro de la carpeta target/release/bundle/macos/:
myapp.app- El paquete estándar de la app.myapp.app.tar.gz- El paquete del actualizador.myapp.app.tar.gz.sig- La firma del paquete de actualización.
En Windows, Tauri creará archivos .zip a partir de los instaladores MSI y NSIS dentro de las carpetas target/release/bundle/msi/ y target/release/bundle/nsis:
myapp-setup.exe- El paquete estándar de la app.myapp-setup.nsis.zip- El paquete del actualizador.myapp-setup.nsis.zip.sig- La firma del paquete de actualización.myapp.msi- El paquete estándar de la app.myapp.msi.zip- El paquete del actualizador.myapp.msi.zip.sig- La firma del paquete de actualización.
Configuración de Tauri
Sección titulada “Configuración de Tauri”Configura el tauri.conf.json en este formato para que el actualizador comience a funcionar.
| Claves | Descripción |
|---|---|
createUpdaterArtifacts |
Establecer esto en true le indica al empaquetador de aplicaciones de Tauri que cree artefactos para el actualizador. Si estás migrando tu aplicación desde una versión anterior de Tauri, establécelo en "v1Compatible" en su lugar. Esta configuración se eliminará en v3, así que asegúrate de cambiarla a true una vez que todos tus usuarios hayan migrado a v2. |
pubkey |
Esta debe ser la clave pública generada desde la CLI de Tauri en el paso anterior. ¡No puede ser una ruta de archivo! |
endpoints |
Debe ser un array de URL de endpoints como cadenas de texto. TLS es obligatorio en modo producción. ¡Tauri solo continuará a la siguiente URL si se devuelve un código de estado distinto de 2XX! |
dangerousInsecureTransportProtocol |
Establecer esto en true permite que el actualizador acepte endpoints que no sean HTTPS. ¡Usa esta configuración con precaución! |
Cada URL de actualizador puede contener las siguientes variables dinámicas, lo que te permite determinar en el lado del servidor si hay una actualización disponible.
{{current_version}}: La versión de la app que solicita la actualización.{{target}}: El nombre del sistema operativo (uno delinux,windowsodarwin).{{arch}}: La arquitectura de la máquina (una dex86_64,i686,aarch64oarmv7).
{ "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" ] } }}installMode en Windows
Sección titulada “installMode en Windows”En Windows hay una configuración opcional adicional "installMode" para cambiar cómo se instala la actualización.
{ "plugins": { "updater": { "windows": { "installMode": "passive" } } }}"passive": Habrá una pequeña ventana con una barra de progreso. La actualización se instalará sin requerir interacción del usuario. Generalmente recomendado y es el modo por defecto."basicUi": Se mostrará una interfaz de usuario básica que requiere interacción del usuario para finalizar la instalación."quiet": No habrá comentarios de progreso para el usuario. Con este modo, el instalador no puede solicitar privilegios de administrador por sí mismo, por lo que solo funciona en instalaciones a nivel de usuario o cuando tu app ya se ejecuta con privilegios de administrador. Generalmente no recomendado.
Soporte de servidor
Sección titulada “Soporte de servidor”El plugin updater se puede utilizar de dos formas. Ya sea con un servidor de actualización dinámico o con un archivo JSON estático (para usar en servicios como S3 o GitHub gists).
Archivo JSON estático
Sección titulada “Archivo JSON estático”Al usar estático, solo necesitas devolver un JSON que contenga la información requerida.
| Claves | Descripción |
|---|---|
version |
Debe ser un SemVer válido, con o sin una v inicial, lo que significa que tanto 1.0.0 como v1.0.0 son válidos. |
notes |
Notas sobre la actualización. |
pub_date |
La fecha debe estar formateada según el RFC 3339 si está presente. |
platforms |
Cada clave de plataforma está en el formato OS-ARCH, donde OS es uno de linux, darwin o windows, y ARCH es uno de x86_64, aarch64, i686 o armv7. |
signature |
El contenido del archivo .sig generado, que puede cambiar con cada build. ¡Una ruta o URL no funciona! |
Las claves obligatorias son "version", "platforms.[target].url" y "platforms.[target].signature"; las demás son opcionales.
{ "version": "", "notes": "", "pub_date": "", "platforms": { "linux-x86_64": { "signature": "", "url": "" }, "windows-x86_64": { "signature": "", "url": "" }, "darwin-x86_64": { "signature": "", "url": "" } }}Ten en cuenta que Tauri validará todo el archivo antes de verificar el campo version, así que asegúrate de que todas las configuraciones de plataformas existentes sean válidas y estén completas.
Servidor de actualización dinámico
Sección titulada “Servidor de actualización dinámico”Al utilizar un servidor de actualización dinámico, Tauri seguirá las instrucciones del servidor. Para desactivar la comprobación de versión interna puedes sobrescribir la comparación de versiones del plugin, esto instalará la versión enviada por el servidor (útil si necesitas hacer un rollback de tu app).
Tu servidor puede usar variables definidas en la URL del endpoint anterior para determinar si se requiere una actualización. Si necesitas más datos, puedes incluir encabezados de solicitud adicionales en Rust a tu gusto.
Tu servidor debe responder con un código de estado 204 No Content si no hay ninguna actualización disponible.
Si se requiere una actualización, tu servidor debe responder con un código de estado 200 OK y una respuesta JSON en este formato:
| Claves | Descripción |
|---|---|
version |
Debe ser un SemVer válido, con o sin una v inicial, lo que significa que tanto 1.0.0 como v1.0.0 son válidos. |
notes |
Notas sobre la actualización. |
pub_date |
La fecha debe estar formateada según el RFC 3339 si está presente. |
url |
Debe ser una URL válida al paquete de actualización. |
signature |
El contenido del archivo .sig generado, que puede cambiar con cada build. ¡Una ruta o URL no funciona! |
Las claves obligatorias son "url", "version" y "signature"; las demás son opcionales.
{ "version": "", "pub_date": "", "url": "", "signature": "", "notes": ""}Comprobando actualizaciones
Sección titulada “Comprobando actualizaciones”La API por defecto para comprobar e instalar actualizaciones aprovecha los endpoints configurados y se puede acceder tanto desde código JavaScript como Rust.
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();}Para obtener más información, consulta la documentación de la API de JavaScript.
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(())}Para obtener más información, consulta la documentación de la API de Rust.
Ten en cuenta que no es necesario reiniciar tu app inmediatamente después de instalar una actualización y puedes elegir cómo gestionar la actualización esperando a que el usuario reinicie manualmente la app, o pidiéndole que seleccione cuándo hacerlo.
Al comprobar y descargar actualizaciones es posible definir un tiempo de espera (timeout) de solicitud personalizado, un proxy y encabezados de solicitud.
import { check } from '@tauri-apps/plugin-updater';
const update = await check({ proxy: '<proxy url>', timeout: 30000 /* milliseconds */, headers: { Authorization: 'Bearer <token>', },});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?;Configuración en tiempo de ejecución
Sección titulada “Configuración en tiempo de ejecución”Las API del actualizador también permiten configurar el actualizador en tiempo de ejecución para una mayor flexibilidad. Por razones de seguridad, algunas API solo están disponibles para Rust.
Endpoints
Sección titulada “Endpoints”Establecer las URL que se deben consultar para comprobar actualizaciones en tiempo de ejecución permite actualizaciones más dinámicas, como canales de lanzamiento separados:
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?;Clave pública
Sección titulada “Clave pública”Establecer la clave pública en tiempo de ejecución puede ser útil para implementar una lógica de rotación de claves. Se puede establecer mediante el plugin builder o el 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?;Target personalizado
Sección titulada “Target personalizado”Por defecto, el actualizador te permite usar las variables {{target}} y {{arch}} para determinar qué recurso de actualización debe entregarse.
Si necesitas más información sobre tus actualizaciones (por ejemplo, al distribuir una opción binaria Universal de macOS o al tener más variantes de compilación),
puedes establecer un target personalizado.
import { check } from '@tauri-apps/plugin-updater';
const update = await check({ target: 'macos-universal',});Los targets personalizados se pueden establecer mediante el plugin builder o el 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?;Permitir downgrades
Sección titulada “Permitir downgrades”Por defecto, Tauri comprueba si la versión de la actualización es mayor que la versión actual de la app para verificar si debe actualizar o no.
Para permitir downgrades, debes usar la API version_comparator del updater builder:
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?;Hook de Windows antes de salir
Sección titulada “Hook de Windows antes de salir”Debido a una limitación de los instaladores de Windows, Tauri cerrará automáticamente tu aplicación antes de instalar actualizaciones en Windows.
Para realizar una acción antes de que eso suceda, usa la función on_before_exit:
use tauri_plugin_updater::UpdaterExt;
let update = app .updater_builder() .on_before_exit(|| { println!("app is about to exit on Windows!"); }) .build()? .check() .await?;Permisos
Sección titulada “Permisos”De forma predeterminada, todos los comandos y alcances (scopes) potencialmente peligrosos del plugin están bloqueados y no se puede acceder a ellos. Debes modificar los permisos en tu configuración de capabilities para habilitarlos.
Consulta la Visión General de Capacidades para obtener más información y la guía paso a paso para usar permisos de plugins.
{ "permissions": [ ..., "updater:default", ]}Permiso Predeterminado
Este conjunto de permisos configura qué tipo de funciones del actualizador se exponen al frontend.
Permisos Otorgados
El flujo de trabajo completo, desde comprobar las actualizaciones hasta instalarlas, está habilitado.
Este conjunto de permisos predeterminado incluye lo siguiente:
allow-checkallow-downloadallow-installallow-download-and-install
Tabla de Permisos
| Identificador | Descripción |
|---|---|
|
|
Habilita el comando check sin ningún ámbito preconfigurado. |
|
|
Deniega el comando check sin ningún ámbito preconfigurado. |
|
|
Habilita el comando download sin ningún ámbito preconfigurado. |
|
|
Deniega el comando download sin ningún ámbito preconfigurado. |
|
|
Habilita el comando download_and_install sin ningún ámbito preconfigurado. |
|
|
Deniega el comando download_and_install sin ningún ámbito preconfigurado. |
|
|
Habilita el comando install sin ningún ámbito preconfigurado. |
|
|
Deniega el comando install sin ningún ámbito preconfigurado. |
© 2026 Colaboradores de Tauri. CC-BY / MIT