Un sistema de diseño es más que una biblioteca de componentes. Es un lenguaje compartido entre diseñadores y desarrolladores que garantiza la consistencia, acelera el desarrollo y mantiene la calidad en todo un ecosistema de productos.
Esa distinción importa sobre todo cuando el sistema tiene que dar servicio a más de un equipo. Un solo ingeniero entusiasta puede construir una biblioteca de componentes en pocas semanas. Un sistema de diseño del que dependen decenas de personas se parece más a un producto interno: tiene usuarios, una hoja de ruta, versiones, solicitudes de soporte y una reputación que proteger. Este artículo cubre lo que cambia cuando se construye para esa escala, desde la arquitectura de tokens hasta la gobernanza y el versionado.
Por qué importan los sistemas de diseño
Cuando los equipos crecen más allá de unos pocos desarrolladores, mantener la consistencia visual y de comportamiento se vuelve difícil. Sin un sistema de diseño, cada equipo interpreta las guías de marca de forma distinta, lo que da lugar a una experiencia de usuario fragmentada. Un sistema de diseño bien construido elimina este problema al proporcionar una única fuente de verdad.
El beneficio menos visible es la reutilización de decisiones. Cada vez que un equipo construye su propio selector de fechas, vuelve a decidir el comportamiento con teclado, los estados de error, la localización y la gestión del foco, y normalmente se equivoca en alguno de ellos. Un componente compartido codifica esas decisiones una sola vez. Los equipos de producto pueden entonces dedicar su tiempo a las partes de la interfaz que son realmente específicas de su producto.
Un sistema de diseño también le da apalancamiento. Corrija un error de contraste en un token compartido y todas las superficies que lo usan quedarán corregidas en la siguiente versión. Sin el sistema, la misma corrección es un buscar y reemplazar entre repositorios que nadie tiene tiempo de coordinar.
Componentes fundamentales
Todo sistema de diseño eficaz empieza con los design tokens: los valores atómicos que definen colores, espaciado, tipografía y movimiento. Estos tokens alimentan a primitivas como botones, campos y elementos de texto, que a su vez se componen en patrones más complejos como tarjetas, modales y barras de navegación.
Organice sus tokens en capas
Las listas planas de tokens no escalan. Una estructura habitual y eficaz tiene tres capas:
- Los tokens de referencia contienen valores en bruto sin ningún significado asociado:
blue-600,space-4,radius-md. - Los tokens semánticos describen un propósito:
color-surface,color-text-muted,color-border-focus,color-danger. - Los tokens de componente cubren los pocos casos en los que un componente necesita su propio ajuste:
button-padding-inline,card-radius.
Los componentes deben consumir tokens semánticos o de componente, nunca tokens de referencia directamente. Esa única regla es lo que hace posible el theming: el modo oscuro, el modo de alto contraste o una marca white-label pasan a ser un mapeo distinto de valores semánticos a valores de referencia, sin cambios en los componentes.
:root {
--color-surface: var(--gray-50);
--color-text: var(--gray-900);
--color-border-focus: var(--blue-600);
}
[data-theme="dark"] {
--color-surface: var(--gray-950);
--color-text: var(--gray-100);
--color-border-focus: var(--blue-400);
}
Almacene los tokens en un formato neutral respecto a la plataforma y genere a partir de esa única fuente las custom properties de CSS, los valores nativos de cada plataforma y las variables de las herramientas de diseño. El W3C Design Tokens Community Group ha publicado un formato JSON común y estable precisamente con este fin (su primera versión estable salió en octubre de 2025), y adoptar pronto un formato estructurado facilita cambiar de herramientas más adelante.
Construya primitivas con variantes explícitas
Las primitivas son donde se gana o se pierde la consistencia. Dé a cada una un conjunto pequeño y con nombre de variantes y tamaños, y haga que el mapeo de props a estilos sea una función pura que pueda probarse sin renderizar:
import { cva } from 'class-variance-authority';
const button = cva('inline-flex items-center gap-2 rounded-md font-medium', {
variants: {
intent: { primary: '...', secondary: '...', danger: '...' },
size: { sm: 'h-8 px-3 text-sm', md: 'h-10 px-4', lg: 'h-12 px-5 text-lg' },
},
defaultVariants: { intent: 'primary', size: 'md' },
});
Resista la tentación de añadir una variante por cada petición. Cada opción nueva es superficie de API permanente que hay que documentar, probar, tematizar y mantener. Cuando un equipo pida una variante nueva, pregunte primero qué problema intenta resolver; a menudo una variante existente o una composición ya lo cubre.
Todo componente tiene estados
La especificación de un componente no está completa hasta que cubre todos los estados en los que puede estar: por defecto, hover, foco, activo, deshabilitado, cargando, vacío, error y cualquier estado de selección o expansión. Los componentes con muchos datos, en particular, necesitan estados de vacío, carga y error diseñados, porque son los estados que los equipos de producto omiten con más frecuencia bajo la presión de los plazos. Si el sistema los proporciona, todos los productos los obtienen.
La documentación forma parte del componente
La documentación es igual de importante. Cada componente debe incluir pautas de uso, notas de accesibilidad y ejemplos de código. Herramientas como Storybook, o la Container API de Astro para renderizar componentes de forma aislada, facilitan desarrollar y mostrar los componentes por sí solos.
Una buena documentación de componentes responde a las preguntas que la gente realmente hace:
- ¿Cuándo debo usar esto y cuándo debo usar otra cosa? Una breve sección de “qué hacer y qué no hacer” evita más usos indebidos que cualquier regla de lint.
- ¿Cuáles son las props? Genere la referencia a partir de las definiciones de tipos para que no pueda quedar desactualizada.
- ¿Cómo se comporta para los usuarios de teclado y de lectores de pantalla? Documente el orden del foco, los atajos de teclado y el ARIA que gestiona el componente.
- ¿Cómo se ve cada estado? Renderícelos, no los describa.
Estrategias para escalar
A medida que su organización crezca, considere adoptar un modelo federado en el que los distintos equipos contribuyan al sistema de diseño. Establezca un proceso de contribución claro con revisiones de diseño y pruebas automatizadas para mantener la calidad. Versione con cuidado los paquetes de su sistema de diseño para evitar cambios incompatibles en las aplicaciones que los consumen.
Elija un modelo de propiedad de forma deliberada
Existen tres grandes modelos, y la mayoría de las organizaciones pasan de uno a otro con el tiempo:
- Centralizado. Un equipo dedicado construye y es dueño de todo. La calidad y la consistencia son altas, pero el equipo se convierte en un cuello de botella a medida que crece la demanda.
- Federado. Diseñadores e ingenieros de los equipos de producto contribuyen, mientras un pequeño equipo central fija los estándares y revisa. Escala mejor, pero exige una fuerte disciplina de revisión.
- Híbrido. Un equipo central es dueño de los fundamentos y las primitivas; los equipos de producto son dueños de los patrones de más alto nivel, que siguen las reglas del sistema. En la práctica, aquí es donde terminan muchos sistemas maduros.
Elija el que elija, déjelo por escrito. La ambigüedad sobre quién es responsable de un componente es la forma de acabar con tres modales ligeramente distintos.
Haga de la contribución un camino definido
Un proceso de contribución que la gente realmente usa es breve y predecible:
- Proponer. Abra un issue que describa el problema, los productos que lo necesitan y los componentes existentes que se han considerado.
- Acordar la forma. Una breve revisión del diseño y de la API antes de escribir código ahorra el tipo de retrabajo más costoso.
- Construir según el estándar. Solo tokens, todos los estados, comprobaciones de accesibilidad, tests y documentación.
- Revisar y publicar. El equipo central revisa según una lista de verificación y lo incluye en la siguiente versión.
Publique la lista de verificación. Quienes contribuyen deberían saber de antemano exactamente qué significa “terminado”, en lugar de descubrirlo en los comentarios de revisión.
Versione y publique con cuidado
Trate los paquetes del sistema como cualquier librería pública y siga estrictamente el versionado semántico. Un nombre de prop cambiado, una variante eliminada o un valor de token que desplaza el layout es un cambio incompatible, aunque los tipos de TypeScript sigan compilando.
- Publique versiones pequeñas y frecuentes en lugar de grandes y esporádicas; son más fáciles de adoptar y de revertir.
- Marque como obsoleto antes de eliminar. Mantenga la API antigua funcionando durante al menos una versión mayor, con una advertencia en la consola y una ruta de migración documentada.
- Siempre que pueda, proporcione codemods para las migraciones mecánicas, como las props renombradas.
- Mantenga un changelog escrito para quienes consumen el sistema, no una lista de mensajes de commit.
/** @deprecated Use `intent="danger"` en su lugar. Se eliminará en v5. */
destructive?: boolean;
Automatice el estándar de calidad
A gran escala no puede confiar en que los revisores lo detecten todo. Lleve el estándar a las herramientas:
- Tests de regresión visual para cada estado de cada componente, de modo que un cambio no intencionado en un token compartido se detecte antes de publicar.
- Comprobaciones automáticas de accesibilidad en los tests de componentes, respaldadas por pruebas manuales periódicas con teclado y lectores de pantalla.
- Reglas de lint que señalen valores de color en bruto, espaciados fijos en el código o importaciones de componentes obsoletos en las aplicaciones consumidoras.
- Comprobaciones de contraste de los pares de tokens, ejecutadas para cada tema, para que una paleta nueva no pueda publicarse con combinaciones ilegibles.
Mida la adopción
No puede mejorar lo que no puede ver. Haga seguimiento de qué superficies de producto usan los componentes del sistema y cuáles usan equivalentes locales, de qué versiones usa cada aplicación y de con qué frecuencia los equipos sobrescriben los estilos. Un análisis estático de las sentencias de importación en todos los repositorios le da la mayor parte de esta información. Un número creciente de sobrescrituras es una señal temprana de que el sistema no cubre una necesidad, y conviene investigarla antes de que se convierta en un fork.
Dé soporte a quienes lo usan
Un sistema de diseño triunfa o fracasa en función de si los equipos de producto deciden usarlo, y eso depende en gran medida de cómo es trabajar con el equipo que hay detrás. Trate el soporte como parte del trabajo, no como una interrupción:
- Mantenga un único canal de soporte visible donde las preguntas se respondan en público, para que la siguiente persona con la misma duda pueda encontrar la respuesta.
- Organice horas de consulta periódicas en las que los equipos puedan traer diseños en curso y recibir orientación antes de construir algo que el sistema ya ofrece.
- Convierta las preguntas repetidas en documentación. Si la misma pregunta aparece tres veces, a la documentación le falta algo.
- Acompañe la adopción temprana. Para un equipo que migra un producto grande, un miembro del equipo central integrado durante un sprint suele aportar más que cualquier guía.
- Publique la hoja de ruta. Los equipos están mucho más dispuestos a esperar un componente cuando saben que llegará y, aproximadamente, cuándo.
Ser accesible también le aporta mejor información. Los equipos que usan el sistema a diario le dirán dónde se queda corto, siempre que decírselo sea fácil.
Errores comunes
Los sistemas de diseño a gran escala suelen fallar de formas predecibles:
- Construir antes de escuchar. Un sistema diseñado de espaldas a los productos a los que sirve acabará ignorado. Empiece por auditar lo que los equipos ya han construido y estandarice los patrones que se repiten.
- Tratarlo como un proyecto. Un sistema de diseño no tiene línea de meta. Sin financiación y responsables continuos, se deteriora en cuanto el equipo del lanzamiento pasa a otra cosa.
- Componentes excesivamente configurables. Un botón con veinte props es señal de que el sistema intenta ser a la vez el componente local de cada equipo. Prefiera la composición.
- Diseño y código que se distancian. Si los archivos de diseño y los componentes en código no coinciden, la gente confiará en el que vea primero. Genere ambos a partir de los mismos tokens y revíselos juntos.
- Ignorar el coste de migración. Cada cambio incompatible supone trabajo para cada equipo consumidor. Preséntelo en el presupuesto, ayude con él y agrúpelo.
Conclusión
Invertir en un sistema de diseño da frutos con el tiempo. Los equipos publican más rápido, los diseñadores dedican menos tiempo a revisar decisiones ya tomadas y los usuarios disfrutan de una experiencia coherente en cada punto de contacto.
Llegar ahí a gran escala depende menos de un componente concreto y más del sistema que rodea a los componentes: tokens en capas que abaratan el theming, primitivas con APIs pequeñas y explícitas, documentación que responde a preguntas reales, un camino de contribución que la gente pueda seguir y versiones que respetan a los equipos que dependen de usted. Si acierta con esos fundamentos, el número de componentes puede crecer sin que la calidad baje.