Qué es un design system (y cómo ponerlo en marcha de verdad)
Una guía práctica para convertir componentes, patrones y reglas en una forma consistente de construir producto.
Qué es un design system (y cómo ponerlo en marcha de verdad)
En muchas empresas “design system” significa tener unos pocos componentes en Figma y poco más. Pero un design system de verdad es algo mucho más concreto: es la forma oficial de construir interfaz en tu producto.
Es un sistema porque combina:
- Decisiones visuales (colores, tipografías, espaciados…)
- Componentes reutilizables
- Patrones de interacción
- Reglas de uso
- Implementación en código
El objetivo es simple: que cualquier equipo pueda crear pantallas nuevas rápido, consistente y sin romper nada.
Por qué te interesa tener un design system
Un buen design system resuelve cuatro problemas muy comunes:
-
Inconsistencia visual Cada nuevo desarrollador “pinta” los botones de una forma diferente. Al cabo de un año, tu app parece un collage.
-
Velocidad de desarrollo Sin sistema, cada pantalla implica debatir colores, fuentes, tamaños, espaciados… Con sistema, ensamblas piezas ya pensadas.
-
Escalabilidad de equipos Cuando hay varios equipos trabajando en paralelo, necesitas un lenguaje común: “Botón primario”, “card de producto”, “alerta de error”, etc.
-
Calidad y accesibilidad Si resuelves accesibilidad una vez en los componentes base, se hereda en todo el producto. Menos bugs visuales, menos chapuzas.
De qué se compone un design system
1. Foundations: los fundamentos
Son los átomos sobre los que se construye todo:
-
Color
- Paleta principal, secundarios, neutrales y estados (success, warning, error, info).
- Idealmente modelado como tokens:
color.primary.500,color.text.muted, etc.
-
Tipografía
- Familias tipográficas permitidas.
- Jerarquía: H1–H6, párrafos, labels, captions.
-
Espaciado
- Escala de spacing:
4, 8, 12, 16, 24, 32, 48…(px o rem). - Reutilizada para padding, margin, gap, etc.
- Escala de spacing:
-
Radii, bordes y sombras
radius.sm,radius.md,radius.lg, etc.- Sombras estándar para tarjetas, modales…
-
Grid y breakpoints
- Puntos de corte responsive (sm, md, lg, xl…).
- Reglas básicas para layout.
Estos fundamentos deberían existir tanto en diseño (Figma, Sketch) como en código (CSS variables, Tailwind, tokens JSON…).
2. Componentes
Son las piezas reutilizables que realmente usas en las pantallas:
- Botones (
Button) - Campos de formulario (
Input,Textarea,Select) - Navegación (
Navbar,Sidebar,Tabs) - Feedback (
Alert,Toast,Badge) - Contenedores (
Card,Modal,Drawer)
Cada componente debería tener:
- Variantes (primario, secundario, ghost…)
- Estados (normal, hover, focus, disabled, loading)
- Reglas de cuándo usarlo y cuándo no
3. Patrones y layouts
Cuando combinas componentes, aparecen patrones recurrentes:
- Formulario de login/registro
- Listado + filtros + paginación
- Detalle de un item (producto, usuario)
- Wizards o flujos por pasos
Los patrones son importantes porque evitan que cada nueva pantalla invente una interacción distinta para lo mismo.
4. Documentación
Un design system sin documentación es simplemente “código que alguien hizo una vez”.
Necesitas:
- Catálogo de componentes con ejemplos
- “Do & Don’t” (ejemplos correctos e incorrectos)
- Reglas de accesibilidad
- Fragmentos de código listos para copiar/pegar
Herramientas habituales:
- Storybook (para ver componentes y sus estados)
- Documentación interna (Notion, Confluence…)
- Web interna del design system
5. Implementación en código
Al final, el design system se convierte en una librería de UI:
-
Por ejemplo, un paquete
@org/uipublicado en un registry -
Contiene:
- Componentes React
- Tokens (colores, tipografía, spacing…)
- Utilidades (hooks, helpers, etc.)
Los productos consumen esa librería y dejan de inventar sus propios botones, inputs, etc.
Cómo crear un design system paso a paso
Paso 1: Define objetivos y principios
Antes de tocar Figma o código, aclara:
- ¿Qué productos lo van a usar?
- ¿Cuántos equipos? ¿Qué nivel de disciplina hay ahora?
- ¿Qué problema quieres resolver primero? (ej. inconsistencia, velocidad, accesibilidad…)
Define principios sencillos, por ejemplo:
- “Primero accesible”
- “Mobile-first”
- “Menos variantes, más reutilización”
Te servirán como criterio cuando haya dudas.
Paso 2: Haz un inventario de la UI actual
No empieces desde cero imaginando el sistema ideal. Mira lo que ya tienes:
- Lista todos los botones, inputs, cards, modales, alerts…
- Apunta qué tipografías y tamaños se usan realmente
- Detecta todos los colores que están en producción
Objetivo: encontrar patrones y duplicados, y unificar.
Paso 3: Normaliza en forma de tokens
Con el inventario en la mano, reduce el caos:
- Unifica la paleta de colores (elimina variantes casi iguales)
- Limita el número de tamaños de texto
- Define una escala de espaciado coherente
Todo eso se convierte en tokens que luego usarás en código.
Ejemplo en Tailwind (Next 15 + Tailwind):
// tailwind.config.ts
import type { Config } from "tailwindcss";
const config: Config = {
theme: {
extend: {
colors: {
brand: {
50: "#eef6ff",
100: "#d9e8ff",
500: "#2563eb",
600: "#1d4ed8",
700: "#1e40af",
},
},
borderRadius: {
sm: "0.25rem",
md: "0.5rem",
lg: "0.75rem",
xl: "1rem",
},
spacing: {
1: "0.25rem",
2: "0.5rem",
3: "0.75rem",
4: "1rem",
6: "1.5rem",
8: "2rem",
},
},
},
plugins: [],
};
export default config;
Aquí ya estás metiendo parte del design system dentro del build de tu proyecto.
Paso 4: Construye los componentes core
Empieza por los que aparecen por todas partes:
ButtonInputSelectCard- Reglas de tipografía (H1–H6, body, etc.)
Un ejemplo de Button en React + TypeScript:
// components/ui/button.tsx
import { ComponentPropsWithoutRef } from "react";
import clsx from "clsx";
type Variant = "primary" | "secondary" | "ghost";
type Size = "sm" | "md" | "lg";
interface ButtonProps extends ComponentPropsWithoutRef<"button"> {
variant?: Variant;
size?: Size;
loading?: boolean;
}
const baseStyles =
"inline-flex items-center justify-center rounded-md font-medium focus:outline-none focus-visible:ring disabled:opacity-60 disabled:cursor-not-allowed transition";
const variantStyles: Record<Variant, string> = {
primary:
"bg-brand-600 text-white hover:bg-brand-700 focus-visible:ring-brand-500",
secondary:
"bg-white text-gray-900 border border-gray-300 hover:bg-gray-50 focus-visible:ring-brand-500",
ghost:
"bg-transparent text-gray-700 hover:bg-gray-100 focus-visible:ring-brand-500",
};
const sizeStyles: Record<Size, string> = {
sm: "px-3 py-1.5 text-sm",
md: "px-4 py-2 text-sm",
lg: "px-5 py-2.5 text-base",
};
export function Button({
variant = "primary",
size = "md",
loading = false,
className,
children,
...props
}: ButtonProps) {
return (
<button
className={clsx(
baseStyles,
variantStyles[variant],
sizeStyles[size],
className
)}
disabled={loading || props.disabled}
{...props}
>
{loading && (
<span className="mr-2 inline-block h-4 w-4 animate-spin rounded-full border-2 border-t-transparent" />
)}
{children}
</button>
);
}
Este componente ya captura decisiones de diseño: colores, radios, padding, tamaños, estados…
Paso 5: Documenta mientras construyes
Por cada componente que añadas:
- Qué problema resuelve
- Variantes disponibles
- Estados
- Props/atributos y ejemplos de código
- “Uso recomendado” y “mal uso”
Lo ideal es que esto viva en:
- Storybook (ejemplos interactivos)
- Algún espacio con texto y contexto (Notion, por ejemplo)
Paso 6: Integra el design system en tus productos
Cuando tengas un mínimo de fundamentos + componentes:
- Empieza a migrar pantallas al nuevo sistema
- Bloquea la creación de “componentes caseros” que duplican lo existente
- Usa revisiones de código para reforzar el uso del design system
Lo importante es que el sistema se use, aunque sea pequeño al principio.
Paso 7: Gobernanza y evolución
Un design system no es un documento estático. Debes definir:
- Quién puede proponer nuevos componentes o cambios
- Cómo se discuten (issues, RFCs, reuniones cortas)
- Cómo se versiona la librería (
1.2.3, cambios breaking, etc.) - Cómo se comunican las novedades al resto de equipos
Si no gestionas esto, el sistema se fragmenta y pierdes los beneficios iniciales.
Cómo testear tu design system de forma eficaz
Si los componentes del design system se rompen, se rompe todo lo que depende de ellos. Te interesa testearlos bien.
1. Tests unitarios de componentes
Con React Testing Library + Jest o Vitest:
- El componente se renderiza con el texto previsto
- Se disparan los callbacks (
onClick,onChange, etc.) - Las clases/estilos cambian según
variant,size,disabled,loading…
Ejemplo mínimo de test de botón:
// components/ui/button.test.tsx
import { render, screen, fireEvent } from "@testing-library/react";
import { Button } from "./button";
test("renderiza el texto y ejecuta onClick", () => {
const handleClick = vi.fn();
render(<Button onClick={handleClick}>Enviar</Button>);
const btn = screen.getByRole("button", { name: /enviar/i });
fireEvent.click(btn);
expect(handleClick).toHaveBeenCalledTimes(1);
});
2. Tests de regresión visual
Muy recomendables para un design system:
-
Usa Storybook para tener todas las variantes controladas
-
Añade una herramienta de regresión visual:
- Chromatic
- Playwright con screenshots y snapshots visuales
Esto detecta cambios inesperados en estilos al modificar CSS o tokens.
3. Tests de accesibilidad
- Integra herramientas como
axe/jest-axe - O el addon de accesibilidad de Storybook
Ejemplo rápido:
import { render } from "@testing-library/react";
import { Button } from "./button";
import { axe } from "jest-axe";
test("Button no introduce violaciones de accesibilidad básicas", async () => {
const { container } = render(<Button>Enviar</Button>);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
Si tu design system cuida accesibilidad, todo el producto mejora “gratis”.
Errores típicos al crear un design system
- Intentar definirlo todo antes de usar nada en producción
- Crear demasiadas variantes que nadie necesita
- Diseñar solo en Figma sin pensar en la implementación real
- No versionar ni documentar cambios
- No invertir en tests visuales y de accesibilidad
Conclusión
Un design system no es un lujo estético; es una herramienta de ingeniería y producto:
- Alinea a diseño, desarrollo y negocio
- Reduce inconsistencias
- Acelera el desarrollo
- Mejora la calidad y la accesibilidad
No hace falta empezar con algo gigante. Con unos fundamentos claros, 3–4 componentes bien pensados, buena documentación y tests básicos, ya tienes la base de algo que de verdad aporta valor y puede crecer con tu producto.