Combinar herramientas: el stack pragmático de 2026
La lección que cierra el nivel y el track reúne todo lo anterior en una arquitectura concreta y comprobada: el stack por defecto de 2026, que no es una herramienta sino una combinación deliberada de varias, cada una gobernando la clase de estado para la que fue diseñada. TanStack Query para el estado de servidor, un store ligero como Zustand para el poco estado de cliente que queda, la URL para lo navegable, y una máquina de estado allí donde un flujo tenga modos y transiciones que no pueden fallar. Muestra cómo estas piezas conviven en un mismo componente sin pisarse, por qué combinar herramientas especializadas es más simple que una sola forzada a servir para todo, y cómo cada pieza mantiene su frontera. Cierra el track devolviendo la pregunta a su origen: la arquitectura de estado madura no elige la mejor herramienta, sino la combinación mínima donde cada clase de estado vive en su sitio.
Llegamos al final, y el final no es una herramienta ganadora sino una combinación. Después de recorrer signals, observables, máquinas de estado, Redux, Elm, TCA, MVI y la cache de servidor, la conclusión pragmática de 2026 es que ninguna de esas familias gana el debate porque el debate estaba mal planteado: no compiten por el mismo puesto. El stack por defecto de una aplicación seria hoy no elige entre ellas, las combina, y le asigna a cada una la clase de estado para la que fue diseñada. TanStack Query para el servidor, un store ligero como Zustand para el cliente, la URL para lo navegable, y una máquina de estado allí donde un flujo tenga modos que no pueden fallar. Esta lección monta ese stack, muestra cómo sus piezas conviven sin pisarse, y cierra el track devolviendo la pregunta a su origen: la madurez no está en la herramienta que eliges, sino en la combinación mínima donde cada clase de estado vive en su sitio.
- Montar el stack por defecto de 2026 asignando cada herramienta a la clase de estado que le corresponde.
- Ver cómo las piezas conviven en un mismo componente sin cruzar sus fronteras.
- Entender por qué varias herramientas especializadas son más simples que una sola generalista.
- Cerrar el track reformulando la pregunta de arquitectura como una de composición, no de elección.
El stack como composición, no como elección
El stack de 2026 es la materialización directa del árbol de clases de la primera lección: a cada clase, su herramienta idiomática, y ninguna herramienta invadiendo la clase de otra. No es un producto que instalas ni una opinión de moda; es lo que queda cuando aplicas con disciplina la separación de clases a una app real y dejas que cada pieza caiga en su sitio.
TanStack Query — servidor
Toda la verdad remota: perfiles, catálogos, listas, pedidos. Cache con frescura, revalidación y deduplicación. En muchos casos, los componentes de servidor asumen parte de este trabajo antes de que el dato cruce.
Zustand — cliente
El poco estado de cliente que queda tras sacar el servidor: sesión, tema, preferencias, selección global. Un store diminuto con selectores, sin provider ni ceremonia.
URL — navegable
Filtros, pestaña activa, paginación, término de búsqueda. Compartible por enlace y restaurable al recargar, servido por nuqs o el router del framework.
XState — flujos críticos
Una máquina de estado solo donde un flujo tiene modos excluyentes que no pueden fallar: un asistente de varios pasos, un proceso de pago, una conexión con reintentos.
La expresión clave del quinto punto es donde haga falta. La máquina no es una capa que envuelve toda la app, sino una pieza puntual que insertas en el flujo concreto que la merece, mientras el resto del estado sigue en su store ligero o su cache. El stack no impone una disciplina uniforme: aplica la máxima donde el riesgo lo exige y la mínima donde no, dentro de la misma aplicación.
flowchart TD APP[una app de 2026] --> SRV[estado de servidor] APP --> CLI[estado de cliente] APP --> NAV[estado navegable] APP --> FLU[flujos con transiciones] SRV --> TQ[TanStack Query o RSC] CLI --> ZU[Zustand o Jotai o useState] NAV --> URL[router o nuqs] FLU --> XS[una maquina XState donde duela] style TQ fill:#f38ba8,color:#11111b style ZU fill:#a6e3a1,color:#11111b style URL fill:#fab387,color:#11111b style XS fill:#89b4fa,color:#11111b
Cómo conviven sin pisarse
La objeción instintiva al stack es que suena a más cosas que aprender y mantener. La respuesta es que cada pieza es pequeña porque hace una sola cosa, y que las fronteras entre ellas son limpias justamente porque cada una gobierna una clase distinta. Un mismo componente orquesta las cuatro sin que ninguna sepa de las otras:
function PanelPedidos() {
// servidor: verdad remota, vive en la cache y solo se lee
const { data: pedidos, isPending } = useQuery({
queryKey: ['pedidos'], queryFn: traerPedidos,
});
// navegable: el filtro vive en la URL, compartible y restaurable
const [estado] = useSearchParam('estado');
// cliente: preferencia propia, vive en un store ligero
const compacto = useUI((s) => s.vistaCompacta);
// flujo critico: el alta de un pedido es una maquina con modos
const [snapshot, enviar] = useMachine(maquinaAlta);
if (isPending) return <Cargando />;
const visibles = pedidos.filter((p) => p.estado === estado);
return <Tabla filas={visibles} compacta={compacto} onNuevo={() => enviar({ type: 'abrir' })} />;
}
Ninguna de las cuatro herramientas conoce a las demás. TanStack Query no sabe que existe un store; el store no sabe de la URL; la máquina gobierna su flujo sin tocar la cache. Esa ignorancia mutua no es un accidente: es la propiedad que hace el stack mantenible. Cuando cada pieza tiene una frontera clara y una sola responsabilidad, puedes razonar sobre una sin cargar las otras en la cabeza, y puedes reemplazar cualquiera —cambiar Zustand por Jotai, nuqs por el router nativo— sin que las demás se enteren.
La intuición de que menos librerías es más simple confunde el número de piezas con la complejidad. Una sola herramienta forzada a gobernar las cuatro clases de estado no es simple: es una navaja suiza donde cada función está a medias, y donde tú pagas la diferencia reimplementando a mano la cache que le falta o la máquina que no tiene. Cuatro herramientas especializadas, cada una excelente en su clase y con una frontera nítida, dan un sistema más simple de operar que una generalista mediocre en todo, porque la simplicidad real no se mide en número de dependencias sino en cuánto tienes que tener en la cabeza para razonar sobre una parte. Cuatro cajas rotuladas ordenan mejor que un cajón único, por muchas cosas que quepan en el cajón.
Combinar mal: cuando dos herramientas se disputan un dato
El stack falla no cuando eliges mal una pieza, sino cuando dos piezas se disputan la misma. El caso típico: traes una lista con TanStack Query y la copias al store de Zustand para tenerla a mano, o guardas el filtro a la vez en la URL y en un useState local. En ese instante el dato tiene dos dueños, y la pregunta de cuál manda cuando discrepan no tiene respuesta limpia. El solapamiento de fronteras reintroduce exactamente los bugs de sincronización que la separación de clases existía para eliminar.
La regla que lo previene es de dueño único: cada pieza de estado tiene una sola herramienta que la posee, y las demás la leen de ahí sin copiarla. Si dos componentes necesitan la misma lista de servidor, ambos la piden con la misma clave a la cache, que deduplica; no la copian a un store compartido. Si un filtro vive en la URL, los componentes lo leen de la URL, no de una copia local que habría que mantener sincronizada. Un dato, un dueño: esa es la disciplina que hace que combinar herramientas sume claridad en vez de multiplicar el desorden.
// Dos componentes, un dueno: ambos leen de la cache con la misma clave.
function Cabecera() {
const { data } = useQuery({ queryKey: ['pedidos'], queryFn: traer }); // no copia
return <Contador n={data?.length ?? 0} />;
}
function Tabla() {
const { data } = useQuery({ queryKey: ['pedidos'], queryFn: traer }); // deduplica
return <Filas datos={data ?? []} />;
}
// una sola peticion, una sola verdad; ninguno guarda una copia en un store
Antes de guardar cualquier dato, pregúntate si ya vive en otra herramienta del stack. Si la respuesta es sí, no lo copies: léelo de su dueño. La tentación de duplicar por comodidad —tenerlo a mano en el store— es la grieta por la que se cuela el desorden que el stack prometía evitar. Un stack de cuatro herramientas con fronteras nítidas es más simple que uno de dos con fronteras difusas, porque la complejidad no está en el número de piezas sino en cuántos dueños tiene cada dato. Mantén ese número en uno y las cuatro herramientas convivirán sin rozarse.
El cierre: de la elección a la composición
Aquí termina el track, y conviene ver cuánto ha cambiado la pregunta desde el principio. Empezamos con la pregunta ingenua —qué gestor de estado es el mejor— y llegamos a entender que carecía de sentido, porque presuponía un ganador único para un problema que no es uno solo. La pregunta madura no busca la mejor herramienta: busca la combinación mínima donde cada clase de estado vive gobernada por lo que su naturaleza pide.
El stack de esta lección es el punto de partida razonable de 2026, no una obligación. Un proyecto ya montado sobre Redux Toolkit con RTK Query tiene un stack coherente y no debe migrar por moda; una app diminuta puede vivir con useState y la cache sin más; un dominio con muchos flujos críticos tendrá más máquinas que store. Los nombres concretos —TanStack Query, Zustand, XState— envejecerán y serán reemplazados por otros. Lo que no envejece es la forma del stack: una herramienta por clase de estado, fronteras limpias entre ellas, y disciplina proporcional al riesgo de cada pieza. Aprende la forma, no los nombres.
Todo el track cabe, al final, en un cambio de pregunta, y este stack es su respuesta encarnada. La pregunta con la que casi todo el mundo empieza —cuál es el mejor gestor de estado— es incontestable no porque falten datos, sino porque está mal formada: da por hecho que el estado es una cosa y que existe un campeón capaz de gobernarla entera. La pregunta con la que se termina —cómo compongo el conjunto mínimo de herramientas para que cada clase de estado viva donde su naturaleza pide— sí tiene respuesta, y la respuesta es este stack o cualquiera que respete su forma. El desplazamiento de la elección a la composición es la maduración completa de la disciplina. Elegir es un acto de consumidor: comparas productos y te quedas con uno, y todo tu estado se rinde a la forma de ese producto ganador. Componer es un acto de arquitecto: analizas el problema, descubres que tiene varias clases con dueños y formas incompatibles, y le das a cada una la herramienta diseñada para su naturaleza, aceptando que ninguna sirve para todo porque ninguna se pensó para todo. Por eso el ingeniero que ha recorrido este camino ya no pregunta qué usar, sino qué es cada pieza de su estado —de quién es su verdad, qué forma tiene, cuánto riesgo carga— y deja que esas respuestas dicten la composición. Las herramientas de hoy son las hojas más concretas de un árbol de decisiones que seguirá en pie cuando ellas hayan sido sustituidas, porque el árbol no es sobre TanStack Query ni sobre Zustand: es sobre la pluralidad irreducible del estado y la disciplina de darle a cada clase su sitio. Esa es la única lección que este track quería dejar grabada por encima de cualquier API, cualquier framework y cualquier moda: no colecciones herramientas ni busques la definitiva, aprende a mirar tu estado hasta ver de qué clases está hecho, y la arquitectura correcta será, casi siempre, la más pequeña que le da a cada clase lo que su naturaleza exige. Ese gesto —mirar el problema antes que la herramienta y componer en vez de elegir— no es una técnica más entre otras; es lo que significa, en el fondo, haber aprendido a diseñar estado.
- Toma una pantalla de tu app y clasifica cada pieza de estado en las cuatro clases: servidor, cliente, navegable, flujo crítico.
- Asigna a cada clase su herramienta del stack y escribe el componente que las orquesta las cuatro, como en el ejemplo.
- Verifica que ninguna herramienta conoce a las demás: la cache no toca el store, el store no toca la URL, la máquina no toca la cache.
- Identifica el único flujo de la pantalla que de verdad merece una máquina —modos excluyentes que no pueden fallar— y resiste ponerla en los demás.
- Justifica, clase por clase, por qué su herramienta es la mínima que resuelve su naturaleza y no un peldaño de más.
- Formula, en una sola frase que resuma el track entero, por qué la arquitectura de estado es composición y no elección.