Base64 y Hex Nativos en JavaScript: Adiós al Truco de btoa() + unescape()
Uint8Array.toBase64(), fromBase64() y toHex() llegaron con ES2025 y ya funcionan en todos los navegadores. El hack que rompía con cualquier carácter Unicode por fin tiene sustituto oficial.
El peor snippet de JavaScript por fin tiene sustituto
Este código lleva más de una década en producción en medio internet:
// Codificar texto a Base64 "soportando Unicode"
const b64 = btoa(unescape(encodeURIComponent(texto)));
// Decodificar
const texto = decodeURIComponent(escape(atob(b64)));
Funciona... hasta que no. btoa solo acepta Latin-1, unescape/escape están deprecados desde hace décadas, y el pipeline URI→Latin-1 es frágil con cualquier entrada exótica. La respuesta oficial llegó con ES2025: métodos nativos en Uint8Array para Base64 y hex, ya disponibles en todos los navegadores modernos.
// Codificar
const bytes = new TextEncoder().encode('héllo wörld');
bytes.toBase64(); // 'aMOpbGxvIHfDtnJsZA=='
// Decodificar
const decoded = Uint8Array.fromBase64('aMOpbGxvIHfDtnJsZA==');
new TextDecoder().decode(decoded); // 'héllo wörld'
// Y de regalo, hex:
bytes.toHex(); // '68c3a96c6c6f2077c3b6726c64'
Uint8Array.fromHex('ff'); // Uint8Array [255]
Lo que la API resuelve de verdad
Base64url de serie
La API acepta opciones, incluido el alfabeto base64url — el mismo que usan los JWT:
bytes.toBase64({ alphabet: 'base64url', omitPadding: true });
// Seguro para URLs, tokens y headers sin '+', '/' ni '=' dando problemas
Si alguna vez reemplazaste + por - y / por _ a mano para meter un token en una URL, ya tienes método oficial. Y hablando de JWT: el payload base64url de cualquier token lo puedes inspeccionar directamente en nuestro decodificador JWT.
Streaming y arrays grandes
setFromBase64() escribe el resultado directamente sobre un array existente — sin copias intermedias — y las opciones lastChunkHandling controlan qué hacer con chunks parciales al procesar streams. Pensado para archivos grandes y WebSockets, no solo para textos.
Hex para hashes y binary debugging
El clásico Array.from(buf).map(b => b.toString(16).padStart(2, '0')).join('') —sí, el que usamos en nuestro post de SHA-256— se reduce a new Uint8Array(digest).toHex().
Estado del soporte
- Navegadores: Chrome/Edge, Firefox y Safari actuales ya lo traen (Baseline 2025).
- Node: disponible en las versiones recientes (24+/26+).
- Polyfill:
core-jslo incluye si necesitas cubrir navegadores antiguos.
Mientras la adopción termina, nada cambia en lo práctico: si lo que necesitas es codificar o decodificar Base64 ahora mismo sin montar un proyecto, nuestro codificador Base64 y decodificador siguen ahí para eso.
Detalle honesto: estas herramientas del sitio usan internamente el patrón clásico — como casi todo el software del planeta. La noticia es que por fin hay API estándar para dejar de hacerlo.
Related articles
El Gusano Shai-Hulud Sigue Vivo en npm: Qué Credenciales Rotar y en Qué Orden
tensorlake@0.5.144 es la última variante del gusano que roba tokens de npm, GitHub y tu .env antes de republicarse con tu identidad. Checklist práctico si instalaste paquetes afectados.
OAuth 2.1 Ya Jubila Oficialmente a RFC 6749: Estas Son las Reglas Nuevas
El draft-16 de OAuth 2.1, publicado en septiembre, declara obsoletos RFC 6749 y 6750: PKCE para todos, adiós al implicit grant. Y el nuevo BCP de validación de JWT está a punto de ser RFC.
Temporal Ya Es Estándar: La API Que Por Fin Sustituye a Date
TC39 aprobó Temporal en Stage 4 y ya funciona sin flags en Chrome, Firefox y Node 26. Qué cambia para tus timestamps, zonas horarias y cálculos de fechas.