Codificación Base64 en JavaScript: Guía Completa
Usa el Codificador Base64 Online gratuito directamente en tu navegador — sin instalación.
Probar Codificador Base64 Online online →Cuando incrustas una imagen en una URI de datos CSS, pasas credenciales en un encabezado HTTP Authorization, o almacenas un certificado binario en una variable de entorno, necesitas codificar datos JavaScript en Base64 de forma fiable tanto en el navegador como en Node.js. JavaScript proporciona dos APIs integradas distintas:btoa() para entornos de navegador (también disponible en Node.js 16+) y Buffer.from() para Node.js — cada una con diferentes restricciones en torno a Unicode, datos binarios y seguridad en URLs. Para una codificación rápida sin escribir ningún código, el Codificador Base64 de ToolDeck lo maneja al instante en el navegador. Esta guía cubre ambos entornos con ejemplos listos para producción: manejo de Unicode, variantes URL-safe, codificación de archivos y respuestas de API, uso CLI, y los cuatro errores que causan bugs consistentemente en proyectos reales.
- ✓btoa() es nativo del navegador y está disponible en Node.js 16+ de forma global, pero solo acepta Latin-1 (puntos de código 0–255) — la entrada Unicode lanza una DOMException
- ✓Buffer.from(text, "utf8").toString("base64") es el equivalente en Node.js y maneja Unicode de forma nativa sin pasos adicionales
- ✓URL-safe Base64 reemplaza + → -, / → _, y elimina el relleno = — usa Buffer.from().toString("base64url") en Node.js 18+ para hacerlo en una sola línea
- ✓Para datos binarios (ArrayBuffer, Uint8Array, archivos), usa Buffer en Node.js o el enfoque arrayBuffer() + Uint8Array en el navegador — nunca response.text()
- ✓Uint8Array.prototype.toBase64() (TC39 Stage 3) ya está disponible en Node.js 22+ y Chrome 130+ y unificará ambos entornos
¿Qué es la Codificación Base64?
Base64 convierte datos binarios arbitrarios en una cadena formada por 64 caracteres ASCII imprimibles: A–Z, a–z, 0–9, +, y /. Cada 3 bytes de entrada se asignan exactamente a 4 caracteres Base64; si la longitud de la entrada no es múltiplo de 3, se agregan uno o dos caracteres de relleno =. La salida codificada es siempre aproximadamente un 33% más grande que el original.
Base64 no es cifrado — no proporciona confidencialidad. Cualquier persona con la cadena codificada puede decodificarla con una sola llamada a función. Su propósito es la seguridad en el transporte: muchos protocolos y formatos de almacenamiento fueron diseñados para texto ASCII de 7 bits y no pueden manejar bytes binarios arbitrarios. Base64 cubre esa brecha. Los casos de uso comunes en JavaScript incluyen URIs de datos para incrustar recursos, encabezados HTTP Basic Auth, segmentos de tokens JWT, adjuntos MIME de correo electrónico, y almacenamiento de blobs binarios en APIs JSON.
deploy-bot:sk-prod-a7f2c91e4b3d8
ZGVwbG95LWJvdDpzay1wcm9kLWE3ZjJjOTFlNGIzZDg=
btoa() — La Función de Codificación Nativa del Navegador
btoa() (binary-to-ASCII) ha estado disponible en navegadores desde IE10 y se convirtió en global en Node.js 16.0 como parte de la iniciativa de compatibilidad WinterCG. También funciona de forma nativa en Deno, Bun y Cloudflare Workers. No se necesita ninguna importación.
La función toma un único argumento de tipo cadena y devuelve su forma codificada en Base64. La contraparte simétrica atob() (ASCII-to-binary) la decodifica de vuelta. Ambas son síncronas y se ejecutan en memoria constante relativa al tamaño de la entrada.
Ejemplo mínimo funcional
// Encoding an API credential pair for an HTTP Basic Auth header
const serviceId = 'deploy-bot'
const apiKey = 'sk-prod-a7f2c91e4b3d8'
const credential = btoa(`${serviceId}:${apiKey}`)
// → 'ZGVwbG95LWJvdDpzay1wcm9kLWE3ZjJjOTFlNGIzZDg='
const headers = new Headers({
Authorization: `Basic ${credential}`,
'Content-Type': 'application/json',
})
console.log(headers.get('Authorization'))
// Basic ZGVwbG95LWJvdDpzay1wcm9kLWE3ZjJjOTFlNGIzZDg=Decodificación con atob()
// Round-trip: encode, transmit, decode const payload = 'service:payments region:eu-west-1 env:production' const encoded = btoa(payload) const decoded = atob(encoded) console.log(encoded) // c2VydmljZTpwYXltZW50cyByZWdpb246ZXUtd2VzdC0xIGVudjpwcm9kdWN0aW9u console.log(decoded === payload) // true
btoa() y atob() forman parte de la API Mínima Común de WinterCG — la misma especificación que rige Fetch, URL y crypto en runtimes que no son navegadores. Se comportan de forma idéntica en Node.js 16+, Bun, Deno y Cloudflare Workers.Manejo de Unicode y Caracteres No-ASCII
El problema más común con btoa() es su estricto límite de Latin-1. Cualquier carácter con un punto de código superior a U+00FF causa una excepción inmediata:
btoa('Müller & Søren') // ❌ Uncaught DOMException: String contains an invalid character
btoa('résumé') // ❌ 'é' is U+00E9 = 233 — within Latin-1, this one actually works
btoa('田中太郎') // ❌ Throws — all CJK characters are above U+00FFEl enfoque correcto es codificar primero la cadena a bytes UTF-8, luego codificar esos bytes en Base64. JavaScript proporciona TextEncoder exactamente para este propósito:
Enfoque con TextEncoder — seguro para cualquier entrada Unicode
// Utility functions for Unicode-safe Base64
function toBase64(text: string): string {
const bytes = new TextEncoder().encode(text)
const chars = Array.from(bytes, byte => String.fromCharCode(byte))
return btoa(chars.join(''))
}
function fromBase64(encoded: string): string {
const binary = atob(encoded)
const bytes = Uint8Array.from(binary, ch => ch.charCodeAt(0))
return new TextDecoder().decode(bytes)
}
// Works with any language or script
const orderNote = 'Confirmado: Carlos Mendoza — almacén Madrid, cant: 250'
const encoded = toBase64(orderNote)
const decoded = fromBase64(encoded)
console.log(encoded)
// Q29uZmlybWFkbzogQ2FybG9zIE1lbmRvemEg4oCTIGFsbWFjw6luIE1hZHJpZCwgY2FudDogMjUw
console.log(decoded === orderNote) // trueBuffer.from(text, 'utf8').toString('base64'). Maneja Unicode de forma nativa y es más rápido para cadenas largas.Buffer.from() en Node.js — Guía Completa con Ejemplos
En Node.js, Buffer es la API idiomática para todas las operaciones con datos binarios, incluidas las conversiones de codificación. Precede a TextEncoder por años y sigue siendo la opción preferida para el código del lado del servidor. Ventajas clave frente a btoa(): soporte nativo de UTF-8, manejo de datos binarios y el atajo de codificación 'base64url' disponible desde Node.js 18.
Codificación y decodificación básica de texto
// Encoding a server configuration object for storage in an env variable
const dbConfig = JSON.stringify({
host: 'db-primary.internal',
port: 5432,
database: 'analytics_prod',
maxConnections: 100,
ssl: { rejectUnauthorized: true },
})
const encoded = Buffer.from(dbConfig, 'utf8').toString('base64')
console.log(encoded)
// eyJob3N0IjoiZGItcHJpbWFyeS5pbnRlcm5hbCIsInBvcnQiOjU0MzIsImRhdGFiYXNlIjoiYW5h...
// Decoding back
const decoded = Buffer.from(encoded, 'base64').toString('utf8')
const config = JSON.parse(decoded)
console.log(config.host) // db-primary.internal
console.log(config.maxConnections) // 100Codificación de archivos binarios desde disco
import { readFileSync, writeFileSync } from 'node:fs'
import { join } from 'node:path'
// Read a TLS certificate and encode it for embedding in a config file
const certPem = readFileSync(join(process.cwd(), 'ssl', 'server.crt'))
const certBase64 = certPem.toString('base64')
// Store as a single-line string — suitable for env vars or JSON configs
writeFileSync('./dist/cert.b64', certBase64, 'utf8')
console.log(`Certificate encoded: ${certBase64.length} characters`)
// Certificate encoded: 2856 characters
// Restore the binary cert from the encoded value
const restored = Buffer.from(certBase64, 'base64')
console.log(restored.equals(certPem)) // trueCodificación asíncrona de archivos con manejo de errores
import { readFile } from 'node:fs/promises'
async function encodeFileToBase64(filePath: string): Promise<string> {
try {
const buffer = await readFile(filePath)
return buffer.toString('base64')
} catch (err) {
const code = (err as NodeJS.ErrnoException).code
if (code === 'ENOENT') throw new Error(`File not found: ${filePath}`)
if (code === 'EACCES') throw new Error(`Permission denied: ${filePath}`)
throw err
}
}
// Encode a PDF for an email attachment payload
const reportBase64 = await encodeFileToBase64('./reports/q1-financials.pdf')
const emailPayload = {
to: 'finance-team@company.internal',
subject: 'Q1 Financial Report',
attachments: [{
filename: 'q1-financials.pdf',
content: reportBase64,
encoding: 'base64',
contentType: 'application/pdf',
}],
}
console.log(`Attachment: ${reportBase64.length} chars`)Funciones Base64 de JavaScript — Referencia de Parámetros
A diferencia del módulo base64 de Python, JavaScript no tiene una única función Base64 unificada. La API depende del entorno de destino. Aquí está la referencia completa para todos los enfoques nativos:
| Función | Tipo de entrada | Unicode | URL-safe | Disponible en |
|---|---|---|---|---|
| btoa(string) | string (Latin-1) | ❌ lanza por encima de U+00FF | ❌ reemplazo manual | Browser, Node 16+, Bun, Deno |
| atob(string) | Base64 string | ❌ devuelve cadena binaria | ❌ reemplazo manual | Browser, Node 16+, Bun, Deno |
| Buffer.from(src, enc) .toString(enc) | string | Buffer | Uint8Array | ✅ codificación utf8 | ✅ base64url en Node 18+ | Node.js, Bun |
| TextEncoder().encode(str) + btoa() | string (cualquier Unicode) | ✅ vía bytes UTF-8 | ❌ reemplazo manual | Browser, Node 16+, Deno |
| Uint8Array.toBase64() (TC39) | Uint8Array | ✅ binario | ✅ omitPadding + alphabet | Chrome 130+, Node 22+ |
La firma Buffer.from(src, enc).toString(enc) acepta varios valores de codificación relevantes para Base64:
Base64 URL-safe — Codificación para JWTs, URLs y Nombres de Archivo
El Base64 estándar usa + y /, que están reservados en URLs — + se decodifica como espacio en cadenas de consulta, y / es un separador de rutas. Los JWTs, parámetros de URL, nombres de archivo y valores de cookies requieren la variante URL-safe: + → -, / → _, = final eliminado.
Navegador — reemplazo manual de caracteres
function toBase64Url(text: string): string {
// For ASCII-safe input (e.g., JSON with only ASCII chars)
return btoa(text)
.replace(/+/g, '-')
.replace(///g, '_')
.replace(/=/g, '')
}
function fromBase64Url(encoded: string): string {
// Restore standard Base64 characters and padding before decoding
const base64 = encoded.replace(/-/g, '+').replace(/_/g, '/')
const padded = base64 + '==='.slice(0, (4 - base64.length % 4) % 4)
return atob(padded)
}
// JWT header — must be URL-safe Base64
const header = JSON.stringify({ alg: 'HS256', typ: 'JWT' })
const encoded = toBase64Url(header)
console.log(encoded) // eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
const decoded = fromBase64Url(encoded)
console.log(decoded) // {"alg":"HS256","typ":"JWT"}Node.js 18+ — codificación nativa 'base64url'
// Node.js 18 added 'base64url' as a first-class Buffer encoding
const sessionPayload = JSON.stringify({
userId: 'usr_9f2a1c3e8b4d',
role: 'editor',
workspaceId:'ws_3a7f91c2',
exp: Math.floor(Date.now() / 1000) + 3600,
})
const encoded = Buffer.from(sessionPayload, 'utf8').toString('base64url')
// No + or / or = characters in the output
// eyJ1c2VySWQiOiJ1c3JfOWYyYTFjM2U4YjRkIiwicm9sZSI6ImVkaXRvciIsIndvcmtzcGFjZUlkIjoid3NfM2E3ZjkxYzIiLCJleHAiOjE3MTcyMDM2MDB9
const decoded = Buffer.from(encoded, 'base64url').toString('utf8')
console.log(JSON.parse(decoded).role) // editorCodificación de Archivos y Respuestas de API en JavaScript
En el código de producción, la codificación Base64 se aplica con mayor frecuencia a archivos que se transmiten y a respuestas de APIs externas que entregan contenido binario. Los patrones difieren entre el navegador y Node.js, y los datos binarios requieren un cuidado especial.
Navegador — codificar un archivo desde un elemento input
// Modern approach: File.arrayBuffer() (Chrome 76+, Firefox 69+, Safari 14+)
async function encodeFile(file: File): Promise<string> {
const buffer = await file.arrayBuffer()
const bytes = new Uint8Array(buffer)
const chars = Array.from(bytes, b => String.fromCharCode(b))
return btoa(chars.join(''))
}
const uploadInput = document.getElementById('avatar') as HTMLInputElement
uploadInput.addEventListener('change', async (e) => {
const file = (e.target as HTMLInputElement).files?.[0]
if (!file) return
try {
const encoded = await encodeFile(file)
const dataUri = `data:${file.type};base64,${encoded}`
// Preview the image inline
const img = document.getElementById('preview') as HTMLImageElement
img.src = dataUri
img.hidden = false
console.log(`Encoded ${file.name} (${file.size} bytes) → ${encoded.length} Base64 chars`)
} catch (err) {
console.error('Encoding failed:', err)
}
})Obtención de datos binarios codificados en Base64 desde una API
// GitHub Contents API returns file content as Base64 with embedded newlines
async function fetchRepoFile(
owner: string,
repo: string,
path: string,
token: string,
): Promise<string> {
const res = await fetch(
`https://api.github.com/repos/${owner}/${repo}/contents/${path}`,
{
headers: {
Authorization: `Bearer ${token}`,
Accept: 'application/vnd.github.v3+json',
},
}
)
if (!res.ok) throw new Error(`GitHub API ${res.status}: ${res.statusText}`)
const data = await res.json() as { content: string; encoding: string; size: number }
if (data.encoding !== 'base64') {
throw new Error(`Unexpected encoding from GitHub: ${data.encoding}`)
}
// GitHub wraps output at 60 chars — strip newlines before decoding
const clean = data.content.replace(/\n/g, '')
return atob(clean)
}
const openApiSpec = await fetchRepoFile(
'acme-corp', 'platform-api', 'openapi.json', process.env.GITHUB_TOKEN!
)
const spec = JSON.parse(openApiSpec)
console.log(`API version: ${spec.info.version}`)Cuando solo necesitas inspeccionar una respuesta codificada durante la depuración de APIs sin configurar un script, pega el valor Base64 directamente en el Codificador Base64 — también decodifica, con salida inmediata. Útil para inspeccionar respuestas de la API de GitHub, payloads JWT y firmas de webhooks.
Codificación Base64 en Línea de Comandos con Node.js y Shell
Para scripts de CI/CD, targets de Makefile o depuración puntual, rara vez necesitas un script completo. Tanto las herramientas del sistema como los one-liners de Node.js cubren la mayoría de los casos multiplataforma.
# ── macOS / Linux system base64 ───────────────────────────────────────
# Standard encoding
echo -n "deploy-bot:sk-prod-a7f2c91e4b3d8" | base64
# ZGVwbG95LWJvdDpzay1wcm9kLWE3ZjJjOTFlNGIzZDg=
# URL-safe variant (replace chars and strip padding)
echo -n "deploy-bot:sk-prod-a7f2c91e4b3d8" | base64 | tr '+/' '-_' | tr -d '='
# Encode a file inline (macOS: -b 0 removes line wrapping; Linux: --wrap=0)
base64 -b 0 ./config/production.json
# or on Linux:
base64 --wrap=0 ./config/production.json
# Decode
echo "ZGVwbG95LWJvdDpzay1wcm9kLWE3ZjJjOTFlNGIzZDg=" | base64 --decode
# ── Node.js one-liner — works on Windows too ───────────────────────────
node -e "process.stdout.write(Buffer.from(process.argv[1]).toString('base64'))" "my:secret"
# bXk6c2VjcmV0
# URL-safe from Node.js 18+
node -e "process.stdout.write(Buffer.from(process.argv[1]).toString('base64url'))" "my:secret"
# bXk6c2VjcmV0 (same here since there are no special chars)
# Decode in Node.js
node -e "console.log(Buffer.from(process.argv[1], 'base64').toString())" "ZGVwbG95LWJvdA=="base64 envuelve la salida en 76 caracteres por defecto. Esto rompe el análisis posterior. Siempre añade -b 0 (macOS) o --wrap=0 (Linux) cuando necesites un resultado en una sola línea — por ejemplo, al escribir en una variable de entorno o en un campo de configuración.Alternativa de Alto Rendimiento: js-base64
Las APIs integradas son suficientes para la mayoría de los casos de uso. La razón principal para recurrir a una librería es la consistencia entre entornos: si publicas un paquete que se ejecuta tanto en el navegador como en Node.js, usar Buffer requiere detección de entorno o configuración del bundler, mientras que btoa() requiere el truco de Unicode. js-base64 (más de 100M de descargas semanales en npm) maneja ambos de forma transparente.
npm install js-base64 # or pnpm add js-base64
import { toBase64, fromBase64, toBase64Url, fromBase64Url, isValid } from 'js-base64'
// Standard encoding — Unicode-safe, works in browser and Node.js
const telemetryEvent = JSON.stringify({
eventId: 'evt_7c3a9f1b2d',
type: 'checkout_completed',
currency: 'EUR',
amount: 14900,
userId: 'usr_4e2b8d6a5c',
timestamp: 1717200000,
})
const encoded = toBase64(telemetryEvent)
const urlEncoded = toBase64Url(telemetryEvent) // No +, /, or = characters
const decoded = fromBase64(encoded)
console.log(JSON.parse(decoded).type) // checkout_completed
// Binary data — pass a Uint8Array as second argument
const pngMagicBytes = new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])
const binaryEncoded = toBase64(pngMagicBytes, true) // true = binary mode
// Validation before decoding
const suspicious = 'not!valid@base64#'
console.log(isValid(suspicious)) // falseInternamente, js-base64 usa Buffer nativo cuando está disponible y recurre a una implementación en JS puro en el navegador. Es 2–3× más rápido que el enfoque TextEncoder+btoa para cadenas Unicode largas, y la API simétrica (toBase64 / fromBase64) elimina la carga mental de recordar en qué dirección van btoa y atob.
Codificación de Archivos Binarios Grandes con Streams de Node.js
Cuando necesitas codificar archivos de más de ~50 MB, cargar el archivo completo en memoria con readFileSync() se convierte en un problema. Los streams de Node.js te permiten procesar los datos en fragmentos — pero la codificación Base64 tiene una restricción: debes alimentar el codificador en múltiplos de 3 bytes para evitar un relleno incorrecto en los límites de los fragmentos.
import { createReadStream, createWriteStream } from 'node:fs'
import { pipeline } from 'node:stream/promises'
// Stream a large binary file to a Base64-encoded output file
async function streamEncodeToBase64(
inputPath: string,
outputPath: string,
): Promise<void> {
const readStream = createReadStream(inputPath, { highWaterMark: 3 * 1024 * 256 }) // 768 KB chunks (multiple of 3)
const writeStream = createWriteStream(outputPath, { encoding: 'utf8' })
let buffer = Buffer.alloc(0)
await pipeline(
readStream,
async function* (source) {
for await (const chunk of source) {
buffer = Buffer.concat([buffer, chunk as Buffer])
// Encode in complete 3-byte groups to avoid mid-stream padding
const remainder = buffer.length % 3
const safe = buffer.subarray(0, buffer.length - remainder)
buffer = buffer.subarray(buffer.length - remainder)
if (safe.length > 0) yield safe.toString('base64')
}
// Flush remaining bytes (may add 1 or 2 '=' padding chars)
if (buffer.length > 0) yield buffer.toString('base64')
},
writeStream,
)
}
// Usage: encode a 200 MB video attachment
await streamEncodeToBase64(
'./uploads/product-demo.mp4',
'./dist/product-demo.b64',
)
console.log('Stream encoding complete')= en el medio de la salida. El ejemplo usa 3 * 1024 * 256 = 786.432 bytes (768 KB) — ajusta highWaterMark según tu presupuesto de memoria. Para archivos de menos de 50 MB, readFile() + Buffer.toString('base64') es más simple y suficientemente rápido.Errores Comunes
He revisado muchas bases de código JavaScript con codificación Base64, y estos cuatro errores aparecen de forma consistente — a menudo sin descubrirse hasta que un carácter no-ASCII o un archivo binario alcanza la ruta de codificación en producción.
Error 1 — Pasar Unicode directamente a btoa()
Problema: btoa() solo acepta caracteres con puntos de código 0–255. Caracteres como ñ, emojis o ideogramas CJK causan una DOMException inmediata. Solución: codifica primero con TextEncoder, o usa Buffer.from(text, 'utf8').toString('base64') en Node.js.
// ❌ DOMException: The string to be encoded contains // characters outside of the Latin1 range const username = 'Ana Torres' const encoded = btoa(username) // throws
// ✅ Encode as UTF-8 bytes first
function safeEncode(text: string): string {
const bytes = new TextEncoder().encode(text)
const chars = Array.from(bytes, b => String.fromCharCode(b))
return btoa(chars.join(''))
}
const encoded = safeEncode('Ana Torres')
// QW5hIFRvcnJlcw==Error 2 — Olvidar restaurar el relleno antes de atob()
Problema: El Base64 URL-safe elimina el relleno =. Pasar la cadena sin relleno directamente a atob() produce una salida incorrecta o lanza una excepción según la longitud de la cadena. Solución: restaura + y / y vuelve a añadir la cantidad correcta de relleno antes de llamar a atob().
// ❌ atob() may return wrong data or throw // on URL-safe Base64 without padding const jwtSegment = 'eyJ1c2VySWQiOiJ1c3JfOWYyYTFjM2UifQ' const decoded = atob(jwtSegment) // Unreliable
// ✅ Restore characters and padding first
function decodeBase64Url(input: string): string {
const b64 = input.replace(/-/g, '+').replace(/_/g, '/')
const pad = b64 + '==='.slice(0, (4 - b64.length % 4) % 4)
return atob(pad)
}
const decoded = decodeBase64Url('eyJ1c2VySWQiOiJ1c3JfOWYyYTFjM2UifQ')
// {"userId":"usr_9f2a1c3e"}Error 3 — Concatenar fragmentos codificados en lugar de buffers crudos
Problema: Cada llamada a btoa() o .toString('base64') añade su propio relleno. Concatenar dos cadenas Base64 con relleno produce una salida inválida porque el relleno solo debe estar al final. Solución: concatena los datos crudos antes de codificar.
// ❌ Both parts are padded independently —
// the combined string is not valid Base64
const part1 = Buffer.from('webhook-secret').toString('base64')
// d2ViaG9vay1zZWNyZXQ= ← has padding
const part2 = Buffer.from('-v2').toString('base64')
// LXYy ← correct in isolation
const combined = part1 + part2 // ❌ Invalid — padding in the middle// ✅ Concatenate raw Buffers before encoding
const combined = Buffer.concat([
Buffer.from('webhook-secret'),
Buffer.from('-v2'),
]).toString('base64')
// d2ViaG9vay1zZWNyZXQtdjI= — single valid Base64 stringError 4 — Usar response.text() para leer datos binarios de API antes de codificar
Problema: response.text() interpreta los bytes crudos como UTF-8 y reemplaza las secuencias de bytes no reconocidas con el carácter de reemplazo U+FFFD. Cualquier contenido binario — imágenes, PDFs, audio — se corrompe silenciosamente antes de llegar a btoa(). Solución: usa response.arrayBuffer() para obtener los bytes crudos.
// ❌ response.text() corrupts binary data
const res = await fetch('/api/exports/invoice.pdf')
const text = await res.text() // ❌ PDF bytes mangled as UTF-8
const encoded = btoa(text) // ❌ Corrupted Base64// ✅ arrayBuffer() preserves raw bytes
const res = await fetch('/api/exports/invoice.pdf')
const buffer = await res.arrayBuffer()
const bytes = new Uint8Array(buffer)
const chars = Array.from(bytes, b => String.fromCharCode(b))
const encoded = btoa(chars.join('')) // ✅ Valid Base64Métodos Base64 de JavaScript — Comparación Rápida
| Método | Unicode | Datos binarios | URL-safe | Entornos | Requiere instalación |
|---|---|---|---|---|---|
| btoa() / atob() | ❌ Latin-1 | ❌ workaround necesario | ❌ reemplazo manual | Browser, Node 16+, Bun, Deno | No |
| TextEncoder + btoa() | ✅ UTF-8 | ✅ vía Uint8Array | ❌ reemplazo manual | Browser, Node 16+, Deno | No |
| Buffer.from().toString() | ✅ utf8 | ✅ nativo | ✅ base64url (Node 18+) | Node.js, Bun | No |
| Uint8Array.toBase64() (TC39) | ✅ binario | ✅ nativo | ✅ opción alphabet | Chrome 130+, Node 22+ | No |
| js-base64 | ✅ siempre | ✅ Uint8Array | ✅ integrado | Universal | npm install |
Elige btoa() solo cuando la entrada es comprobadamente solo ASCII — resúmenes hexadecimales, IDs numéricos o cadenas Latin-1 prevalidadas. Para texto proporcionado por el usuario en un navegador, usa TextEncoder + btoa(). Para todo el código del lado del servidor en Node.js, Buffer es el predeterminado correcto. Para librerías que necesitan ejecutarse en ambos entornos sin configuración del bundler, js-base64 elimina todos los casos límite.
Preguntas Frecuentes
Herramientas Relacionadas
Para codificar o decodificar con un clic sin escribir ningún código, pega tu cadena o binario directamente en el Codificador Base64 — maneja los modos estándar y URL-safe al instante en tu navegador.
Alex is a front-end and Node.js developer with extensive experience building web applications and developer tooling. He is passionate about web standards, browser APIs, and the JavaScript ecosystem. In his spare time he contributes to open-source projects and writes about modern JavaScript patterns, performance optimisation, and everything related to the web platform.
Sophie is a full-stack developer focused on TypeScript across the entire stack — from React frontends to Express and Fastify backends. She has a particular interest in type-safe API design, runtime validation, and the patterns that make large JavaScript codebases stay manageable. She writes about TypeScript idioms, Node.js internals, and the ever-evolving JavaScript module ecosystem.