FC-0041 · 28 MAR 2026 · proceso

¿Vale la pena la arquitectura hexagonal para un CRM chico?

Tres años y cuatro proyectos: comparo dos sistemas hexagonales con dos sistemas planos.

PALABRAS 1.420
LECTURA ~6 MIN
CATEGORÍA proceso
TAGS Arquitectura · Hexagonal · Proceso

Los tutoriales de arquitectura hexagonal suelen usar bancos o e-commerce como ejemplo. Yo trabajo con equipos de una a tres personas. Necesito saber cuándo la estructura compensa su costo.

Después de tres años y cuatro proyectos, dos con hexagonal y dos sin ella, tengo una respuesta.

Costos y beneficios

La arquitectura hexagonal ofrece tres beneficios concretos:

  1. Los tests de dominio corren sin red, base de datos ni LLM. Los puertos mantienen los mocks pequeños.
  2. Podés cambiar Postgres por Supabase o Claude por GPT sin tocar el dominio. Cambiás el adapter.
  3. Cada capa declara lo que recibe y devuelve.

El costo también es concreto. Un caso de uso simple puede ocupar seis archivos: use case, port in, port out, adapter in, adapter out y DTO. Una persona nueva puede tardar una semana en entenderlos. Si construís un CRUD puro, esa estructura agrega trabajo sin resolver un problema del producto.

Cuándo conviene

CRM con agente IA: hexagonal

El caso de uso convertir_lead_a_cliente tiene:

  • Políticas: cuándo un lead es qualifiable
  • Side-effects: mandar mail, crear Stripe customer, disparar workflow
  • Actores externos: el LLM sugiere la acción pero no la ejecuta

Este caso tiene reglas que cambian con el negocio y LLMs que cambian con el proveedor. La lógica debe poder probarse sin depender de ninguno.

src/
├── domain/
│   ├── lead.ts           # entidad, puro TS, cero imports
│   ├── qualification.ts  # política de dominio
│   └── events.ts         # LeadConverted, LeadRejected
├── app/
│   └── convert-lead/
│       ├── use-case.ts   # orquesta la política + puertos
│       └── port.ts       # input/output del caso
└── infra/
    ├── postgres/         # adapter-out
    ├── stripe/           # adapter-out
    └── mcp/              # adapter-in (el LLM entra por acá)

Landing con Typeform: React + Supabase

Un formulario de captura de leads necesita endpoints y validación. Una capa de casos de uso agrega trabajo sin resolver un problema del producto.

El argumento económico

Tres años, cuatro proyectos. Medí dos cosas: horas hasta el primer feature entregado y horas refactorizando en el mes 6.

ProyectoArquitecturaPrimer featureRefactor mes 6
CRM AHexagonal42h8h
CRM BPlano18h64h
SaaS CHexagonal38h4h
LandingPlano6h2h

Al comparar las cuatro filas, veo la diferencia: los proyectos planos arrancan con menos horas, pero un dominio con reglas cambiantes cobra ese ahorro durante el mantenimiento.

Mi stack hexagonal en 2026

  • Dominio: TypeScript puro, cero dependencias, Zod para value objects.
  • Casos de uso: funciones puras que reciben puertos como argumento. Nada de clases.
  • Puertos: interfaces mínimas. Si tiene más de 3 métodos, está mal diseñado.
  • Adapters: una carpeta por tecnología. Postgres, Stripe, Claude.
  • DI: explícita en la composition root. Sin frameworks.

Nunca uso clases para casos de uso. No las necesito. Y evito que el equipo se enganche en discusiones de OOP que no resuelven nada.

Criterio de uso

Para un MVP de un fin de semana, elegí la estructura más corta que puedas mantener. La arquitectura hexagonal consumiría tiempo que el producto todavía no necesita.

Para un sistema que vivirá más de un año y tomará decisiones de negocio, la separación entre dominio y adapters reduce el costo de los cambios en el mes seis.

REL — RELACIONADOS
FC-0040 · 14 FEB 2026
"Ship" no es "done": el costo escondido de features en producción
FC-0042 · 12 ABR 2026
MCP servers en producción: lo que aprendí shipeando tres