Back

Generación de IDs únicos con la Web Crypto API

Generación de IDs únicos con la Web Crypto API

Todo desarrollador frontend eventualmente enfrenta este problema: necesitas un identificador único para datos del lado del cliente, pero aún no hay un ID generado por el servidor. Quizás estés construyendo una lista de tareas, gestionando campos de formulario o rastreando elementos antes de que se persistan. Necesitas algo confiable, y lo necesitas ahora.

¿Las buenas noticias? Los navegadores modernos incluyen una solución integrada. La Web Crypto API proporciona crypto.randomUUID()—una forma simple y segura de generar IDs únicos en el navegador sin instalar ninguna librería.

Puntos Clave

  • crypto.randomUUID() produce UUIDs v4 criptográficamente seguros y compatibles con RFC de forma nativa en el navegador con cero dependencias.
  • Siempre genera los IDs en el momento de creación del objeto, no durante los ciclos de renderizado.
  • El método requiere un contexto seguro (HTTPS o localhost).
  • Para entornos que carecen de crypto.randomUUID(), usa crypto.getRandomValues() como alternativa ligera.

Por qué crypto.randomUUID() debería ser tu opción predeterminada

El método crypto.randomUUID() produce UUIDs versión 4 compatibles con RFC 9562 (anteriormente RFC 4122) utilizando un generador de números aleatorios criptográficamente seguro. La salida se ve así:

550e8400-e29b-41d4-a716-446655440000

Es una cadena de 36 caracteres con 122 bits de aleatoriedad. La probabilidad de colisión es astronómicamente baja—necesitarías generar mil millones de UUIDs por segundo durante aproximadamente 85 años para alcanzar un 50% de probabilidad de una sola colisión.

Así de simple es:

function generateId() {
  return crypto.randomUUID()
}

const newItem = { id: generateId(), label: 'My item' }

Este método funciona en todos los navegadores modernos (Chrome 92+, Firefox 95+, Safari 15.4+), se ejecuta en Web Workers y no requiere dependencias.

El requisito de contexto seguro

Un detalle crítico: crypto.randomUUID() solo funciona en contextos seguros. Esto significa HTTPS en producción o localhost durante el desarrollo. Si estás probando sobre HTTP simple en un dominio que no es localhost, el método no estará disponible.

Este requisito existe porque la Web Crypto API proporciona primitivas criptográficas que no deberían exponerse en entornos inseguros.

Por qué los patrones antiguos se quedan cortos

Antes de que crypto.randomUUID() estuviera ampliamente disponible, los desarrolladores solían recurrir a alternativas que parecen razonables pero tienen problemas reales.

Math.random() no es criptográficamente seguro. Su salida puede ser predecible, y las colisiones son mucho más probables de lo que esperarías en aplicaciones de producción.

Timestamps (como Date.now()) fallan cuando se generan múltiples IDs en el mismo milisegundo—un escenario común en bucles u operaciones por lotes.

Generadores ad-hoc que combinan timestamps con números aleatorios son mejores, pero están reinventando un problema resuelto con menos rigurosidad que la que proporciona la plataforma de forma nativa.

Para la generación segura de IDs del lado del cliente, crypto.randomUUID() es la elección clara.

Consideraciones prácticas de frontend

Genera una vez, almacena inmediatamente

El error más común es generar IDs durante los ciclos de renderizado. En su lugar, crea el ID cuando se crea el objeto y almacénalo:

// ✓ Correcto: ID generado en el momento de creación
function addItem(label) {
  return { id: crypto.randomUUID(), label }
}

// ✗ Incorrecto: ID generado durante el renderizado
items.map(item => <li key={crypto.randomUUID()}>{item.label}</li>)

Generar un nuevo UUID en cada renderizado derrota el propósito de las keys estables. React, por ejemplo, usa keys para rastrear elementos a través de re-renderizados. Una nueva key cada vez fuerza el desmontaje y recreación innecesarios del DOM.

SSR y entornos de navegador

Si estás usando renderizado del lado del servidor, crypto.randomUUID() está disponible en Node.js 19+ y versiones recientes de otros runtimes. Para versiones antiguas de Node o casos especiales, verifica la disponibilidad antes de llamar:

const id = typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'
  ? crypto.randomUUID()
  : fallbackGenerator()

Una estrategia de respaldo ligera

Para entornos donde crypto.randomUUID() no está disponible, crypto.getRandomValues() tiene un soporte más amplio (incluyendo Node.js 16+) y puede generar UUIDs sin librerías:

function fallbackUUID() {
  const bytes = crypto.getRandomValues(new Uint8Array(16))
  bytes[6] = (bytes[6] & 0x0f) | 0x40 // Version 4
  bytes[8] = (bytes[8] & 0x3f) | 0x80 // Variant 10
  
  const hex = [...bytes].map(b => b.toString(16).padStart(2, '0')).join('')
  return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`
}

Esto establece manualmente los bits de versión y variante para producir un UUID v4 válido, utilizando la misma fuente aleatoria criptográficamente segura bajo el capó.

Cuándo las librerías aún tienen sentido

Aunque crypto.randomUUID() cubre la mayoría de los casos, podrías recurrir a una librería como uuid o nanoid cuando necesites:

  • Versiones de UUID que no sean v4 (v1, v5, v7)
  • IDs más cortos para URLs o visualizaciones de cara al usuario
  • Compatibilidad garantizada entre entornos con runtimes más antiguos

Pero para la generación estándar de IDs seguros del lado del cliente, la API nativa debería ser tu punto de partida.

Conclusión

crypto.randomUUID() te proporciona UUIDs criptográficamente seguros y compatibles con RFC sin dependencias. Genera IDs en el momento de creación del objeto, no durante los renderizados. Usa HTTPS en producción. Para casos especiales, recurre a crypto.getRandomValues(). El navegador ya tiene lo que necesitas—úsalo.

Preguntas frecuentes

Sí, los UUIDs v4 generados por crypto.randomUUID() son adecuados como claves primarias. Los 122 bits de aleatoriedad criptográfica hacen que las colisiones sean prácticamente imposibles. Sin embargo, ten en cuenta que los UUIDs aleatorios pueden causar fragmentación de índices en algunas bases de datos. Si el rendimiento de inserción importa a escala, considera UUID v7, que está ordenado por tiempo, aunque eso requiere una librería.

Requiere un contexto seguro porque la Web Crypto API expone primitivas criptográficas. Los navegadores restringen estas a HTTPS y localhost para prevenir ataques de intermediario que manipulen operaciones criptográficas. Durante el desarrollo local en localhost, funciona sin HTTPS. En producción, necesitas un certificado TLS válido.

Sí. El objeto crypto y su método randomUUID están disponibles en Web Workers, Service Workers y Shared Workers, siempre que el contexto sea seguro. Esto lo hace conveniente para generar IDs en hilos de fondo sin necesidad de comunicarse de vuelta al hilo principal para la creación de IDs.

crypto.randomUUID() produce UUIDs v4 estándar de 36 caracteres usando el generador aleatorio criptográfico integrado del navegador. nanoid genera IDs más cortos y amigables para URLs con un alfabeto y longitud personalizables, y funciona en más entornos de forma inmediata. Elige randomUUID para cumplimiento de estándares y cero dependencias. Elige nanoid cuando necesites IDs compactos o soporte más amplio de runtimes.

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Check our GitHub repo and join the thousands of developers in our community.

OpenReplay