Durante más de cuatro años mantuve la app de cine de eFilm. Como casi todo proyecto con tiempo encima, el estado global había crecido a base de Redux: actions, reducers, selectors y una capa de middleware que pocos querían tocar. Funcionaba, pero cada nueva feature pedía demasiado código repetido.

El problema no era Redux

Quiero ser justo: Redux no es el villano. El problema era la cantidad de ceremonia para algo tan simple como guardar si el usuario tenía el reproductor en silencio. Tres archivos para un booleano. La pregunta no fue «¿cómo arreglo Redux?», sino «¿cuánto de esto necesito de verdad?».

store/player.ts
// antes: action + reducer + selector
const toggleMute = () => ({ type: 'player/toggleMute' });
 
// después: todo en un store
const usePlayer = create((set) => ({
  muted: false,
  toggleMute: () => set((s) => ({ muted: !s.muted })),
}));

El mismo comportamiento, un solo lugar.

Migrar sin parar el barco

La regla fue clara: nada de un «big bang». Redux y Zustand convivieron durante semanas. Migré slice por slice, empezando por los más aislados (preferencias de UI) y dejando para el final los que tocaban la sesión y el reproductor.

«Una migración en producción no se mide por lo rápido que cambias, sino por lo poco que el usuario lo nota.»

Cada slice migrado venía con su prueba y un periodo de observación en producción antes de borrar el código viejo. Cero downtime, cero regresiones reportadas.

Lo que me llevo

Si estás con una decisión parecida, no migres por moda. Migra cuando el coste de mantener supere el de cambiar — y entonces, hazlo despacio.