ecosystem-wikicómo extender los templates sin romper sus convenciones
‹ todas las recipes

Cómo está organizado el cliente

template-expo
último cambio 2026-09-25

El cliente móvil tiene una estructura plana y corta. No hay capas como en la api: aquí lo que manda es para qué sirve un fichero, no en qué nivel de abstracción vive.

src/
  app/          rutas — cada fichero es una pantalla (expo-router)
  components/   piezas reutilizables de UI
  hooks/        carga de datos y lógica reutilizable de pantalla
  services/     todo lo que habla con fuera: api, almacenamiento, push
  context/      estado global (hoy solo la sesión)
  constants/    tema, etiquetas, listas fijas
  config/       lectura de variables de entorno
  lib/          utilidades puras sin dependencias

La regla de dónde va cada cosa

Si es… Va en
Una pantalla a la que se navega app/
UI que usan dos pantallas o más components/
Una llamada a la api services/<recurso>-api.ts
“Cargar X y saber si está cargando” hooks/use-<x>.ts
Algo que necesita toda la app a la vez context/
Un color, un espaciado, una lista de opciones constants/
Una función pura (formatear una fecha) lib/

Dos criterios que evitan la mayoría de las dudas:

No hay gestor de estado, y es a propósito

Ni Redux, ni Zustand, ni React Query. El estado se reparte en tres sitios y nada más:

  1. useState local en la pantalla, para lo que solo le importa a ella.
  2. Un hook de datos (useFetch/usePaginatedFetch) para lo que viene de la api.
  3. Un contexto para lo único que de verdad es global: la sesión.

Funciona porque la api es la fuente de la verdad y no hay estado compartido complejo entre pantallas. Cada pantalla pide lo que necesita al entrar. La contrapartida asumida es que dos pantallas que muestran el mismo dato lo piden dos veces; a este tamaño, eso es más barato que mantener una caché.

Antes de añadir una librería de estado, comprueba que el problema no se resuelve con un hook compartido — que es cómo se han resuelto todos hasta ahora.

Dos detalles de convención