Vercel: Experiencia de Desarrollador como Diseño
Cómo Vercel hizo de la experiencia del desarrollador el producto: diseño dark-mode-first, indicadores de estado en pestañas, UI optimista y estados vacíos funcionales. Con patrones de implementación CSS y JavaScript.
Vercel: La experiencia del desarrollador como diseño
«Los desarrolladores son alérgicos a la mala UX — no quieren un "onboarding encantador" si los ralentiza.»
La filosofía de diseño de Vercel es implacablemente centrada en el desarrollador. El sistema de diseño Geist prioriza la claridad, la velocidad y la densidad de información por encima de la decoración. Cada píxel está al servicio del flujo de trabajo del desarrollador.
Por qué Vercel importa
Vercel demuestra que las herramientas para desarrolladores pueden tener un diseño excepcional sin ser "diseñosas". El dashboard es rápido, denso en información y no se interpone en el camino.
Logros clave: - Creó Geist, una tipografía diseñada específicamente para desarrolladores - El rediseño del dashboard redujo el First Meaningful Paint en 1.2s - Fue pionero en el diseño dark-mode-first en herramientas para desarrolladores - Estableció el estándar para la UX de despliegue - Iconos de pestaña que reflejan el estado del despliegue (compilando, error, listo)
Conclusiones clave
- El modo oscuro es respeto, no una funcionalidad - Los desarrolladores trabajan en terminales e IDEs con fondos oscuros; un dashboard blanco genera cambios de contexto bruscos y fatiga visual
- El estado debe estar visible en todas partes - Favicons en pestañas, títulos de página, puntos en la línea de tiempo: el estado del despliegue debería ser visible sin cambiar de foco ni abrir pestañas
- La UI optimista elimina la latencia percibida - Muestra el estado esperado de inmediato, sincroniza con la realidad en segundo plano; los desarrolladores notan retrasos de 300ms
- Los estados vacíos son instrucciones, no ilustraciones - Muestra el comando exacto a ejecutar (
git push origin main), no un gráfico decorativo con un botón de "Comenzar" - El rendimiento es diseño - El rediseño del dashboard de Vercel redujo el First Meaningful Paint en 1.2s; ninguna cantidad de animaciones bonitas compensa tiempos de carga lentos
Filosofía de diseño fundamental
El principio centrado en el desarrollador
Los desarrolladores juzgan los productos por lo poco que los ralentizan. El diseño de Vercel refleja esto:
ANTI-PATRONES (Lo que los desarrolladores odian) ENFOQUE DE VERCEL
───────────────────────────────────────────────────────────────────
Animaciones "encantadoras" que añaden retraso Estados instantáneos, sin transiciones
Wizards de onboarding que bloquean el trabajo CLI-first, dashboard opcional
Documentación densa oculta en pestañas Información visible de un vistazo
Spinners de carga en cada acción Actualizaciones optimistas + SWR
Texto de marketing en el dashboard UI puramente funcional
Idea clave: Los desarrolladores no quieren ser "deleitados". Quieren desplegar.
Biblioteca de patrones
1. Excelencia en modo oscuro
El modo oscuro de Vercel no es un toggle. Es el valor por defecto. El diseño es quirúrgico: blanco y negro puros crean el máximo contraste.
Filosofía de color:
:root {
/* La paleta de Vercel es notablemente simple */
/* Fondos - negro puro, sin grises */
--bg-000: #000000;
--bg-100: #0A0A0A;
--bg-200: #111111;
/* Primer plano - blanco de alto contraste */
--fg-100: #FFFFFF;
--fg-200: #EDEDED;
--fg-300: #A1A1A1;
--fg-400: #888888;
/* Bordes - sutiles pero visibles */
--border-100: #333333;
--border-200: #444444;
/* Semánticos - estado de despliegue */
--color-success: #00DC82; /* Verde - desplegado */
--color-error: #FF0000; /* Rojo - fallido */
--color-warning: #FFAA00; /* Ámbar - compilando */
--color-info: #0070F3; /* Azul - en cola */
/* El acento - la firma de Vercel */
--accent: #FFFFFF; /* Blanco como acento sobre negro */
}
Por qué funciona el negro puro: - Máximo contraste para la legibilidad del texto - Estética inspirada en la terminal que los desarrolladores reconocen - Reduce la fatiga visual en entornos oscuros - Hace que los indicadores de estado con color destaquen
2. Indicadores de estado en pestañas
Vercel refleja el estado del despliegue en los iconos de las pestañas del navegador, haciendo visible la información incluso cuando la pestaña no está en primer plano.
┌─ Barra de pestañas del navegador ──────────────────────────────────┐
│ │
│ [▶] acme-web - Compilando [✓] blog - Listo [✕] api - Error │
│ │
└────────────────────────────────────────────────────────────────────┘
Estados del icono de pestaña:
⏳ En cola (círculo gris)
▶ Compilando (spinner animado)
✓ Listo (check verde)
✕ Error (X roja)
Patrón de implementación:
// Favicon dinámico basado en el estado del despliegue
function updateFavicon(status) {
const link = document.querySelector("link[rel~='icon']");
const icons = {
queued: '/favicon-queued.svg',
building: '/favicon-building.svg', // Animado
ready: '/favicon-ready.svg',
error: '/favicon-error.svg',
};
link.href = icons[status];
}
// El título también refleja el estado
function updateTitle(projectName, status) {
const prefixes = {
queued: '⏳',
building: '▶',
ready: '✓',
error: '✕',
};
document.title = `${prefixes[status]} ${projectName} - Vercel`;
}
Idea clave: Los desarrolladores tienen muchas pestañas abiertas. El estado visible en la barra de pestañas significa que no necesitan cambiar de pestaña para verificar el estado de la compilación.
3. Línea de tiempo de despliegue
El inspector de despliegue muestra una línea de tiempo clara del proceso de despliegue.
┌─ Línea de tiempo de despliegue ────────────────────────────────────┐
│ │
│ [o] En cola 12:34:56 PM │
│ │ │
│ [o] Compilando 12:34:58 PM │
│ │ └─ Instalando dependencias... 3.2s │
│ │ └─ Compilando... 12.4s │
│ │ └─ Generando páginas estáticas... 2.1s │
│ │ │
│ [o] Desplegando 12:35:14 PM │
│ │ └─ Subiendo artefactos de compilación... │
│ │ │
│ [*] Listo 12:35:18 PM │
│ └─ https://acme-abc123.vercel.app │
│ │
│ Total: 22s │
│ │
└────────────────────────────────────────────────────────────────────┘
Codificación visual:
.timeline-step {
position: relative;
padding-left: 24px;
}
.timeline-step::before {
content: '';
position: absolute;
left: 0;
top: 6px;
width: 10px;
height: 10px;
border-radius: 50%;
background: var(--step-color);
}
/* Línea de conexión */
.timeline-step:not(:last-child)::after {
content: '';
position: absolute;
left: 4px;
top: 16px;
width: 2px;
height: calc(100% - 6px);
background: var(--border-100);
}
/* Estados de los pasos */
.timeline-step[data-status="complete"]::before {
background: var(--color-success);
}
.timeline-step[data-status="active"]::before {
background: var(--color-warning);
animation: pulse 1.5s infinite;
}
.timeline-step[data-status="error"]::before {
background: var(--color-error);
}
.timeline-step[data-status="pending"]::before {
background: var(--fg-400);
}
4. Diseño del Visor de Logs
El visor de logs de Vercel está integrado en la vista general del despliegue, no en una página separada.
┌─ Build Logs ───────────────────────────────────────────────────────┐
│ │
│ Filter: [All ▼] [Function: api/hello ▼] [Copy] [↓] │
│ │
├────────────────────────────────────────────────────────────────────┤
│ │
│ 12:34:58.123 info Installing dependencies... │
│ 12:35:01.456 info added 1234 packages in 3.2s │
│ 12:35:01.789 info Running build... │
│ 12:35:14.012 info ✓ Compiled successfully │
│ 12:35:14.234 warn Large bundle size: pages/index.js (245kb) │
│ 12:35:14.567 info Generating static pages... │
│ 12:35:16.890 info ✓ Generated 42 pages │
│ │
└────────────────────────────────────────────────────────────────────┘
Características clave: - Copia al portapapeles con un solo clic - Filtrado por función o salida de compilación - Niveles de log con código de colores (info, warn, error) - Marcas de tiempo con precisión de milisegundos - URLs compartibles para líneas de log específicas
Implementación:
.log-line {
display: flex;
font-family: var(--font-mono);
font-size: 12px;
line-height: 1.6;
padding: 2px 12px;
}
.log-line:hover {
background: var(--bg-200);
}
.log-timestamp {
color: var(--fg-400);
min-width: 100px;
margin-right: 12px;
}
.log-level {
min-width: 48px;
margin-right: 12px;
}
.log-level[data-level="info"] { color: var(--fg-300); }
.log-level[data-level="warn"] { color: var(--color-warning); }
.log-level[data-level="error"] { color: var(--color-error); }
.log-message {
color: var(--fg-100);
white-space: pre-wrap;
word-break: break-word;
}
5. Estados Vacíos
Los estados vacíos de Vercel son funcionales, no decorativos. Te indican qué hacer a continuación.
┌─ Empty State: No Deployments ──────────────────────────────────────┐
│ │
│ │
│ No deployments yet │
│ │
│ Push to your repository to create │
│ your first deployment │
│ │
│ │
│ git push origin main │
│ │
│ │
│ [View Documentation] │
│ │
│ │
└────────────────────────────────────────────────────────────────────┘
Principios de diseño: - Sin ilustraciones decorativas - Acción clara (el comando git) - Enlace útil a la documentación - Monoespaciado para comandos (fácil de copiar)
Sistema de Diseño Visual
Tipografía (Geist)
Vercel creó Geist específicamente para experiencias de desarrollador:
:root {
/* Geist Sans - UI and body text */
--font-sans: 'Geist', -apple-system, BlinkMacSystemFont, sans-serif;
/* Geist Mono - code and technical content */
--font-mono: 'Geist Mono', 'SF Mono', monospace;
/* Size scale */
--text-xs: 12px;
--text-sm: 13px;
--text-base: 14px;
--text-lg: 16px;
--text-xl: 18px;
--text-2xl: 24px;
/* Line heights */
--leading-tight: 1.25;
--leading-normal: 1.5;
--leading-relaxed: 1.75;
/* Letter spacing */
--tracking-tight: -0.02em;
--tracking-normal: 0;
--tracking-wide: 0.02em;
}
/* Tabular numbers for data */
.tabular-nums {
font-variant-numeric: tabular-nums;
}
/* Or use Geist Mono for comparisons */
.data-value {
font-family: var(--font-mono);
}
Sistema de Espaciado
:root {
/* 4px base unit */
--space-1: 4px;
--space-2: 8px;
--space-3: 12px;
--space-4: 16px;
--space-5: 20px;
--space-6: 24px;
--space-8: 32px;
--space-10: 40px;
--space-12: 48px;
--space-16: 64px;
}
Border Radius
:root {
/* Radios sutiles y consistentes */
--radius-sm: 4px;
--radius-md: 6px;
--radius-lg: 8px;
--radius-xl: 12px;
--radius-full: 9999px;
}
Patrones de Animación
Actualizaciones Optimistas
Vercel utiliza actualizaciones de interfaz optimistas. Las acciones se sienten instantáneas.
// Patrón SWR para actualizaciones en tiempo real
const { data, mutate } = useSWR('/api/deployments');
async function triggerDeploy() {
// Mostrar inmediatamente el estado "desplegando"
mutate(
{ ...data, status: 'building' },
false // No revalidar todavía
);
// Luego ejecutar realmente
await fetch('/api/deploy', { method: 'POST' });
// Revalidar para obtener el estado real
mutate();
}
Estados de Carga Sutiles
/* Carga skeleton - sin spinners */
.skeleton {
background: linear-gradient(
90deg,
var(--bg-200) 0%,
var(--bg-100) 50%,
var(--bg-200) 100%
);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
border-radius: var(--radius-md);
}
@keyframes shimmer {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
Estados de Botones
.button {
transition: background 100ms ease, transform 100ms ease;
}
.button:hover {
background: var(--fg-100);
}
.button:active {
transform: scale(0.98);
}
/* Sin transiciones largas - retroalimentación instantánea */
Optimizaciones de Rendimiento (Informadas por el Diseño)
El rediseño del dashboard de Vercel incluyó decisiones de diseño que mejoraron el rendimiento:
Técnicas utilizadas: - Preconexión a los orígenes de API, Assets y Avatar - Las llamadas críticas a la API reciben mayor prioridad del navegador - Memoización de componentes React (useMemo, useCallback) - ReactDOM.unstable_batchedUpdates redujo los re-renders en un 20% - SWR para actualizaciones eficientes de datos en tiempo real
Idea clave: El rendimiento ES diseño. Un dashboard lento con animaciones hermosas es peor que un dashboard rápido sin ninguna.
Lecciones para Nuestro Trabajo
1. Modo Oscuro como Predeterminado
Cuando tus usuarios trabajan en entornos oscuros (terminales, IDEs), el modo oscuro no es una funcionalidad—es respeto.
2. Estado en Cada Rincón
Iconos de pestaña, títulos de página, indicadores de línea de tiempo: el estado debe ser visible sin necesidad de enfocar la atención.
3. Optimista por Defecto
Muestra el estado esperado de inmediato. Actualiza con la realidad en segundo plano.
4. Los Desarrolladores Odian Esperar
Nada de spinners de carga si puedes evitarlos. Estados skeleton, actualizaciones optimistas, precarga.
5. Los Estados Vacíos Son Instrucciones
No muestres una ilustración bonita. Muestra el comando que necesitan ejecutar.
Preguntas Frecuentes
¿Por qué Vercel usa negro puro (#000000) en lugar de gris oscuro para los fondos?
El negro puro proporciona el máximo contraste para el texto blanco, creando una legibilidad óptima. También coincide con la estética de las terminales y editores de código que los desarrolladores ya utilizan, haciendo que el dashboard se sienta como una parte nativa de su flujo de trabajo. Los fondos en gris oscuro suelen parecer más "suaves" pero reducen el contraste y pueden verse deslavados en pantallas de alta resolución.
¿Cómo funcionan los indicadores de estado en las pestañas de Vercel?
Vercel actualiza dinámicamente el favicon del navegador según el estado del despliegue: un spinner durante la compilación, una marca verde cuando está listo, una X roja en caso de error. El título de la página también se actualiza con prefijos de emoji (▶, ✓, ✕). Esto significa que los desarrolladores pueden monitorear múltiples despliegues en distintas pestañas sin cambiar el foco—el estado es visible de un vistazo en la barra de pestañas del navegador.
¿Cuál es el enfoque de Vercel respecto a los estados de carga?
Vercel evita los spinners de carga tradicionales en favor de la interfaz optimista y las pantallas skeleton. Cuando activas un despliegue, la interfaz muestra inmediatamente el estado "compilando" antes de que el servidor confirme. La biblioteca SWR se encarga de la revalidación en segundo plano. Esto hace que las acciones se sientan instantáneas incluso cuando las solicitudes de red tardan entre 200 y 500ms.
¿Qué es Geist y por qué Vercel creó una tipografía personalizada?
Geist es una familia tipográfica que Vercel diseñó específicamente para interfaces de desarrollo. Incluye Geist Sans para texto de interfaz y Geist Mono para código. El diseño está optimizado para tamaños pequeños (12-14px) comunes en dashboards, incluye números tabulares para columnas de datos alineadas y tiene formas de caracteres diferenciadas para evitar confusión entre glifos similares (l, 1, I).
¿Cómo maneja Vercel los estados vacíos de forma diferente a otros productos?
Los estados vacíos de Vercel muestran comandos accionables, no ilustraciones decorativas. Una página de despliegues vacía muestra git push origin main en tipografía monoespaciada (facilitando el copiado) en lugar de una caricatura con un botón genérico de "Comenzar". La filosofía es que los desarrolladores quieren saber exactamente qué hacer, no ser calmados visualmente.