Módulo 1: What A Design System Is
Las cuatro capas: tokens, utilidades, componentes, patrones
Descripción
Hasta aquí hablamos de una sola pieza del sistema —el token, el frasco etiquetado— porque es la más baja y la más fácil de entender. Pero un sistema de diseño no es una pila de tokens; es una arquitectura de cuatro capas, cada una construida sobre la de abajo. Esta lección presenta esas cuatro capas —tokens → utilidades → componentes → patrones— que son la columna vertebral de toda la guía. Cada módulo que viene después vive en una de ellas: el módulo 2 profundiza los tokens, el 3 las utilidades (Tailwind), el 5 los componentes con variantes, y los patrones aparecen en el capstone. Si entiendes el mapa de las cuatro capas ahora, cada módulo siguiente sabrás exactamente dónde encaja.
La idea central —y la que previene el error más común de todo el tema— es que las capas tienen un orden, y ese orden va de abajo hacia arriba. No se puede construir un componente coherente sin tokens debajo, igual que no se puede construir un segundo piso sin cimientos. Mucha gente empieza por los componentes (la capa visible, la que se toca al programar) y se salta las de abajo; el resultado son componentes que se ven bien pero divergen entre sí, porque no comparten una base. Entender el orden es entender por qué el sistema funciona.
Conexión con el módulo. La lección 1 dio la tesis, la 2 mostró el salto en la capa más baja (tokens). Esta lección abre el mapa completo: las cuatro capas y cómo se apilan. Es la lección más estructural del módulo —la que más veces vas a recordar en el resto de la guía— porque cada concepto que aprendas después ("¿esto es un token o una utilidad?", "¿esto va en el componente o en el patrón?") se ubica en este mapa. La lección 4 profundizará por qué las capas dan coherencia (midiendo el drift que evitan), la 7 armará el inventario completo de Mercado con estas cuatro capas, y la 8 te pondrá a listarlas tú.
Una analogía: de la cantera a la ciudad
Piensa en cómo se construye una ciudad, de lo más crudo a lo más terminado.
Primero está la materia prima estandarizada: los ladrillos, todos del mismo tamaño; el cemento, de una fórmula fija; las vigas, de medidas normadas. Nadie vive en un ladrillo, pero todo lo demás depende de que los ladrillos sean idénticos entre sí. Esos son los tokens: los valores atómicos del diseño (un color, un espacio, un tamaño de letra), estandarizados para que todo lo que se construya encima encaje.
Luego están las técnicas de construcción: "pon un ladrillo", "aplica una capa de cemento", "levanta una hilera". Son gestos pequeños, reutilizables, que aplican la materia prima. No son un edificio; son las acciones con las que se hace uno. Esas son las utilidades: clases pequeñas de un solo propósito (p-4 = "pon padding de space-4", bg-primary = "pinta con color.primary") que aplican un token a un elemento.
Después vienen los elementos prefabricados: una puerta, una ventana, un muro completo. Cada uno está hecho de muchos ladrillos y técnicas, pero se maneja como una sola cosa con opciones: la puerta puede ser de una o dos hojas, la ventana chica o grande. Esos son los componentes: piezas reutilizables (Button, ProductCard) hechas de muchas utilidades, que se usan como una unidad y se configuran con variantes (variant, size).
Y arriba de todo está la traza urbana: cómo se disponen las casas en una calle, cómo se organiza una plaza. No es una casa nueva; es un arreglo reconocible de casas. Esos son los patrones: composiciones de componentes que resuelven una necesidad recurrente (la cuadrícula de productos, la cabecera del sitio, el formulario de checkout).
La analogía carga la lección entera: no se puede levantar una puerta con ladrillos de tamaños distintos, ni trazar una calle sin casas. El orden es obligatorio de abajo hacia arriba. Y cambiar la materia prima —un ladrillo más grande— cambia, en cascada, todo lo construido encima. Esa dependencia hacia abajo es lo que hace del sistema un sistema y no cuatro cosas sueltas.
Las cuatro capas, una por una
Veámoslas con el storefront de Mercado, de abajo hacia arriba. Este diagrama es el que conviene memorizar:
┌─────────────────────────────────────────────────────────┐
│ PATTERNS product-grid, site-header, checkout-form │ composiciones
│ (arreglos reconocibles de componentes) │ de componentes
├─────────────────────────────────────────────────────────┤
│ COMPONENTS Button, ProductCard, SearchBar, Badge │ piezas con
│ (con variantes: variant, size) │ variantes
├─────────────────────────────────────────────────────────┤
│ UTILITIES bg-primary, p-4, text-lg, flex, gap-4 │ aplican UN token
│ (una clase = una intención de estilo) │ a un elemento
├─────────────────────────────────────────────────────────┤
│ TOKENS color.primary, space-4, text-lg, radius-md │ los valores
│ (los valores atómicos, nombrados por rol) │ atómicos
└─────────────────────────────────────────────────────────┘
cada capa se apoya en la de ABAJO ▲
Capa 1 — Tokens (los valores atómicos). Un token es una decisión de diseño nombrada por su rol: color.primary (el color de marca), space-4 (el espacio mediano de la escala), text-lg (un tamaño de la escala tipográfica), radius-md (un radio de esquina). Es el frasco etiquetado de la lección 2. Los tokens no hacen nada por sí solos —son solo valores con nombre—; son la materia prima que todo lo demás usa. Nombrarlos por rol y no por valor (color.primary, no blue) es lo que les permite cambiar sin mentir. La mecánica completa —primitivos vs semánticos, theming— es el módulo 2.
Capa 2 — Utilidades (aplicar un token a un elemento). Una utilidad es una clase pequeña, de un solo propósito, que aplica un token: p-4 pone padding del token space-4; bg-primary pone background del token color.primary; text-lg pone el tamaño de letra text-lg. En vez de escribir CSS a mano para cada elemento, compones utilidades. Son las técnicas de construcción: gestos mínimos y reutilizables. Este es el modelo de Tailwind, y cómo funciona por debajo (por qué todas tienen igual especificidad y ganan por orden de fuente, la cascada de web-fundamentals) es el módulo 3.
Capa 3 — Componentes (piezas con variantes). Un componente agrupa muchas utilidades en una pieza reutilizable con un nombre y opciones: Button, ProductCard, SearchBar. Es la puerta prefabricada. Un Button no es "azul con padding 16"; es una pieza que puede ser variant="primary" o variant="ghost", size="sm" o size="lg" —sus variantes—. Por dentro, cada variante es un conjunto de utilidades (y por tanto de tokens); por fuera, se usa como una unidad. Ya sabes construir componentes de react-fundamentals; aquí aprendes a estilarlos y variarlos. El patrón de variantes (cva) es el módulo 5.
Capa 4 — Patrones (composiciones de componentes). Un patrón es un arreglo recurrente de componentes que resuelve una necesidad: product-grid (una cuadrícula de ProductCard), site-header (el logo + SearchBar + nav), checkout-form (los campos + Button). No es un componente nuevo; es cómo se disponen los componentes que ya tienes, de una forma reconocible y repetible. Es la traza urbana. Los patrones dan coherencia al nivel de pantallas completas, no solo de piezas.
La regla de oro que sostiene las cuatro: cada capa solo puede usar las de abajo, nunca las de arriba. Una utilidad usa tokens; un componente usa utilidades (y por tanto tokens); un patrón usa componentes. Nunca al revés: un token no sabe de botones, una utilidad no sabe de ProductCard. Esa dirección única del flujo —de abajo hacia arriba— es lo que mantiene el sistema desenredado. Si un token cambia, la onda sube por las cuatro capas sola. Si intentaras que un token dependiera de un componente, crearías un ciclo y el sistema se enredaría.
Ejemplo trabajado: el inventario de las cuatro capas
Para que las cuatro capas dejen de ser un diagrama y se vuelvan algo contable, vamos a modelar el sistema de Mercado como un objeto —una lista de piezas por capa— y escribir un systemInventory que las recorre en orden, cuenta las piezas de cada una y muestra cómo se apilan. La flecha -> al final de cada capa señala que hay otra encima que se apoya en ella:
// L3 — systemInventory: las 4 capas del sistema y cuantas piezas hay en cada una.
const mercadoSystem = {
tokens: ['color.primary', 'color.surface', 'color.text', 'space-4', 'space-6', 'text-lg', 'radius-md'],
utilities: ['bg-primary', 'text-lg', 'p-4', 'flex', 'gap-4', 'rounded-md'],
components: ['Button', 'ProductCard', 'SearchBar', 'Badge'],
patterns: ['product-grid', 'site-header', 'checkout-form'],
};
// El orden importa: cada capa se construye sobre la anterior.
const LAYERS = ['tokens', 'utilities', 'components', 'patterns'];
function systemInventory(system) {
console.log('=== Inventario del sistema de Mercado ===\n');
let total = 0;
LAYERS.forEach((layer, i) => {
const pieces = system[layer];
total += pieces.length;
const arrow = i < LAYERS.length - 1 ? ' ->' : ' ';
console.log(String(i + 1) + '. ' + layer.padEnd(11) + pieces.length + ' piezas' + arrow);
console.log(' ' + pieces.join(', '));
});
console.log('\nTotal de piezas en el sistema: ' + total);
}
systemInventory(mercadoSystem);
Qué esperar. Al correr el archivo, la salida es exactamente esta:
=== Inventario del sistema de Mercado ===
1. tokens 7 piezas ->
color.primary, color.surface, color.text, space-4, space-6, text-lg, radius-md
2. utilities 6 piezas ->
bg-primary, text-lg, p-4, flex, gap-4, rounded-md
3. components 4 piezas ->
Button, ProductCard, SearchBar, Badge
4. patterns 3 piezas
product-grid, site-header, checkout-form
Total de piezas en el sistema: 20
Lee la salida como lo que es: el sistema de Mercado, desarmado en sus cuatro capas. Cada línea numerada es una capa; el -> marca que arriba de ella hay otra que la usa; y las piezas listadas son los nombres reales que verás en toda la guía.
Fíjate en la forma de la pirámide. Hay 7 tokens, 6 utilidades, 4 componentes, 3 patrones: la base es ancha y la punta angosta. Eso no es casualidad, es la naturaleza de un sistema sano. Pocas cosas grandes, hechas de muchas cosas chicas. Hay pocos patrones porque cada uno reúne varios componentes; pocos componentes porque cada uno reúne varias utilidades; y las utilidades y los tokens son la base ancha porque son los átomos que todo lo demás combina. Si algún día vieras la pirámide invertida —cientos de componentes sobre tres tokens— sabrías que algo anda mal: son componentes que no comparten base, es decir, drift disfrazado de reutilización.
Y fíjate en el flujo hacia arriba, que es la clave de todo. La utilidad bg-primary (capa 2) usa el token color.primary (capa 1). El componente Button (capa 3) usa utilidades como bg-primary y p-4 (capa 2). El patrón product-grid (capa 4) usa el componente ProductCard (capa 3). Cada pieza se apoya en la capa de abajo. Por eso, si mañana cambias el token color.primary de azul a verde, la onda sube sola: bg-primary pinta verde, el Button se vuelve verde, y todos los product-grid que usan botones se vuelven verdes —con un solo cambio, en la capa más baja—. Ese es el superpoder que las cuatro capas te dan, y que la lección 5 mide en detalle.
Una pregunta para que te la hagas: si tuvieras que agregar un Badge de oferta al storefront, ¿en qué capa entra, y de qué capas de abajo dependería? (Es un componente —capa 3—, hecho de utilidades como bg-danger y text-sm —capa 2—, que a su vez usan tokens como color.danger y text-sm —capa 1—. Nunca al revés.)
Errores comunes
Empezar por los componentes y saltarse los tokens. Qué pasa: se abre el editor y lo primero que se construye es un Button bonito, con sus colores y espaciados escritos directamente en él. Por qué pasa: el componente es la capa visible, la que "se usa", y parece el lugar natural para empezar. Cómo detectarlo: tienes componentes reutilizables, pero cada uno tiene sus propios #3b82f6 y 16px a mano; dos componentes distintos no comparten ni un valor. Cómo corregirlo: construye de abajo hacia arriba. Primero los tokens (los valores nombrados), luego las utilidades que los aplican, y después los componentes que combinan utilidades. Un componente que define sus propios valores en vez de usar tokens es una puerta hecha con ladrillos de tamaños distintos: se ve como puerta, pero no encaja con el resto del edificio. La lección 1 ya nombró este error ("sistema ≠ librería de componentes"); aquí ves por qué: los componentes son la capa 3, y saltarse la 1 y la 2 los deja sin base común.
Confundir en qué capa vive cada cosa. Qué pasa: se mete lógica de espaciado dentro de un token (--card-with-two-columns-gap), o se mete un color a mano dentro de un componente saltándose la utilidad. Por qué pasa: las capas se sienten borrosas al principio y uno pone las cosas "donde caigan". Cómo detectarlo: tienes tokens que en realidad describen un componente entero, o componentes con valores mágicos que no salen de ningún token. Cómo corregirlo: hazte la pregunta de la capa. ¿Es un valor atómico con un rol? → token. ¿Aplica un token a un elemento? → utilidad. ¿Es una pieza reutilizable con variantes? → componente. ¿Es un arreglo de componentes? → patrón. Cada cosa tiene su capa; ponerla en la equivocada enreda el flujo hacia arriba y rompe la propiedad de "cambio un token, cambia todo".
Creer que las capas son opcionales o intercambiables. Qué pasa: alguien decide "yo hago componentes y patrones, los tokens y utilidades me los salto". Por qué pasa: se ven las capas de arriba como "lo importante" y las de abajo como burocracia. Cómo detectarlo: tus componentes se ven bien en aislamiento pero divergen entre sí, y cada cambio global es una cacería manual. Cómo corregirlo: las cuatro capas no son un menú del que eliges; son una dependencia. Un componente sin tokens debajo es un componente sin base común, y ahí vuelve el drift que todo el sistema existe para evitar. Puedes tener un sistema pequeño (pocos tokens, pocos componentes), pero no puedes tener uno sin capas de abajo: sería un edificio sin cimientos.
Ejercicios
Ejercicio 1 — Clasifica por capa. Para cada pieza, di en cuál de las cuatro capas vive (token / utilidad / componente / patrón):
- (a)
--color-danger: #dc2626 - (b)
SearchBar - (c)
text-sm(la clase que ponefont-sizedel tokentext-sm) - (d)
checkout-form(el arreglo de campos +Buttonde la página de pago)
Ver solución
- (a) Token. Es un valor atómico nombrado por su rol (
color-danger, el color de error/peligro). Capa 1. - (b) Componente.
SearchBares una pieza reutilizable con nombre (y probablemente variantes comosize). Capa 3. - (c) Utilidad.
text-sm(la clase) aplica un token a un elemento: pone elfont-sizedel tokentext-sm. Capa 2. (Ojo con el nombre repetido:text-smes el token de tamaño y el nombre de la utilidad que lo aplica; el módulo 3 aclara esta correspondencia.) - (d) Patrón.
checkout-formes un arreglo recurrente de componentes (campos +Button) que resuelve una necesidad (pagar). Capa 4.
La pregunta guía en cada caso: ¿valor atómico? token. ¿aplica un token? utilidad. ¿pieza con variantes? componente. ¿arreglo de piezas? patrón.
Ejercicio 2 — Predice el inventario. Sin correr nada, di qué "Total de piezas" imprimiría systemInventory para este sistema, y qué forma tendría la pirámide (¿base ancha o punta ancha?):
const miniSystem = {
tokens: ['color.primary', 'color.text', 'space-4'],
utilities: ['bg-primary', 'text-text'],
components: ['Button'],
patterns: [],
};
Ver solución
El total sería 6: 3 tokens + 2 utilidades + 1 componente + 0 patrones = 6.
La forma es la pirámide sana, base ancha y punta angosta: 3 en la base (tokens), 2 encima (utilidades), 1 arriba (componente), 0 en la punta (no hay patrones todavía). Es un sistema pequeño pero bien formado: cada capa tiene igual o menos piezas que la de abajo, y todo se apoya en los tokens. Que no haya patrones aún es normal en un sistema joven —los patrones aparecen cuando ya tienes varios componentes que combinar—. Lo que sí sería una alarma es lo contrario: muchos componentes sobre pocos o ningún token.
Ejercicio 3 — Traza el flujo hacia arriba. El componente ProductCard de Mercado usa, entre otras, la utilidad bg-surface y la utilidad p-4. La utilidad bg-surface aplica el token color.surface, y p-4 aplica el token space-4. Dibuja (en texto) la cadena de dependencias desde el patrón product-grid hasta los tokens, y responde: si cambias el token color.surface, ¿qué se actualiza y qué no?
Ver solución
La cadena, de arriba hacia abajo:
product-grid (patrón)
└─ usa ProductCard (componente)
├─ usa bg-surface (utilidad) ──> aplica color.surface (token)
└─ usa p-4 (utilidad) ──> aplica space-4 (token)
Si cambias el token color.surface (por ejemplo, de blanco a un gris muy claro):
- Se actualiza: la utilidad
bg-surface(ahora pinta el gris claro), y con ella todos losProductCard(su fondo cambia), y con ellos todos losproduct-grid(todas las cuadrículas de productos del storefront). Un solo cambio, en la capa 1, sube por las tres capas de arriba. - No se toca: el token
space-4, la utilidadp-4, ni ninguna otra pieza que no dependa decolor.surface. El padding de las tarjetas sigue igual, porque depende de otro token.
Esta es, en pequeño, la propiedad que hace valioso el sistema: el cambio viaja hacia arriba por las capas, exactamente hasta donde llega la dependencia, y ni un paso más. La lección 5 mide este superpoder ("un cambio, N actualizaciones") en detalle.
Resumen y siguiente paso
En esta lección abriste el mapa que vas a recordar el resto de la guía: las cuatro capas del sistema —tokens, utilidades, componentes, patrones—, cada una construida sobre la de abajo. Con la analogía de la ciudad viste que los tokens son la materia prima estandarizada (los ladrillos), las utilidades las técnicas que la aplican, los componentes las piezas prefabricadas con opciones, y los patrones la traza que las dispone. Ejecutaste el systemInventory de Mercado y viste la pirámide sana —7 tokens, 6 utilidades, 4 componentes, 3 patrones: base ancha, punta angosta— y el flujo hacia arriba que hace que cambiar un token en la base actualice todo lo construido encima. Y aprendiste la regla de oro: cada capa solo usa las de abajo, nunca las de arriba.
Antes de avanzar deberías poder: nombrar las cuatro capas en orden y qué contiene cada una; clasificar una pieza cualquiera en su capa; explicar por qué el orden va de abajo hacia arriba; y trazar cómo un cambio en un token sube por las capas.
La lección 4 toma una de estas capas —la base— y mide por qué da coherencia: la consistencia y el costo del drift. Vimos que un sistema elimina el drift; ahora vamos a cuantificarlo a través de varios roles a la vez (color, espaciado, radios) y a ponerle un número al caos —un "drift score"— para que la consistencia deje de ser una opinión estética y se vuelva algo que se mide. Es el argumento duro de por qué vale la pena montar las cuatro capas.
Recursos
- Brad Frost, "Atomic Design" (capítulo online) — atomicdesign.bradfrost.com/chapter-2. Las capas de átomos → moléculas → organismos → plantillas → páginas; el marco clásico del que descienden las cuatro capas de este módulo. En inglés.
- Design Tokens Community Group (W3C) — tr.designtokens.org/format. La especificación formal de la capa 1 (tokens): qué son y cómo se estructuran. En inglés.
- Tailwind CSS, "Styling with utility classes" — tailwindcss.com/docs/styling-with-utility-classes. La capa 2 (utilidades) en la herramienta que usarás desde el módulo 3. En inglés.
- shadcn/ui, "Components" — ui.shadcn.com/docs/components. Un catálogo real de la capa 3 (componentes con variantes) para ver piezas construidas sobre tokens. En inglés.