Empaquetado nativo y @nexa/platform
El mismo código fuente compila a un binario de escritorio real (Tauri), un APK real (Capacitor Android) o un proyecto Xcode real (Capacitor iOS) — sin reescribir nada. Web, escritorio, Android e iOS desde un solo proyecto, y @nexa/platform es lo que hace que el mismo handler funcione en los tres sin ramas propias.
Escritorio con Tauri
nexa add tauri
cd src-tauri && cargo build
# binario de escritorio real, ejecutableGenera src-tauri/ real — cargo build produce un binario de escritorio real y ejecutable en Windows, macOS y Linux.
Android con Capacitor
nexa add capacitor
npx @capacitor/cli add android
cd android && ./gradlew assembleDebug
# APK real en app/build/outputs/apk/debug/Requiere el SDK de Android instalado — el resultado es un APK real, compilado con Gradle. Verificado de punta a punta con un SDK real.
iOS con Capacitor
nexa add capacitor
npx @capacitor/cli add ios
npx cap open ios
# abre el proyecto real en Xcode (requiere macOS)Mismo capacitor.config.json que Android — add ios genera un proyecto Xcode real (ios/). Necesita macOS con Xcode para compilar: no probado en este entorno Linux, pero el mecanismo es idéntico al de Android.
@nexa/platform: un mismo handler, tres plataformas
function shareThis() {
platform.share({ title: "Nexa", url: location.href });
}
const users = platform.db("users");
await users.set("1", { name: "Ada" });platform.share()/platform.notify()/platform.capturePhoto() llaman al plugin real de Capacitor en Android/iOS (@capacitor/share, etc.) y a la Web API estándar en web y en el webview de Tauri — sin que el proyecto escriba ninguna rama propia. platform.storage()/platform.sessionStorage() envuelven localStorage/sessionStorage con el mismo contrato en los tres entornos; platform.cache() da acceso directo a la Cache API (sin declarar [pwa]); platform.db("nombre") es un wrapper mínimo sobre IndexedDB, sin declarar nada de antemano. Cada función lanza un Error con mensaje claro si la capacidad no está disponible — nunca falla en silencio.
Tema oscuro, red y ciclo de vida
platform.theme.set("dark");
platform.network.onChange((status) => {
console.log(status.online, status.type);
});
platform.lifecycle.onChange((state) => {
console.log(state.active ? "activa" : "en segundo plano");
});platform.theme.set("dark"|"light"|"system") persiste la preferencia y le gana al prefers-color-scheme del sistema (sin llamarlo nunca, el sitio ya lo respeta). platform.network.getStatus()/onChange() dan el estado de conectividad real (online/offline, y el tipo de conexión en Capacitor); platform.lifecycle.getState()/onChange() avisan cuando la app pasa a segundo plano o vuelve — en Capacitor vía @capacitor/app, en web vía document.hidden/visibilitychange. Se amplía de a un módulo por vez, según necesidad real: geolocalización, deep links, push real, biometría y haptics todavía no están.