“Simple, pero no fácil” es probablemente el principio que más define cómo pienso el desarrollo.

No es mío, obviamente. Pero lo llevo conmigo como un mantra cada vez que tomo una decisión de código, de arquitectura o de proceso.

Y cuanto más laburo en esto, más convencido estoy de que es la diferencia entre un sistema que se mantiene y uno que se pudre.

Simple no es fácil

Acá hay una confusión que veo todo el tiempo.

Fácil es lo que se hace rápido. Lo que no requiere pensar mucho. Lo que sale natural. Agregar un if más en vez de repensar la condición. Meter una librería en vez de entender el problema. Copiar y pegar ese componente porque total, “son dos líneas”.

Simple es otra cosa. Simple es lo que se entiende. Lo que no necesita explicación adicional. Lo que está tan bien separado que cada parte hace una sola cosa y la hace bien.

El problema es que hacer algo simple requiere entenderlo en profundidad. Y entender en profundidad lleva tiempo, criterio y experiencia.

Lo fácil es instantáneo. Lo simple es el resultado de iterar, refactorizar, borrar y volver a pensar.

Lo fácil es el atajo. Lo simple es el camino que encontrás después de conocer todo el terreno.

El costo invisible de lo fácil

Cada vez que elegís lo fácil en vez de lo simple, estás pateando deuda para adelante.

No es una cuestión de ser purista. Es una cuestión de costo real.

Pongamos un ejemplo concreto que vi mil veces. Tenés que mostrar una lista de cosas con un filtro. Lo fácil:

function Lista({ datos, filtro }) {
  const [resultados, setResultados] = useState([]);

  useEffect(() => {
    if (filtro === "activos") {
      setResultados(datos.filter(d => d.activo));
    } else if (filtro === "inactivos") {
      setResultados(datos.filter(d => !d.activo));
    } else {
      setResultados(datos);
    }
  }, [datos, filtro]);

  return /* ... */;
}

Funciona. Pasa los tests. Se mergea el PR.

Seis meses después ese componente tiene 14 condiciones, 8 useEffect, datos que vienen de tres fuentes distintas y un bug que solo pasa en producción los viernes.

Lo simple hubiera sido preguntarse antes: ¿de dónde vienen estos datos? ¿quién es responsable del filtrado? ¿esto va en el componente o en una capa de dominio? ¿hay una abstracción que me evite el if/else?

Lo simple hubiera sido escribir un selector, un hook dedicado o —incluso— reconocer que quizás este componente ni siquiera debería existir.

Lo simple se piensa antes. Lo fácil se arregla después. Y a veces, ya es tarde.

La falsa dicotomía entre velocidad y simplicidad

Otra cosa que escucho seguido: “no tenemos tiempo para hacerlo simple, necesitamos entregar”.

Y lo entiendo. Los deadlines existen. El negocio apura. Pero acá hay una trampa mental: asumimos que hacerlo simple demora más.

A veces sí, a veces no. Pero lo que siempre es cierto es que hacerlo fácil demora más en el mediano plazo. El tiempo que “ahorraste” lo vas a pagar con intereses en debugging, en onboarding de gente nueva, en features que deberían ser triviales pero tocan código que nadie entiende.

Conozco sistemas que llevan años en producción y se mantienen con confianza. Y conozco sistemas que a los 8 meses ya son tierra de nadie. La diferencia nunca es la tecnología. La diferencia es si alguien se tomó el laburo de hacer las cosas simples.

No es minimalismo, es criterio

Ojo, no estoy diciendo que todo tiene que ser mínimo o que hay que sobre-ingenierizar todo.

Simple no significa “pocas líneas”. Simple significa que cada línea tiene una razón clara de existir.

A veces lo simple es una función de 3 líneas. A veces lo simple es una clase con 200 líneas porque el dominio lo pide. A veces lo simple es reconocer que dos cosas que parecen iguales en realidad no lo son y merecen estar separadas.

El criterio está en saber cuándo separar y cuándo unir. Y eso no te lo da ningún framework ni ninguna guía de estilo. Te lo da haber mantenido código que no entendías, haber sufrido abstracciones prematuras y haber visto las consecuencias de las decisiones fáciles.

Cómo sé si estoy haciendo algo simple

Con el tiempo desarrollé un par de pruebas mentales que me ayudan:

1. La prueba del junior. Si llega alguien nuevo al equipo, ¿puede entender qué hace esto sin que yo le explique? No digo que pueda extenderlo —digo entenderlo. Si necesita un diagrama y una reunión de una hora, probablemente no es simple.

2. La prueba del cambio. Si cambia un requerimiento chico, ¿toco un solo lugar o tengo que perseguir modificaciones por todo el proyecto? Si tengo que abrir 8 archivos para cambiar un texto, hay algo que no es simple.

3. La prueba del “por qué”. ¿Puedo explicar por qué cada pieza existe sin decir “porque siempre lo hicimos así” o “porque el tutorial decía”? Si no tengo una razón clara para algo, probablemente sobra.

Ninguna de estas pruebas es infalible. Pero en conjunto, me han salvado de meter más complejidad de la necesaria incontables veces.

Lo simple da miedo

Hay algo que no se dice mucho: hacer las cosas simples requiere coraje.

Coraje para decir “esto no está listo, necesita otra iteración”. Coraje para borrar código que funciona pero que es confuso. Coraje para admitir que esa abstracción que hiciste hace dos semanas era innecesaria.

Lo fácil te da la dopamina del PR mergeado. Lo simple te da la confianza de desplegar un viernes a las 5 de la tarde y desconectarte tranquilo.

Elegí cuál querés.