← Blog

Construir Apps Offline-First que Realmente Funcionan

·
PWASQLiteArquitectura

La mayoría de las apps "offline-first" son realmente "online-first con caché". Funcionan bien en una cafetería con wifi intermitente, pero fallan en un taller sin señal.

Construí una PWA de gestión de taller que necesitaba ser completamente funcional offline — no degradada, no solo lectura, sino completamente operativa. Esto es lo que aprendí.

Las Restricciones

La app necesitaba manejar:

  • Crear y editar órdenes de trabajo sin conectividad
  • Rastrear movimientos de caja y saldos de clientes
  • Importar datos legacy desde archivos DBF
  • Exportar toda la base de datos como un solo archivo para backup

La restricción clave: la app tenía que sentirse igual estando online u offline. Los usuarios no deberían tener que pensar en la conectividad.

Por Qué SQLite, No IndexedDB

IndexedDB es el "estándar" para almacenamiento en el navegador, pero tiene problemas reales para apps operativas:

  • Sin SQL — escribís queries verbosos basados en cursores
  • Las migraciones de esquema son dolorosas
  • No hay forma fácil de exportar toda la base de datos
  • El rendimiento se degrada con datasets grandes

SQLite (vía sql.js compilado a WASM) nos dio:

  • Queries SQL reales
  • Exportación/backup de un solo archivo (solo descargá el .db)
  • Herramientas de migración maduras
  • Rendimiento predecible a escala

El tradeoff: un bundle WASM de ~1MB. Para una herramienta interna, es aceptable.

Estrategia de Sincronización de Datos

Lo mantuvimos simple: sin sincronización en tiempo real. La app funciona de forma autónoma. Cuando hay internet, puede enviar datos al servidor, pero no es obligatorio.

Esto eliminó toda una clase de complejidad:

  • Sin resolución de conflictos
  • Sin estrategias de merge
  • Sin sorpresas de "la última escritura gana"

El usuario exporta o sincroniza explícitamente. La app nunca sobreescribe sus datos en silencio.

Lecciones

  1. Offline-first es una decisión de UX, no técnica. La arquitectura se deriva de "¿cómo debería sentirse esto?" no "¿qué API debería usar?"
  2. SQLite en el navegador está subestimado. Para apps con muchos datos, es mejor que IndexedDB en casi todos los aspectos.
  3. Evitá la sincronización en tiempo real si podés. La sincronización explícita es más simple, más predecible y más fácil de debuggear.
  4. Exportá todo. Los usuarios confían en herramientas que les permiten llevarse sus datos.

Si tu equipo rastrea trabajo en hojas de cálculo y pierde datos, hablemos de construir algo mejor.

¿Querés discutir esto?

Si esto resonó con un problema que estás enfrentando, hablemos.