Cada año se repite el mismo patrón. Un equipo necesita una app de escritorio. Tira de Electron porque todo el mundo tira de Electron. Un mes después están entregando una binary de 180 MB que se come 400 MB de RAM para renderizar un formulario y tres pestañas, y se preguntan por qué la app no se siente como una app Mac en un Mac.
Electron es un valor por defecto. No siempre es la elección correcta.
La respuesta corta. Flutter es una opción madura para desarrollo de apps de escritorio multiplataforma. Entrega una binary base de ~30 MB, renderiza su propia UI vía Skia o Impeller a 60 a 120 fps, corre en Windows, macOS y Linux, y comparte código con iOS, Android y web desde el mismo código base Dart. Si ya usas Flutter en móvil, escritorio es la extensión barata. Si tienes una app Electron que funciona, quédate hasta tener una razón real para migrar.
¿Qué es el desarrollo de apps de escritorio multiplataforma?
Desarrollo de apps de escritorio multiplataforma significa construir un único código base que corre en Windows, macOS y Linux, en vez de mantener tres proyectos nativos. Las cuatro opciones que la mayoría de los equipos evalúan hoy:
- Electron (Node y Chromium). Ecosistema dominante, mayor comunidad, las binaries más grandes.
- Flutter (Dart con Skia o Impeller). Un código base para móvil, web y escritorio.
- Tauri (backend Rust, frontend con webview del sistema). Binary pequeña, ecosistema más joven.
- Qt o nativo (C++, Swift, WinUI). Máxima fidelidad, máximo coste.
Cada opción hace trade-offs distintos en tamaño de binary, memoria, feel, developer experience y cuánto de nativo parece el resultado para la persona que realmente lo usa.
Por qué Flutter para escritorio (y por qué no)
Flutter llegó a stable en Windows en 2022 y en macOS y Linux en la misma ventana. Ya no es experimental.
Nosotros mismos hemos entregado apps Flutter de escritorio, incluyendo una herramienta de supervisión de exámenes para la universidad Karel de Grote que captura paquetes de red, detecta máquinas virtuales y enumera adaptadores de hardware en Windows, macOS y Linux desde un único código base Flutter. Nuestra insight de Flutter FFI explica cómo funciona realmente esa integración nativa.
Las cosas que Flutter desktop hace bien:
Un código base, cada pantalla. Una app Flutter bien arquitectada corre en iOS, Android, Windows, macOS, Linux y web desde los mismos widgets. El código específico de plataforma (menús, gestión de ventanas, atajos) vive en finas capas condicionales. Para un equipo que ya entrega Flutter móvil, añadir escritorio es cuestión de semanas, no de meses.
Tamaño y memoria. La brecha entre Flutter y Electron no es teórica. Aparece en disco, en RAM y en el pipeline de renderizado.
Esa brecha importa para equipos de IT que despliegan a flotas Windows bloqueadas y para usuarios con hardware más antiguo. 170 MB de diferencia en tamaño de binary es la diferencia entre “aprobación rápida” y “rechazado por política” en muchos entornos empresariales.
La brecha de Flutter respecto a nativo es de aproximadamente 2x en binary y RAM. Respecto a Electron está más cerca de 5x. Y allí donde la brecha de 2x frente a nativo realmente duele (un loop de render, un pipeline de audio, una etapa de compresión), dart:ffi te deja bajar a C o Rust para ese único hot path y mantener todo lo demás en Flutter. La historia de compartir código multiplataforma permanece intacta.
Feel. Flutter renderiza su propia UI a 60 a 120 fps vía Skia o Impeller. Scroll, animación y latencia de input se sienten nativos en hardware habitual. Aún así tienes que respetar las convenciones de plataforma (menús en macOS, clic derecho en Windows, atajos Ctrl vs Cmd), pero la capa de widgets es lo bastante rápida como para que nada se sienta como una página web dentro de una ventana.
Nativo cuando hace falta, Flutter en todo lo demás. “Multiplataforma” en Flutter no significa “puro Dart”. Los hot paths críticos en rendimiento no te obligan a salir del framework. Bajas a C o Rust vía dart:ffi para las partes que necesitan velocidad nativa real (pipelines de imagen, DSP de audio, captura de paquetes, criptografía, enumeración de hardware) y mantienes Flutter para todo alrededor: UI, estado, navegación y la orquestación multiplataforma. La herramienta de supervisión de exámenes de KDG enlazada arriba es exactamente ese patrón, con un shell Dart y un hot path en C. Ambos salen del mismo comando flutter build. Los platform channels (llamar a Swift, Objective-C, Kotlin o C++) cubren las APIs del SO de más alto nivel donde FFI es excesivo.
Cómo es realmente “un único código base”. El hello-world para Flutter desktop es el mismo que el hello-world para Flutter móvil:
import 'package:flutter/material.dart';
void main() => runApp(
const MaterialApp(
home: Scaffold(
body: Center(child: Text('Hello, Desktop')),
),
),
);
Ejecútalo con flutter run -d macos, flutter run -d windows o flutter run -d linux. Ese es todo el punto de entrada. El código específico de plataforma viene después, en finas capas condicionales para menús, atajos y gestión de ventanas.
Las cosas que Flutter desktop no hace bien:
No todos los paquetes están listos para escritorio. pub.dev tiene miles de paquetes que apuntan a móvil y que en escritorio silenciosamente no hacen nada (o petan). Pasarás tiempo comprobando el soporte de plataforma de cada dependencia.
Accesibilidad por detrás de nativo en Windows y Linux. El soporte de lectores de pantalla en Windows y Linux es más débil que en iOS, Android y macOS. Para aplicaciones accessibility-first, testea esto antes de comprometerte.
Entrada de texto e IME. Los métodos de entrada para idiomas asiáticos y algunos teclados internacionales aún tienen aristas. Testea con las locales en las que realmente teclean tus usuarios.
Las cargas intensivas en gráficos y sensibles a la latencia piden un híbrido. CAD, estaciones de trabajo de audio digital, editores de vídeo en tiempo real y motores de juegos tienen techos de rendimiento que un pipeline 100% Dart no alcanzará. Flutter no es un motor de juegos y no intenta serlo. Pero tampoco tienes que abandonar Flutter para estas apps: el shell, la UI, el estado y la orquestación multiplataforma se quedan en Dart, y el loop de render, la cadena DSP o el pipeline del encoder bajan a C o Rust vía dart:ffi. Mismo flutter build, misma historia multiplataforma, rendimiento nativo donde importa.
Cuándo Flutter es la elección correcta para tu app de escritorio
Para todo lo que cae en productividad, operaciones, admin, herramientas creativas y SaaS vertical, Flutter desktop es el valor por defecto pragmático para trabajo nuevo.
Cosas específicas del escritorio que de verdad tendrás que cablear
Una app Flutter de escritorio real acaba escribiendo un puñado de cosas que una app Flutter móvil no necesita:
Gestión de ventanas. Multi-ventana, tamaño y persistencia del estado de las ventanas se hacen con paquetes como window_manager o bitsdojo_window. Ambos son maduros.
Barra de menú y atajos de teclado. Los menús nativos usan el PlatformMenuBar integrado de Flutter en macOS y APIs equivalentes en Windows y Linux. A nivel widget, Shortcuts y Actions hacen los atajos componibles entre plataformas.
File picker y drag and drop. file_picker y desktop_drop cubren los casos habituales. Los permisos del sandbox en macOS requieren cuidado.
Integración nativa vía dart:ffi. Para APIs del SO sin paquete Dart, escribes unas pocas líneas de C o Rust y las expones vía dart:ffi. Ese es el camino que tomamos cuando necesitamos capacidades que todavía no están empaquetadas.
Empaquetado y distribución. Windows usa MSIX o Inno Setup. macOS usa DMG con notarización. Linux usa snap, flatpak o deb. La auto-actualización usa el paquete auto_updater o una implementación custom alrededor de tu propio servidor de actualizaciones.
Firma de código y notarización. Toda app de escritorio en producción necesita ambas. Reserva un día para la primera notarización de Apple, menos para la segunda.
La pregunta de migración de Electron
Los equipos con Electron nos preguntan si deberían migrar a Flutter. La respuesta honesta: depende de qué detonantes estás tocando. El coste de migración es real y la mayoría de apps Electron que funcionan no necesitan moverse con urgencia. Pero para los equipos que tocan alguna de las señales de abajo, la cuenta se da la vuelta y el coste de quedarse se vuelve mayor que el coste de moverse.
- La memoria o el tamaño de binary se ha convertido en bloqueador de despliegue. Políticas de flota Windows, quejas de clientes sobre la RAM, despliegues de campo en hardware antiguo. Si la huella te cuesta tratos o genera tickets de soporte, eso es un detonante.
- Estás planeando una versión Flutter móvil o web del mismo producto. En cuanto el reparto de código multiplataforma está en la roadmap, cada mes gastado manteniendo dos stacks es un coste que no hace falta cargar.
- Has medido una brecha de rendimiento o feel que Electron no puede cerrar. No una intuición. Latencia de input, fluidez de animación, tiempo de arranque, medidos contra la baseline nativa que esperan tus usuarios.
- Tu equipo gasta sprints manteniendo Electron con vida. Saltos de versión de Chromium, ciclos de parches de seguridad, churn de dependencias. Si el mantenimiento se come el trabajo de producto, eso también cuenta.
Si una o más de estas te afectan, las siguientes preguntas son cuánto de la app existente se puede reutilizar, qué piezas específicas de plataforma hay que reconstruir y cómo es la timeline realista. Eso es una conversación, no una fórmula, y es la misma que recorremos con equipos que se plantean migración de React Native a Flutter. Nuestro servicio de migración legacy cubre el recorrido completo de discovery y entrega para equipos que han decidido que es hora.
Puntos clave
Electron es un valor por defecto, no una decisión. La mayoría de los equipos lo elige porque todos lo eligen. Está bien cuando es la respuesta correcta. A menudo no lo es.
Flutter desktop está listo para producción hoy. Windows, macOS y Linux, con despliegues insignia en Canonical y apps reales en agencias como la nuestra. La plataforma ha superado la etiqueta de experimental.
La mayor palanca es el reparto de código. Si ya entregas una app Flutter móvil, añadir escritorio son unas semanas. Si entregas escritorio primero, añadir móvil y web después es igual de barato. Electron te da solo escritorio.
Migra por detonantes, no por principio. Las apps Electron que funcionan no necesitan moverse con urgencia. Cuando la memoria, el tamaño de binary, el feel, la carga de mantenimiento o el reparto de código multiplataforma se convierten en un bloqueador real al que puedes apuntar, es hora de hablar.
La vía honesta. Herramientas de productividad, consolas de admin, dashboards de operaciones internas, compañeros de hardware, clientes SaaS verticales y tooling creativo (Rive construye el suyo sobre Flutter). Flutter desktop encaja. Para cargas intensivas en gráficos como CAD, vídeo en tiempo real y audio digital, Flutter sigue gestionando el shell y dart:ffi te baja a C o Rust para el trabajo pesado. Mira nuestra insight de Flutter FFI para ver cómo se entrega realmente el patrón híbrido.
Imagina un equipo pequeño que entregó una app Flutter móvil el año pasado. Este trimestre necesitan un compañero de escritorio. No una reconstrucción, no un segundo equipo, no un framework nuevo. Extraen la lógica de negocio a un paquete, añaden un punto de entrada de escritorio, cablean la barra de menú y entregan. Una semana después la versión Windows corre en el portátil del CEO y la versión macOS en el iMac del diseñador. Eso es a lo que se parece el desarrollo de apps de escritorio multiplataforma cuando el framework deja de estar en el medio.
¿Pensando en Flutter para tu app de escritorio?