El ADN común
Redux en JavaScript, la Elm Architecture, TCA en Swift y MVI en Android nacieron en cuatro rincones distintos del software y hablan lenguas que no se parecen. Y sin embargo, si les practicas una secuenciación genética, descubres que comparten el mismo genoma: estado inmutable, transición pura y flujo unidireccional. Esta lección abre el nivel presentando a las cuatro como fenotipos de un único diseño, no como cuatro inventos que casualmente se asemejan. La tesis es que la convergencia no fue plagio sino evolución convergente: cuatro comunidades resolviendo el mismo dolor llegaron, por presión selectiva, a la misma forma. Aislamos aquí los tres genes que todas llevan dentro.
Cuatro arquitecturas nacidas en cuatro rincones distintos del software —Redux en la web de JavaScript, la Elm Architecture en el navegador funcional, TCA en el iOS de Swift y MVI en el Android de Kotlin— hablan lenguas que no se parecen y crecieron en comunidades que apenas se leían entre sí. Y sin embargo, si les practicas una secuenciación genética, descubres que comparten el mismo genoma. No son cuatro inventos independientes que por azar se asemejan: son cuatro fenotipos de un único diseño, la misma idea vestida con cuatro trajes distintos. Este nivel entero es esa secuenciación, y arranca aquí, aislando los tres genes que todas llevan dentro: estado inmutable, transición pura y flujo unidireccional. Cuando los reconozcas, dejarás de aprender cuatro herramientas y empezarás a ver una sola idea repetida cuatro veces.
- Reconocer
Redux,Elm,TCAyMVIcomo fenotipos de un mismo genoma y no como inventos separados. - Aislar los tres genes compartidos: estado inmutable, transición pura y flujo unidireccional.
- Ver cómo ese ADN se expresa en
JavaScript,Elm,SwiftyKotlinsin dejar de ser el mismo. - Entender por qué la convergencia fue evolución y no copia: la misma presión produjo la misma forma.
Cuatro organismos, un mismo genoma
Las cuatro surgieron para curar, cada una en su plataforma, el mismo dolor: interfaces que crecían hasta volverse impredecibles porque el estado podía cambiar desde cualquier parte y por cualquier vía. Ninguna se propuso fundar una familia; cada una intentaba, sin más, hacer manejable una aplicación que se le iba de las manos. Que acabaran emparentadas fue un hallazgo posterior, no un plan.
Redux cristalizó en 2015 de la mano de Dan Abramov y Andrew Clark, cruzando el patrón Flux de Facebook con una idea tomada de Elm: un solo store y una función pura que calcula el estado siguiente. Su charla de presentación, con el viaje en el tiempo en vivo, convenció a una generación entera de que el estado predecible no era un lujo sino algo alcanzable.
Fue la primera de la familia en volverse mainstream y, por eso, la que fijó el vocabulario que las demás heredarían o discutirían. Cuando hoy decimos acción, reducer o store, hablamos, sin saberlo, el idioma que Redux normalizó.
La Elm Architecture —conocida como TEA— la había destilado antes Evan Czaplicki en un lenguaje funcional puro pensado para el navegador, donde la pureza no era una recomendación sino una ley del compilador. TCA, The Composable Architecture, la llevó a Swift el equipo de Point-Free hacia 2020, obsesionado con la composición y el testing. Y MVI —Model-View-Intent, con raíces en el Cycle.js de André Staltz y popularizado en Android por Hannes Dorfmann— hizo lo propio en Kotlin, primero como artículos de blog y luego como bibliotecas.
Plataformas distintas, casi una década de diferencia, comunidades que apenas se citaban. Y aun así, el mismo esqueleto por debajo.
Lo asombroso no es que se parezcan, sino que se parezcan sin haberse copiado el código: no hay un ancestro común del que las cuatro desciendan por herencia directa, hay cuatro linajes que, sometidos a la misma presión, desarrollaron el mismo órgano. Cuando dos comunidades comparten una librería, la semejanza no sorprende; cuando cuatro mundos que no se hablan dan con la misma forma, la semejanza pide una explicación más profunda que el préstamo.
En biología eso se llama evolución convergente. El ojo del pulpo y el ojo humano no comparten un ancestro con ojos; comparten el problema de ver, y la física de la luz solo admite unas pocas soluciones buenas. El flujo unidireccional es a la interfaz interactiva lo que el ojo es a la visión: la forma a la que se llega, una y otra vez, cuando el problema aprieta lo suficiente.
La familia, además, es más grande que sus cuatro miembros canónicos. Vuex y Pinia en Vue, NgRx en Angular, Mobius de Spotify, Orbit en Android o el propio useReducer que React trae de fábrica son primos cercanos que comparten el mismo genoma. Elegimos estos cuatro porque cada uno lleva un gen a su extremo y porque juntos cubren las tres grandes plataformas, pero lo que aprendas aquí se aplica a todos ellos.
Redux · web / JavaScript
Un único store con reducers puros. La lengua franca del estado en el frontend, la puerta de entrada a toda la familia y la que fijó el vocabulario común.
Elm · navegador funcional
Model, update y view. La forma más pura del patrón, porque un lenguaje sin efectos secundarios no te deja hacer trampas ni aunque quieras.
TCA · iOS / Swift
State, Reducer, Store y Effect. La versión más componible y más testeable de la familia, nativa de las plataformas de Apple.
MVI · Android / Kotlin
Un State inmutable, un Intent que lo pide y un reductor sobre Flow. El flujo unidireccional idiomático del Android moderno con Compose.
Los tres genes del flujo unidireccional
Un genoma no es el organismo: es el juego de instrucciones que lo construye. El genoma de esta familia cabe en tres genes, y basta con que falte uno para que el organismo ya no pertenezca a ella.
Conviene enunciarlos por separado, aunque solo funcionen juntos, porque cada uno cierra una puerta distinta por la que se colaría lo impredecible.
El primer gen es el estado inmutable: todo el estado de una pantalla vive en un valor que nunca se muta, solo se reemplaza. En Redux es el árbol del store; en Elm, el Model, inmutable por decreto del lenguaje; en TCA, un struct State con semántica de valor y copia sobre escritura; en MVI, una data class que se rehace con copy. Cuatro nombres para un mismo gen: el estado es un valor, no un objeto que alguien edita por dentro a tus espaldas.
El gesto que lo encarna es siempre el mismo —reemplazar en lugar de mutar—, y cada dialecto tiene su forma de escribirlo sin tocar el estado anterior.
JS / Redux: const siguiente = { ...estado, contador: estado.contador + 1 }
Kotlin/MVI: val siguiente = estado.copy(contador = estado.contador + 1)
Elm: { model | contador = model.contador + 1 }
Swift/TCA: state.contador += 1 // sobre una copia de valor con semantica inout
El segundo gen es la transición pura: el cambio se expresa como una función que recibe el estado y un hecho, y devuelve el estado siguiente sin tocar el viejo ni provocar efectos. La firma (estado, accion) => nuevoEstado es el reducer de Redux, el update de Elm, el Reduce de TCA y el reductor de MVI.
Esa pureza es determinista de raíz: la misma entrada produce la misma salida, hoy, mañana y en otra máquina. De ella cuelgan el viaje en el tiempo, el testing sin montar nada y la hidratación en servidor, porque una función determinista es lo único que se puede reproducir a voluntad las veces que haga falta.
El tercer gen es el flujo unidireccional: la información viaja en un solo sentido y por un solo carril. La vista emite un hecho con nombre, la transición calcula el estado nuevo, y ese estado se proyecta de vuelta sobre la vista.
No hay atajos laterales ni escrituras directas desde la interfaz; el ciclo se cierra siempre por el mismo sitio, y por eso cada cambio tiene una causa nombrada y rastreable. Es la misma dirección única que viste nacer con Flux en el nivel anterior, aquí elevada a invariante de toda una familia y de tres plataformas.
flowchart TD R[Redux en JavaScript] --> N[genoma unidireccional] E[Elm Architecture] --> N T[TCA en Swift] --> N M[MVI en Android] --> N N --> G1[estado inmutable] N --> G2[transicion pura] N --> G3[flujo unidireccional] style N fill:#cba6f7,color:#11111b style G1 fill:#a6e3a1,color:#11111b style G2 fill:#89b4fa,color:#11111b style G3 fill:#f9e2af,color:#11111b
Los tres genes no son una lista de la que puedas tomar dos: son un contrato de tres cláusulas donde cada una sostiene a las otras. El estado inmutable sería inútil si cualquiera pudiera cambiarlo por su cuenta, y por eso hace falta el flujo unidireccional que obliga a pasar por un solo carril. Y ese carril solo es tratable si lo que ocurre en él es una transición pura e inspeccionable, no un método que muta por dentro.
La consecuencia práctica de que sean un contrato y no una lista es que una herramienta con dos de los tres genes no es un miembro tibio de la familia, sino otra cosa. Un store que muta libremente tiene fuente única pero no transición pura, y pierde el time-travel y la reproducibilidad. Un signal crudo tiene reactividad pero ni hecho con nombre ni flujo único, y con él vuelve el estado que cambia a tus espaldas. La prueba de pertenencia no es el parecido superficial, sino la presencia de los tres.
Un genoma, cuatro dialectos
La prueba más limpia de que hablamos de un solo diseño es poner las cuatro firmas de transición una debajo de otra. Cambia la sintaxis, cambia el lenguaje, cambia hasta el nombre del hecho —acción, mensaje, intención—.
Pero la gramática es idéntica: entra un estado y un hecho, sale un estado. Lo que varía es dialecto, no lengua, y confundir el dialecto con la lengua es lo que hace que un ingeniero crea que empieza de cero cada vez que cambia de plataforma.
Redux (JS): (state, action) => State
Elm: update : Msg -> Model -> ( Model, Cmd Msg )
TCA (Swift): func reduce(into state: inout State, action: Action) -> Effect<Action>
MVI (Kotlin): fun reduce(state: State, intent: Intent): State
Léelas despacio y verás que la coincidencia es estructural, no cosmética: en las cuatro hay exactamente un estado de entrada, exactamente un hecho, y exactamente un estado de salida. Ni una recibe dos estados, ni devuelve una lista de vistas, ni acepta un puñado de argumentos sueltos. Esa disciplina de forma es el genoma hecho firma.
Las diferencias que sí se ven en las firmas no son casuales, pero tampoco tocan el genoma. El inout de TCA y el par ( Model, Cmd Msg ) de Elm son maneras de devolver, junto al estado, una descripción de los efectos que hay que ejecutar. Donde Redux deja el efecto fuera de la firma, Elm y TCA lo incorporan como un valor más de retorno.
Esa grieta —dónde y cómo se tratan los efectos— es la primera por la que asomará lo que diferencia a la familia, y le dedicaremos una lección entera. Por ahora basta con retener que la diferencia vive en la frontera con el mundo, no en el corazón: el corazón es idéntico en las cuatro.
El error de lectura más caro que puedes cometer en este nivel es tratar a Redux, Elm, TCA y MVI como cuatro asignaturas. No lo son. Son un único teorema demostrado en cuatro lenguajes distintos, y quien lo entiende deja de coleccionar frameworks para dominar un principio portátil. La consecuencia práctica es enorme: el ingeniero que ha internalizado los tres genes puede aterrizar en iOS sin haber tocado Swift y reconocer TCA a la primera, o abrir un proyecto Android y leer su MVI como si fuera Redux con otro acento. La cuarta arquitectura, para quien domina la primera de verdad, no es una montaña: es reconocer un rostro conocido bajo un sombrero nuevo. Y hay una lección más honda todavía. Que cuatro comunidades aisladas dieran con la misma forma no es una anécdota simpática: es la señal de que el flujo unidireccional no es una moda de una era ni el gusto de un gurú, sino algo más parecido a una ley descubierta que a una convención inventada. Las modas divergen; las leyes convergen. Cuando veas convergencia tan limpia entre mundos que no se hablaban, sospecha que estás ante una verdad estructural del software interactivo, no ante una tendencia que caducará con la próxima conferencia. Estudiar la familia entera no es, entonces, aprender a cambiar de trabajo entre plataformas: es aprender la única gramática con la que se escribe el estado predecible en cualquiera de ellas.
Por qué esto no es una coincidencia
La objeción natural a todo lo anterior es que quizá se copiaron y punto: Redux nació de Elm, así que no habría misterio. Pero eso solo explica una rama del árbol. TCA y MVI no imitaron a Redux por moda, sino porque sus plataformas adoptaron interfaces declarativas —SwiftUI y Jetpack Compose— y una interfaz declarativa exige un estado único del que derivar la vista. La causa profunda no fue la imitación, sino la presión.
Ese es el hilo que tira la última lección del nivel: por qué la web, iOS y Android convergieron. Adelantamos aquí solo la forma del argumento, porque cambia cómo lees el resto: cuando tres plataformas que no se coordinan dan con la misma solución, la explicación robusta no es el contagio cultural, sino que el problema solo admitía esa solución. La coincidencia sería que difirieran, no que coincidan.
Conviene además desactivar desde ya un reflejo tribal. Quien viene de la web tiende a ver a TCA y a MVI como imitaciones tardías de Redux, y quien viene del mundo funcional ve a Redux como un Elm descafeinado. Ambas lecturas son parroquiales. Ninguna de las cuatro es la original de la que las otras copian: son cuatro respuestas paralelas, y cada una acertó en algo que las demás hacen peor, como veremos en la lección sobre qué aprender de cada una.
Con esto queda planteada la agenda del nivel. Primero mediremos qué comparten exactamente, con criterio de verificación y no con metáfora. Luego veremos qué las diferencia en la frontera del efecto y en la composición. Después destilaremos la virtud que cada una perfeccionó. Y cerraremos con la convergencia entre plataformas y la foto de 2026.
En 2026 los cuatro organismos gozan de salud muy distinta: Redux cedió su trono, Elm como lenguaje está casi congelado, TCA vive su madurez y el MVI de Android es doctrina oficial de Google. Y aun así el genoma está más vivo que nunca, porque no aprendes herramientas que podrían retirarse, sino el código genético que sus herederas seguirán heredando. La cuarta lección volverá sobre esto; por ahora, quédate con que la forma es más duradera que cualquiera de sus encarnaciones.
- Coloca las cuatro firmas de transición una bajo otra y subraya lo común: en todas entra un estado y un hecho con nombre, y en todas sale un estado nuevo.
- Recuerda un bug real —un estado que cambió sin que supieras quién lo tocó— y razona cuál de los tres genes lo habría hecho imposible por construcción.
- Elige la arquitectura de la familia que menos conozcas y localiza en su documentación de 2026 dónde vive exactamente cada uno de los tres genes.
- Aplica la prueba de pertenencia a una librería que uses hoy y decide, gen por gen, si es de la familia o solo se le parece.
- Traza en un papel el ciclo de flujo unidireccional para las cuatro y comprueba que dibujas el mismo diagrama cambiando solo las etiquetas.
- Escribe en una sola frase por qué “evolución convergente” describe mejor a esta familia que “copia”, y guárdala: es la tesis del nivel entero.