Hay una nueva palabra circulando en tech: vibe coding. La idea es seductora —le dices a una IA lo que necesitas, ella escribe el código, y tú solo revisas que funcione. Suena a productividad multiplicada por diez. Y en parte lo es. Pero como toda herramienta potente, mal usada se convierte en un pasivo que puede costarte semanas de debugging, incidentes en producción y una base de código que nadie quiere mantener.
Si tu estrategia de desarrollo con IA se limita a copiar, pegar y rezar, el desastre no es cuestión de si va a ocurrir, sino de cuándo.
Lo que el vibe coding promete (y dónde se queda corto)
La promesa es atractiva: describir una feature en lenguaje natural, verla materializarse en segundos, iterar con un par de instrucciones más. Para prototipos, dashboards internos o scripts de automatización, funciona sorprendentemente bien. La velocidad es real —lo que antes tomaba un día, ahora toma minutos.
El problema aparece cuando ese prototipo se convierte en producción sin pasar por una fase de ingeniería real. Ahí es donde el vibe coding entrega código que:
Funciona, pero no sabes por qué. La IA generó una solución que cumple el caso feliz, pero falla silenciosamente en condiciones inesperadas. Nadie en el equipo puede explicar la lógica, y cuando algo se rompe —que va a romperse— el tiempo de resolución se dispara.
No tiene manejo de errores. Porque tú no pediste "manejo de errores", pediste "un endpoint que haga X". La IA te dio exactamente lo que pediste —no lo que necesitabas.
Mezcla responsabilidades. Lógica de negocio, acceso a datos y presentación en un solo bloque porque la IA optimizó para la respuesta más corta, no para la arquitectura más mantenible. Tres meses después, modificar un campo del formulario de login te obliga a entender 400 líneas de un solo archivo.
Es inseguro por defecto. Sin validación de inputs, sin sanitización, sin consideraciones de autorización. La IA no sabe tu modelo de seguridad a menos que se lo especifiques explícitamente —y aun así, debes verificarlo.
Acumula deuda técnica invisible. Cada iteración de "arréglame esto rápido" introduce una capa de parches que, tras diez iteraciones, convierten tu código en un castillo de naipes. Lo peor: no lo ves hasta que colapsa.
El resultado: código que pasa el primer test manual pero acumula deuda técnica a una velocidad que ningún equipo puede pagar. Peor aún: genera una falsa sensación de velocidad que hace que gerencia y stakeholders crean que todo va bien, hasta que deja de ir bien.
Y esto no es teoría. Cualquiera que haya mantenido código generado sin criterio lo ha vivido.
El costo real del desarrollo sin estructura
Pongámosle números a la intuición. Un equipo que practica vibe coding típicamente experimenta:
| Fase | Vibe Coding | Desarrollo Estructurado con IA |
|---|---|---|
| Primer prototipo | 2 horas | 4 horas |
| Llegar a producción | 3 días (con bugs) | 1 día |
| Primer incidente en prod | Semana 2 | Mes 3 (o nunca) |
| Tiempo de resolución de bug | 4-8 horas (nadie entiende el código) | 30-60 minutos |
| Onboarding de nuevo dev | 3 semanas | 3 días |
| Refactor a los 6 meses | Obligatorio, 2-4 semanas | Rara vez necesario |
La paradoja es brutal: el vibe coding te hace más rápido al inicio y mucho más lento después. El desarrollo estructurado con IA te hace un poco más lento al inicio y exponencialmente más rápido después.
La pregunta entonces no es si usar IA o no —eso ya está decidido. La pregunta es cómo.
Desarrollar con IA de forma adecuada: el método Specs-First
La alternativa no es rechazar la IA. Es cambiar el orden de las operaciones. En lugar de prompt → código → rezar, el flujo profesional es:
Spec → Arquitectura → Código generado → Revisión humana → Integración → Verificación
1. Spec primero, código después
Antes de pedirle una línea de código a la IA, define exactamente qué debe hacer el sistema. Un spec no es un documento de 40 páginas. Puede ser un archivo de 30 líneas que describa:
- Qué entra: inputs, tipos, validaciones, casos límite. Si el email puede tener +, si el teléfono acepta formato internacional, si el nombre permite tildes.
- Qué sale: outputs esperados, códigos de error, formatos de respuesta, headers HTTP.
- Qué no debe hacer: restricciones explícitas. "No debe consultar la base de datos directamente desde el controlador", "No debe loguear contraseñas".
-
Cómo debe fallar: modos de error esperados y mensajes para cada uno. Un 401 debe devolver
{"error": "invalid_credentials"}y no{"error": "Error: password mismatch for user jesus@guayoyo.tech"}.
La diferencia entre un prompt improvisado y un spec de 30 líneas es la diferencia entre un MVP que funciona en la demo y un sistema que no se cae a las 3 AM un sábado.
Pero un spec sin reglas de ejecución es como un mapa sin instrucciones para el conductor. Necesitas que la IA sepa no solo QUÉ construir, sino CÓMO construirlo.
2. Domando a la IA: skills, reglas y contexto
Aquí es donde Claude Code —la herramienta de Anthropic que está marcando el estándar en desarrollo asistido— cambia el juego. Claude Code lee automáticamente un archivo CLAUDE.md en la raíz de tu proyecto y lo usa como sistema de reglas durante TODA la sesión. También puede cargar specs desde archivos Markdown y mantener memoria de decisiones entre sesiones.
Un CLAUDE.md bien escrito convierte a Claude de "generador de código aleatorio" a "junior que sigue tus reglas al pie de la letra, no se queja, y trabaja 24/7". Las categorías que debes cubrir:
- Convenciones de código: estilo, nombrado, estructura de archivos.
- Patrones de seguridad: validación de inputs, sanitización, manejo de secretos.
- Restricciones de arquitectura: qué capas existen, qué puede y no puede tocar cada módulo.
- Manejo de errores obligatorio: toda función que toque I/O debe tener try/catch.
- Testing: qué tipo de tests se esperan por cada tipo de archivo.
3. Tutorial paso a paso: construyendo una API de tareas con Claude Code
Hasta aquí la teoría. Ahora vamos a ensuciarnos las manos.
Construiremos juntos una mini aplicación real —una API REST de gestión de tareas— usando Claude Code con specs y skills desde cero. El objetivo no es la API en sí, sino que internalices el método que acabo de describir. Una vez que lo domines, aplica para cualquier proyecto, desde un script de automatización hasta un backend enterprise.
Nuestra app se llamará MiniTasks y tendrá: crear tareas, listar, marcar como completadas, filtrar por estado, y un endpoint de estadísticas. Node.js + TypeScript + Express + SQLite.
Paso 1: Inicializar el proyecto
# Crear carpeta e iniciar proyecto Node
mkdir minitasks && cd minitasks
npm init -y
npm install express better-sqlite3 zod uuid
npm install -D typescript @types/express @types/better-sqlite3 @types/uuid vitest
npx tsc --init
# Inicializar git (Claude Code lo usa para diff y commits)
git init
git add -A && git commit -m "chore: scaffold inicial"
Paso 2: Crear el archivo de reglas (CLAUDE.md)
Este es el corazón del método. Define cómo Claude DEBE trabajar en tu proyecto. Colócalo en la raíz:
# CLAUDE.md — Reglas de desarrollo para MiniTasks
## Stack
- Runtime: Node.js 20+
- Lenguaje: TypeScript en modo estricto (strict: true)
- Framework: Express.js
- Base de datos: SQLite vía better-sqlite3 (síncrona, sin migraciones complejas)
- Validación: zod
- Testing: vitest
## Estilo de código
- Nombrado: camelCase para variables/funciones, PascalCase para tipos/interfaces
- No usar `any` — usar `unknown` y validar con zod
- Las rutas Express van en archivos separados bajo src/routes/
- La lógica de negocio va en src/services/
- El acceso a datos va en src/db/
- Usar async/await para handlers de Express
## Seguridad
- Validar TODOS los inputs del usuario con zod antes de procesarlos
- Usar consultas parametrizadas (better-sqlite3 lo hace por defecto)
- No exponer stack traces en respuestas de error
- Usar try/catch en todos los handlers de ruta
## Testing
- Cada endpoint debe tener tests de integración con vitest y supertest
- Los servicios deben tener tests unitarios
- Usar una base de datos en memoria para tests
## Reglas de trabajo
- Antes de escribir código, confirma que leíste CLAUDE.md y los specs
- Si el spec es ambiguo, pregunta antes de implementar
- No agregues dependencias sin preguntar
- Haz commits pequeños y atómicos con mensajes descriptivos
- Corrige errores de TypeScript ANTES de ejecutar
Paso 3: Escribir el spec de la aplicación
Creamos specs/minitasks-spec.md. Este documento define QUÉ debe hacer la app, sin entrar en CÓMO:
# Spec: MiniTasks API
## Objetivo
API REST para gestionar tareas personales con persistencia en SQLite.
## Entidades
### Task
- id: string (UUID v4)
- title: string (1-200 caracteres, requerido)
- description: string (opcional, máximo 1000 caracteres)
- status: "pending" | "in_progress" | "done" (default: "pending")
- priority: "low" | "medium" | "high" (default: "medium")
- createdAt: string (ISO 8601)
- updatedAt: string (ISO 8601)
## Endpoints
### POST /tasks
Crear una tarea nueva.
- Body: { title, description?, priority? }
- Response 201: la tarea creada con todos los campos
- Response 400: errores de validación detallados
### GET /tasks
Listar tareas. Query params opcionales:
- ?status=pending|in_progress|done (filtra por estado)
- ?priority=low|medium|high (filtra por prioridad)
- ?sort=createdAt|priority|status (ordenamiento, default: createdAt)
- ?order=asc|desc (default: desc)
- Response 200: array de tareas
### GET /tasks/:id
Obtener una tarea por ID.
- Response 200: la tarea
- Response 404: { error: "task_not_found" }
### PATCH /tasks/:id
Actualizar campos de una tarea.
- Body: { title?, description?, status?, priority? }
- Si status cambia a "done", registrar updatedAt
- Response 200: la tarea actualizada
- Response 404: { error: "task_not_found" }
- Response 400: errores de validación
### DELETE /tasks/:id
Eliminar una tarea.
- Response 204: sin contenido
- Response 404: { error: "task_not_found" }
### GET /stats
Estadísticas generales.
- Response 200:
{
total: number,
byStatus: { pending: number, in_progress: number, done: number },
byPriority: { low: number, medium: number, high: number }
}
## Reglas de negocio
- No se puede crear una tarea con title vacío o solo espacios
- No se puede cambiar una tarea con status "done" a otro estado (operación terminal)
- Las prioridades "high" deben devolverse primero cuando sort=priority
## Formato de errores
Todos los errores deben seguir este formato:
{ "error": "codigo_error", "message": "Descripción legible", "details?": [...] }
Nota cómo el spec es completo pero no toca implementación. No dice "usa un query SQL así" ni "el archivo debe llamarse tasks.ts". Define el contrato del sistema.
Paso 4: Primera iteración con Claude Code
Con el spec y las reglas listas, ejecutamos Claude Code en el directorio del proyecto:
claude
Dentro de la sesión interactiva, le damos el prompt inicial:
Crea la estructura completa del proyecto MiniTasks según el spec en
specs/minitasks-spec.md y las reglas de CLAUDE.md.
Empieza por:
1. Leer CLAUDE.md y specs/minitasks-spec.md
2. Configurar la base de datos SQLite (schema, conexión)
3. Implementar los modelos y validación con zod
4. Implementar las rutas y servicios para todos los endpoints
5. Agregar tests para los endpoints principales
Trabaja en ese orden. Haz un commit después de cada paso completado.
Claude Code va a:
- Leer ambos archivos y entender el contexto
- Crear
src/db/schema.tscon la inicialización de SQLite - Crear
src/schemas/task.tscon los validadores zod - Crear
src/services/task.service.tscon la lógica de negocio - Crear
src/routes/tasks.tsysrc/routes/stats.tscon los handlers - Crear
src/index.tscomo punto de entrada - Ejecutar
tscpara verificar tipos - Escribir los tests y ejecutarlos
Paso 5: Revisar, no confiar
Claude generó el código. Ahora es TU turno de ser ingeniero:
# Revisar el diff completo
git diff HEAD
# Hacer preguntas sobre lo que no entiendes
# En la misma sesión de Claude Code:
"¿Por qué usaste una transacción en createTask pero no en updateTask?"
"¿Qué pasa si envío un title con 300 caracteres en el PATCH?"
"Explícame la lógica del filtro combinado en GET /tasks"
# Ejecutar los tests
npm test
# Probar manualmente con curl
curl -X POST http://localhost:3000/tasks \
-H "Content-Type: application/json" \
-d '{"title": "Aprender Claude Code", "priority": "high"}'
curl http://localhost:3000/tasks
curl http://localhost:3000/stats
Paso 6: Iterar sobre el spec
Los specs viven y evolucionan. Digamos que ejecutando encuentras que necesitas paginación:
# Agregar a specs/minitasks-spec.md
### GET /tasks (actualización)
Agregar query params de paginación:
- ?page=1 (default: 1)
- ?limit=20 (default: 20, máximo 100)
- Response 200:
{
data: [...tasks],
pagination: { page: number, limit: number, total: number, totalPages: number }
}
Actualizas el spec, y en Claude Code:
Actualicé specs/minitasks-spec.md con paginación para GET /tasks.
Implementa los cambios siguiendo el spec actualizado.
Asegúrate de que los tests existentes sigan pasando.
Claude ajusta el código, actualiza los tests, y sigues revisando. Esta iteración spec → código → revisión → spec es el ciclo que distingue el desarrollo profesional del vibe coding.
El resultado final
Al terminar el flujo tienes:
minitasks/
├── CLAUDE.md # Reglas que Claude sigue siempre
├── specs/
│ └── minitasks-spec.md # Spec completo y actualizado
├── src/
│ ├── index.ts # Punto de entrada
│ ├── db/
│ │ └── schema.ts # Inicialización de SQLite
│ ├── schemas/
│ │ └── task.ts # Validadores zod
│ ├── services/
│ │ └── task.service.ts # Lógica de negocio
│ └── routes/
│ ├── tasks.ts # Endpoints CRUD
│ └── stats.ts # Endpoint de estadísticas
├── tests/
│ ├── tasks.test.ts
│ └── stats.test.ts
├── package.json
└── tsconfig.json
Y lo más importante: todo el código fue generado siguiendo reglas explícitas, validado contra un spec, con tests que pasan, y tú entiendes cada decisión porque las revisaste y preguntaste. Eso no es vibe coding. Es ingeniería de software con IA como herramienta.
Esto no es solo para ingenieros
El tutorial que acabas de leer asume que sabes TypeScript y entiendes Express. Pero el método —specs, reglas, iteración— no es exclusivo de desarrolladores.
Una de las grandes mentiras del vibe coding es que "cualquiera puede programar con IA". La verdad es más matizada: cualquiera puede prototipar con IA, pero construir software que escale requiere criterio técnico.
Dicho esto, las herramientas de desarrollo asistido con habilidades bien configuradas también benefician a equipos no técnicos. Un analista de operaciones puede usar un spec bien escrito para generar un script de automatización que un ingeniero revisa en 10 minutos. Un equipo de marketing puede prototipar una landing page y pasarle el spec completo al equipo de desarrollo en lugar de un "dibujito en PowerPoint".
La clave está en quién escribe el spec y quién configura las reglas. Y eso se aprende. Que es justo a donde quería llegar.
La IA no reemplaza al ingeniero — lo multiplica
Volviendo al principio: el vibe coding no es el enemigo. El enemigo es la falta de método. La diferencia entre un desarrollador que solo genera código y uno que domina el flujo Specs-First es la misma que entre un piloto automático y un capitán que usa instrumentos de navegación. Ambos llegan, pero uno sabe exactamente por qué y cómo corregir si algo se desvía.
Y para las empresas, la decisión no es "¿usamos IA o no?". Ese barco ya zarpó. La decisión es: ¿la usamos con método o sin él?
¿Tu equipo está listo para desarrollar con IA sin acumular deuda técnica? En Guayoyo Tech ofrecemos consultoría y adiestramiento especializado en herramientas de desarrollo asistido por inteligencia artificial para equipos técnicos y no técnicos:
- Para equipos de ingeniería: configuramos tu stack de skills y specs, definimos tu arquitectura de reglas e instrucciones, y entrenamos a tus desarrolladores en el flujo Specs-First que escala.
- Para equipos no técnicos: enseñamos a tus analistas, operadores y equipos de negocio a prototipar, automatizar y colaborar con ingeniería usando specs claros y herramientas de IA.
- Para líderes y gerencia: diseñamos la estrategia de adopción de IA en desarrollo que reduce costos sin hipotecar tu arquitectura.
Sin humo. Sin buzzwords. Resultados que se miden en velocidad de delivery y en código que no da miedo tocar.
Top comments (0)