Decisiones escalables, no se trata solo de crear tareas
Tags: frontend, escalabilidad, productivity, programming
Published: 2023-09-27 15:48:45

Artículo de la serie [**¿Que es escalable?, Y que lo es en el desarrollo frontend?**](https://dev.to/eltupac/que-es-escalable-y-que-lo-es-en-el-desarrollo-frontend-4loj).

Foto de <a href="https://unsplash.com/es/@homajob?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Scott Graham</a> en <a href="https://unsplash.com/es/fotos/5fNmWej4tAA?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>

---

Este tópico lo quiero dedicar a la decisión que se toma sobre las tecnologías a utilizar en los proyectos, que suele llevar más trabajo escribir las tareas de implementación, que el de estudiar y fundamentar porque vamos a usarlas. Por ejemplo: que funcionalidad nos provee?, porque tiene sentido dejar esa dependencia a cargo de una librería externa y/o porque tendríamos que desarrollarlo _in-house_. Yo me siento muy apasionado por esta parte, ya que realmente disfruto mucho del hecho de pensar cuales serían las mejores opciones para llevar a cabo cada proyecto. He tenido la suerte de que en más de una ocasión tuve la posibilidad de hacer esta selección y en todos los casos con un estudio por detrás de porqué escogí cada una.
Cabe mencionar que a pesar de siempre poner mucho empeño en elegir el mejor stack tecnológico a la hora de empezar un nuevo proyecto, también presencié muchos desastres en este sentido. Y con esa breve introducción advierto que esta sección puede ser omitida por aquellos que no estén tan interesados, no se sientan interpelados, o tan solo sean totalmente escépticos en la decisión del stack tecnológico en sus proyectos/trabajos.

Me he encontrado que muchas personas no les importa cómo queda la estructuración del stack tecnológico; y también he encontrado algunas personas que siempre están en la búsqueda del **stack perfecto**, que sirva para todo y que se pueda usar para cualquier situación o problema. Hago un llamado de atención aquí, porque no existe el **stack perfecto** como tal, que pueda abarcar todas las problemáticas. Existen algunos frameworks/librerías que apuntan a eso, por ejemplo **Next.js**, pero aun así a veces termina siendo una solución muy grande, pesada y costosa para desafíos que no presentan tal necesidad.
Un ejemplo rápido para entenderlo sería si: _necesito hacer un panel administrativo, con autenticación para todas las cosas, y será usado principalmente para que el personal interno pueda acceder a datos de clientes mientras habla con ellos_. Yo no creo que ninguna de las prestaciones fuertes que ofrece **Next.js** sirva para resolver esa problemática(SSR, embedded API, SSG, etc.); en cambio crear una simple SPA hecha con **Vite** (o cualquier librería/framework similar)reduciría costos, complejidad de desarrollo e infraestructura necesaria.
Y eso es solo un ejemplo hablando del framework/librería base que se encarga de las cosas más globales(enrutamiento, compilar el código, infraestructura que demanda, etc.), pero no voy a profundizar mucho en los aspectos de la relación _"problemática vs stack tecnológico"_ (más adelante en este artículo hablo más sobre las librerías de **componentes de UI** y **manejo de estado**), y voy a continuar mostrando otra importante relación, el _"capital académico vs stack tecnológico"_.
Digamos que tengo mi equipo de desarrolladores, y la mayoría de ellos tiene experiencia principalmente con tecnologías basadas en React. Pasaría por la cabeza de alguna persona cambiar el stack tecnológico para Angular/Vue? Sabiendo que muchos de los desarrolladores van a necesitar un tiempo de capacitación en esa tecnología que no tienen experiencia, ¿La empresa/el equipo puede permitirse ese tiempo de capacitación? ¿Los desarrolladores impactados por esta decisión (o al menos la mayoría), realmente están cómodos con ese cambio abrupto de stack?
Esas mismas preguntas las podemos plantear para casi cualquier cambio de tecnología en el ámbito que sea, algunas tendrán poco impacto, porque capas sean similares entre sí(ejemplo: **styled-components** y **emotion**); y otras tendrán mucho impacto(ejemplo: **React** vs **Angular** vs **Vue**, **Zustand** vs **Redux** vs **Mobx**). Ese impacto será desde código de mala calidad por no tener experiencia, hasta desarrolladores renunciando porque no se sienten cómodos ante estos cambios. Y estas situaciones que parecen distópicas, donde los cambios llevan a destruir el grupo de trabajo, son más comunes de lo que creemos, y yo encuentro una causa muy clara en estos casos.

> Es casi costumbre que el stack tecnológico debe ser definido por personal "_idoneo_", como si los desarrolladores no tuvieran idea de lo que realmente es mejor para un sistema. Por eso muchas veces las empresas optan por delegar estas decisiones a equipos que trabajan solo para tomar estas decisiones de tecnologías, ajenos totalmente al desarrollo en sí mismo.

Entiendo que hace algunos años esos equipos tenían una buena reputación, porque eran como los que tenían la _"posta"_ de lo que funcionaba. Pero eso no es lo que se ve reflejado en el presente de las empresas que conozco y/o que recibo comentarios. Y en mi experiencia solo me encontré que estos equipos hacen propuestas con stacks tecnológicos que encontraron en un blog o que ya funcionó para otro proyecto, donde modifican un poco la estructura para que sea más "**escalable**" a su manera y listo, descartando totalmente el contexto de los equipos que fuesen a ejecutar y desarrollar sobre esas tecnologías.
Con esto podríamos imaginar y recrear la situación más distópica para un equipo de desarrolladores, porque ahora el desarrollador debe agarrar ese stack que alguien más decidió por él (que a veces ni tiene experiencia en alguna de sus partes), adaptarlo para la problemática que tenga que resolver, que a veces tendrá que hacer alguna cosa extraña para resolver algún gap entre el stack y las reglas de negocio pautadas. Tendrá que seguir un diseño, y el design system que pusieron en el stack tecnológico probablemente tenga que ser modificado para poder alinear con lo que se pide. Y si ninguno de los desarrolladores tiene experiencia suficiente en alguna de las tecnologías usadas, probablemente las primeras versiones tengan algún problema de performance o poca calidad en la escritura de su código.

Con esto quiero hacer entender como una mala decisión de las tecnologías puede repercutir tanto en la calidad final del proyecto como en el equipo que lo desarrolla. Y no es mi intención criticar o definir quién debe ser el encargado de elegir las tecnologías a utilizar, pero si estoy muy a favor de que el mismo equipo encargado del desarrollo sea quien tome esas decisiones. Como situación utópica con la que me siento más cómodo(como desarrollador), es que las tecnologías sean elegidas por los programadores, que luego tendrán que utilizar ese stack, sabiendo cuales son los campos de experiencia y especialidad del equipo, obviamente sin perder la objetividad al momento de elegir un stack que sea moderno, porque que haya desarrolladores que hayan tenido mucha experiencia y les sea familiar jQuery, no puede ser tomado como fundamento, bajo ningún punto de vista, para elegir jQuery como tecnología hoy en dia.

Para cerrar esta idea voy a dar un ejemplo donde tuve que elegir las tecnologías para el proyecto de un e-commerce. Era necesario tener obviamente un buen SEO, para que los productos sean indexados en los motores de búsqueda, y eso era lo principal. Para esto elegimos Next.js, usándolo con server side rendering ya que la plataforma en ese momento tenía más de 10 mil productos. Una de las decisiones más difíciles de plantear fue si íbamos a trabajar con Javascript plano o Typescript. Parece algo raro preguntarse eso actualmente, pero voy a explicar a qué venía esta incertidumbre. Para desarrollar este frontend, con objetivo de dejar de utilizar la plataforma Shopify, teníamos 8 personas en el equipo y muy poco tiempo, el deadline desde el kickoff del proyecto eran 2 meses. De esas 8 personas, solo 3 teníamos experiencia en Typescript, las otras 5 personas iban a tener que empezar a aprenderlo, y además aprender otras tecnologías como GraphQL, el entorno de Next.js(no era ampliamente adoptado en ese momento); y como frutilla del postre también desarrollar el design system que iba a utilizar nuestro front end. Poniendo todas las cosas en la balanza, decidimos que Typescript solo iba a complicar y retrasar las cosas, entonces decidimos seguir con Javascript plano. Fue una decisión correcta, y llegamos a entregar lo prometido a tiempo, después por otras cosas se retrasó el release en general, pero fue ajeno a nuestro contexto. Tiempo después de esto, recibí muchísimas críticas de nuevas personas que fueron sumándose a la empresa, diciendo que había sido la peor selección de tecnologías que una persona pudo haber hecho. Esos comentarios en su momento me afectaron bastante, pero lo superé con el tiempo ya que esas personas lo dijeron desde la ignorancia total, ellos ya tenían un equipo con un Seniority muchisimo mas alto del que yo tenía en su momento; y nosotros además teníamos un deadline super apretado para entregar todo un ecommerce de 0 funcionando.
Pongo mi ejemplo para que no solo sepan cómo elegir las tecnologías en base al conocimiento que hay en el equipo que va a encargarse del desarrollo, sino también para que no hagan una crítica destructiva sobre cuáles fueron las elecciones de esas tecnologías si desconocen el contexto del momento en que las eligieron. Aunque sí sugiero que vean cuales son las posibilidades de mejora que tienen esos proyectos.

---

Ahora voy a entrar en algunos temas que puede generar algo de controversia, las librerías de **componentes UI** y las de **manejo de estado**. Y digo que puede generar controversia porque las librerías más populares del mercado actualmente no me parecen para nada útiles a la hora de pensar en un proyecto escalable, y obviamente daré mi punto de vista para que se entienda.

Primero vamos a ver los componentes de UI, y algunas características que yo veo muy importantes a la hora de elegir una librería de componentes:
- Debe tener un naming convention que se respete a todo momento, tanto en los nombres de los componentes, como en sus propiedades, eventos, etc.
- Debe tener algún sistema de theme que permite customizar estilos generales del mismo, colores, espacios, etc.
- Tiene que ser compatible con las otras librerías sin necesidad de estar haciendo workarounds para funcionar. Por ejemplo con Typescript, con Next.js y su SSR, con el bundler(Webpack, SWC, es-build), etc.
- Debe respetar los estándares de accesibilidad.
- Una documentación clara.
- Que al implementarlo no sea como ensuciar el código, quitando legibilidad, siendo poco intuitivo.
- Que la curva de aprendizaje sea baja, no tiene que representar un desafío usarla.
- Es obvio, pero que no tenga errores, que no represente un riesgo utilizarla.
- Debe tener una variedad de componentes considerable; si tiene pocos podríamos necesitar instalar otras librerías para complementar, lo cual podría terminar generando inconsistencias en los estilos.

Y la mayoría de estos puntos no son siempre características de las librerías más adoptadas, y voy a poner como ejemplo **MUI**(Material UI), que para muchos es la mejor librería de componentes, y en mi experiencia es muy deficiente. Pero antes de comenzar a mostrar todo eso, voy a dar el contexto de la creación de MUI y porque la librería que se ofrece al mercado es tan solo un parche de la versión inicial.
Google lanzó su librería **MUI** en 2014, escrita plenamente en Javascript para usarla con React, al momento de escribir esto son casi 9 años. La versión 5 salió en septiembre de 2021, y ya encontramos algunos red flags desde mi perspectiva:
- La librería sigue teniendo el 50% de su código en Javascript plano.
- Entre las pocas razones para hacer la versión 5 encontramos que fue para que la librería sea compatible con las últimas versiones de React, porque tuvo muchos problemas de compatibilidad, y encontramos que aun así cuando salió tuvo muchísimos issues abiertos, principalmente debidos a la compatibilidad con React.
- Entramos a los issues en Github y vemos que hay muchos, realmente muchos issues abiertos y categorizados como "bugs".

Ahora, todos esos puntos no serian tan pesados si habláramos tal vez de un proyecto Open Source, pero encontramos que **MUI** está siendo mantenida por Google, y que además tiene una versión paga donde tiene la colección completa de componentes. Y para agregar un punto más a la lista, si intentaron usar los componentes de DatePicker, que solo están disponibles pagando la librería, funcionan muy mal, las traducciones a idiomas como el Portugues está mal hecha, la accesibilidad es dudosa y en algunos casos desastrosa, y ni siquiera podemos cambiar la variante de estilos del componente (con la propiedad "variant") cómo se podría hacer con cualquier otro componente de input dentro de **MUI**. Y ni siquiera voy a entrar en cuestiones UX donde hay varias críticas al sistema de label flotante que utiliza, el cual puede generar confusión y dolores de cabeza en formularios largos.
Entonces todo este contexto junto solo muestra que la librería que hay actualmente, es tan solo un parche encima del otro de lo que fue la versión inicial de la misma, con el objetivo de intentar "adaptarse" a las nuevas versiones y tecnologías en auge.

Ahora la gran pregunta que surge después de plantear todo esto, ¿Y entonces qué elijo? Actualmente hay más variedad de librerías, en su mayoría Open Source, que cubren una buena parte de las necesidades que tenemos a la hora de elegir una librería de componentes UI. Yo voy a dar una lista de ejemplos de librerías actuales que traen una lavada de cara a la mala fama que existe sobre las mismas(me gustaria ampliar en número, pero estan son las que tengo en mente ahora mismo):
- [Mantine](https://mantine.dev/)
- [Radix-UI](https://www.radix-ui.com/)
- [Headless UI](https://headlessui.com/)

Mi intención no es que elijan de esa lista, pero sí que vean lo que ofrecen de mejoras ante la supremacía de las librerías más establecidas en el mercado, con alto número de descargas y uso.

---

Ahora pasaré a las librerías de manejo de estado, donde voy a decir que el uso de _la más conocida_ es tan específico que es muy fácil reemplazarla con otras opciones, que no sean tan complicadas y abstractas. Y de la misma forma que hice con las librerías de UI no voy a entrar tanto en la cuestión de código, porque eso no pertenece al tópico de este artículo sino a uno de los próximos donde voy a hablar específicamente de eso.

Yo ya estoy siendo consciente de varios de los comentarios que tendré que leer, "Vos porque no entendes como funciona Redux, entonces decis cualquier cosa". No busco justificar mi posición, pero sí comentar que ya tuve que trabajar con Redux, y con Redux Toolkit más recientemente, y en ambas ocasiones tuve que estudiar bastante a fondo para entender cuál es la finalidad y la filosofía por detrás de Redux. Realmente lo veo como un mal necesario cuando llegamos a un proyecto tan grande que haga falta un _increíble_ motor para manejar los estados, y el único/mejor ejemplo que se me ocurre es una arquitectura con micro-frontends. Y fuera de ese ejemplo, la arquitectura necesaria para micro-frontends, **Redux** es un overkill, sobre ingeniería y abstracción muy grande. Y en ese momento hay que poner en la balanza si el proyecto será desarrollado por gente con el seniority suficiente como para entenderlo, porque con el tiempo se empieza a ver la complejidad que agrega tener un manejo de estado abstraído en Redux.

Entonces es realmente importante saber: ¿Qué tan necesaria es esa capa de abstracción que agrega Redux?, ¿Mi proyecto realmente lo necesita?
Piensen que crearon Redux Toolkit a modo de simplificar la implementación del mismo Redux porque es muy complejo de entender, y aun así la gente más Junior no logra descifrar que es lo que hace. ¿No hay otra solución que sea más simple y de las mismas prestaciones?
Fijense que Redux es _opinionated_(que tiene una sola forma correcta de usarlo, lo demas esta mal), ¿Voy a tener que adaptar siempre mi estructura al manejo de los estados?, ¿No existe al revés, el manejo de estado que se adapta a mi lógica de negocios, a mi estructura, arquitectura?.
Y si, existen otras alternativas a Redux, y voy a nombrar las que seguramente ya escucharon:
- Zustand
- createContext(nativo React)

Aunque _createContext_ este atrelada a React, es una gran solución para cuando el proyecto no es muy extenso. Para los que lo hayan usado, sabrán que una vez que el manejo de estado empieza a ser muy complejo se complica mucho mantener los contextos. Pero para un proyecto chiquito, con un manejo de estado más simple, es asegurado que va a servir muchísimo.

Pero la librería que más me ha llamado la atención fue Zustand, justamente surge casi como la contra parte a Redux, ofreciendo un manejo de estado que lo podemos adaptar a nuestro entorno de desarrollo, sin tener que seguir las reglas paso a paso y evitando **copiar y pegar** sin entender lo que hace. No lo quiero plantear como una crítica a Redux, pero al final lo termina siendo. Además, ofrece una simplicidad mucho mayor en la abstracción de los stores, casi que no se siente que sea una capa ultra separada de todo, que no se toca con el código UI que implementamos.

Al momento de escribir esta parte vi un meme que dice "Todos hablan de la experiencia de usuario, pero nadie piensa en la experiencia del desarrollador", y aunque fuese tan solo un meme todo esto lo pienso de esa forma. Que el proyecto tenga una armonía entre sus partes, con una buena elección de tecnologías, siempre ayuda a que la experiencia de desarrollo sea mucho mejor y hasta en cierto punto placentera. Y todas estas elecciones las tendríamos que hacer siempre que vamos a empezar un nuevo proyecto? **Si**, pero no es una posibilidad que exista en general, y muchas veces cuando la posibilidad está abierta, el tomador de decisiones ya tiene un paquete elegido. Eso no quiere decir que siendo simples desarrolladores no puedan aportar a esas decisiones. La idea es siempre uno poder llevar la impronta de algo nuevo, moderno o hasta de cuestionar las decisiones, preguntando ¿porque _esto_ y no _aquello_?

Mi idea en este tópico fue que se haga hincapié en los temas que los hype, modas, tendencias o como quieran decirle, tienen ya seteados como default en nuestro sentido común; por ejemplo que si quiero hacer un frontend usar **Redux** y **MUI** va a ser una decisión totalmente válida para cualquier situación, cuando realmente no es así. A veces, estas cosas pueden ser muy obvias para alguien que ha tenido años desarrollando con varias tecnologías, y puede observar estas diferencias de prestaciones que ofrece cada tecnología, pero una persona sin tanto tiempo en el rubro podría confundirse fácilmente por no hacerse las preguntas correctas al momento de elegir.