Desktop Cross Platform — Cheat Sheet

Tag: electron, tauri, flutter, react-native, desktop, cross-platform

Livello: intermedio

TL;DR: Confronto architetturale tra Electron, Tauri e Flutter per app desktop; ottimizzazione memoria, IPC sicuro e accesso a API native.

Concetti chiave

Electron impacchetta Chromium e Node.js garantendo massima compatibilità web al costo di footprint elevato.

Tauri adotta WebView di sistema native (WebKit, WebView2) con backend in Rust, riducendo binario e memoria.

Flutter compila grafica nativa su Canvas tramite motore dedicato, bypassando interamente i motori browser.

L'architettura multi-processo separa il Main Process (controllo OS) dai Renderer Process (interfaccia utente).

La comunicazione tra UI e backend sfrutta canali IPC asincroni, minimizzando il blocco del loop grafico.

In Electron contextIsolation impedisce al Renderer l'accesso diretto alle API Node.js non mediate.

I pre-load script fungono da ponte controllato, esportando solo selettori specifici tramite contextBridge.

La firma del codice richiede certificati distinti: Authenticode su Windows e Notarization Apple su macOS.

Gli aggiornamenti nativi richiedono installer dedicati per OS, come MSIX/NSIS su Windows o DMG/PKG su macOS.

Domande tipiche e risposte pronte

Q: Quando preferisci Tauri rispetto a Electron?R: Scelgo Tauri quando peso del binario e consumo di memoria sono vincolanti, sfruttando WebView2 e Rust per la sicurezza.

Q: Come metti in sicurezza un'applicazione Electron?R: Abilito contextIsolation, disabilito nodeIntegration ed espongo unicamente handler tipizzati tramite contextBridge nel pre-load script.

Q: Come gestisci operazioni computazionalmente pesanti senza congelare l'interfaccia?R: Sposto i calcoli fuori dal Main e dal Renderer usando Worker thread dedicati in Node.js o command asincroni Rust.

Insidie e errori comuni

Attivare nodeIntegration: true nel Renderer esponendo l'applicazione a vulnerabilità di tipo Remote Code Execution.

Inviare payload massivi tramite canali IPC serializzati, causando overhead di serializzazione e cali di framerate.

Dimenticare differenze tra i motori WebView di sistema in Tauri, provocando discrepanze CSS tra macOS e Windows.

Eseguire operazioni bloccanti I/O sincrone all'interno del Main Process, rendendo l'intera UI non responsiva.

Snippet e comandiTypeScript

// preload.ts: Esposizione sicura di API native al Renderer
import { contextBridge, ipcRenderer } from 'electron';

contextBridge.exposeInMainWorld('desktopApi', {
  sendNotification: (message: string) => ipcRenderer.invoke('notify', message),
  onUpdateAvailable: (callback: () => void) => {
    ipcRenderer.on('update-available', () => callback());
  }
});

Rust

// src-tauri/src/main.rs: Command invocabile da frontend in Tauri
#[tauri::command]
fn read_native_config() -> Result<String, String> {
    std::fs::read_to_string("config.json").map_err(|e| e.to_string())
}

Da ripassare

[ ] Configurazione del ciclo di auto-update con Squirrel e Sparkle.

[ ] Pipeline di notarization Apple e provisioning profiles.

[x] Principi di isolamento del contesto e IPC bridge.

Jarvis Interviews
Jarvis