En la última década, la tecnología ha evolucionado rápidamente, llevando a la creación de herramientas que transforman la manera en que desarrollamos software. Entre estas innovaciones, el vibe-coding surge como un enfoque revolucionario que permite a profesionales sin formación técnica en programación crear prototipos funcionales y probar ideas de manera ágil. Nuestro primer proyecto de rescate con vibe-coding ilustra tanto las virtudes como los retos de este método, especialmente cuando se trata de llevar un producto desde una prueba de concepto hacia un sistema robusto y escalable. La historia comenzó cuando un amigo y excolega, con más de 20 años de experiencia en análisis de negocios, gestión de productos y programas, se aventuró en el mundo del desarrollo sin ser desarrollador. Apoyado por herramientas inteligentes como Cursor y Lovable, decidió experimentar con vibe-coding para materializar algunas ideas que había incubado durante tiempo.
Con cierto entusiasmo y una tarjeta de crédito en mano, se sumergió en esta nueva realidad, construyendo un prototipo funcional que mostró con orgullo durante una reunión casual. Lo que impresionó desde un inicio fue la rápida capacidad del prototipo para reflejar las ideas clave que intentaba plasmar. Estaba construido sobre una arquitectura relativamente simple pero moderna: un back-end basado en Supabase con funciones edge y un front-end desarrollado en React, TypeScript y Tailwind. Sin embargo, el principal obstáculo no fue la construcción inicial, sino el mantenimiento y la extensión del código. Tras cierto tiempo, cada cambio empezaba a generar fallos nuevos, y el entusiasmo inicial dio paso a la frustración.
Un punto interesante fue notar que la inconsistencia en el código resultó ser un enemigo silencioso. El sistema carecía de patrones comunes y una estructura uniforme que permitiera mantenerlo y escalarlo con confianza. La ausencia de un archivo cursorrules, que podría haber impuesto reglas de estilo y mejores prácticas, evidenciaba la falta de estándares claros, lo que complicaba enormemente la tarea de corregir errores y añadir funcionalidades. Además, la gestión del estado en la aplicación reflejaba un panorama caótico. Diferentes mecanismos coexistían sin una dirección común: algunos valores se pasaban como propiedades sin ser efectivamente asignados, otros se obtenían desde rutas o se recuperaban mediante llamadas a APIs, generando un galimatías que dificultaba la trazabilidad y el diagnóstico de problemas.
La simplicidad nativa del dominio de la aplicación hacía aún más llamativo lo enredado de su gestión de estado. Otro problema crucial fue la presencia de funcionalidades en el back-end que simplemente no funcionaban, pero que no figuraban en el listado de errores del desarrollador original. Estas funciones, que nunca fueron solicitadas ni diseñadas conscientemente, actuaban como una suerte de código fantasma que se ejecutaba de forma silenciosa sin hacer nada útil y sin levantar alarma. Estos fragmentos de código muerto o vestigial no solo aumentaban la complejidad del sistema, sino que también generaban incertidumbre sobre qué partes del código eran realmente necesarias y cuáles eran residuos del proceso iterativo. Una revelación profunda se presentó al analizar el proceso mismo de corrección de errores.
La ausencia de un desarrollador humano con una mentalidad unificada facilitaba la aparición de inconsistencias en el código. Mientras que en proyectos tradicionales es posible intentar entender la intención detrás de las decisiones previas, en este caso el código parecía una amalgama de fragmentos generados mediante múltiples interacciones entre un usuario y agentes de inteligencia artificial, que resolvían problemas de manera incremental sin una visión global coherente. Este fenómeno se manifestaba en patrones de diálogo donde el usuario reportaba un problema, la IA proponía una solución parcial, el usuario volvía al problema con un detalle adicional o un error persistente y así sucesivamente. Esta dinámica, aunque efectiva para avanzar rápidamente, contribuía a una base de código altamente frágil y difícil de mantener. Al analizar esta experiencia en un contexto más amplio, el vibe-coding se inscribe dentro de una larga tradición de herramientas diseñadas para habilitar a los llamados desarrolladores ciudadanos.
Desde Microsoft Access hasta Visual Basic pasando por Excel y diversas plataformas low-code, la industria ha intentado empoderar a profesionales con poca o ninguna experiencia en programación para crear soluciones tecnológicas. Muchas de las problemáticas encontradas en nuestro proyecto son familiares para quienes han trabajado en estos entornos: la dificultad para manejar complejidad creciente, la falta de rigor en prácticas de ingeniería y problemas latentes que emergen cuando se intenta escalar. No obstante, el vibe-coding tiene ventajas claras. En primer lugar, proporciona una velocidad sin precedentes en la fase de ideación y creación de pruebas de concepto. Esto reduce las barreras para que profesionales con visión puedan materializar sus ideas rápidamente sin depender de recursos técnicos extensos.
La automatización mediante inteligencia artificial promete democratizar el desarrollo de software, permitiendo que más personas participen en la creación de tecnología. Sin embargo, el camino desde prototipo hasta producto escalable y de calidad sigue siendo un desafío importante. El enfoque de vibe-coding suele obviar aspectos fundamentales de desarrollo, como pruebas automáticas, control de versiones riguroso, revisión de código y metodologías estructuradas, elementos esenciales para garantizar estabilidad y mantenibilidad. Este vacío plantea interrogantes sobre la viabilidad de estos productos para ambientes productivos, especialmente cuando las aplicaciones deben operar bajo demanda constante y con altos estándares de seguridad y performance. De cara al futuro, hay una clara oportunidad para combinar la velocidad y accesibilidad del vibe-coding con las mejores prácticas consolidadas en ingeniería de software.