How to Convert String to Hex in JavaScript
Convert a string to hex in JavaScript with TextEncoder in the browser or Buffer in Node.js, plus the reverse conversion and non-ASCII handling.
Hexadecimal (hex) is base-16: digits 0–9 plus letters A–F. Every byte of data becomes exactly two hex digits. JavaScript has no single built-in toHex() for strings, but the standard approach uses TextEncoder in the browser, and Node.js offers a one-line shortcut with Buffer.
Browser Method: TextEncoder
TextEncoder converts a string to its UTF-8 bytes. Map each byte to a two-digit hex value:
function stringToHex(str) {
const bytes = new TextEncoder().encode(str);
return [...bytes].map(b => b.toString(16).padStart(2, "0")).join("");
}
console.log(stringToHex("Hello"));
Output:
48656c6c6f
That is H = 48, e = 65, l = 6c, l = 6c, o = 6f. The padStart(2, "0") matters: without it, a byte like 5 would print as 5 instead of 05, breaking the two-digits-per-byte rule. toString(16) produces lowercase letters; add .toUpperCase() for uppercase hex.
Node.js Shortcut: Buffer
In Node.js, Buffer does the whole job in one line:
console.log(Buffer.from("Hello", "utf8").toString("hex"));
Output:
48656c6c6f
This works only in Node.js (or bundlers that polyfill Buffer) — it is not available in plain browser JavaScript, where TextEncoder is the correct tool.
Converting Back: Hex to String
Node.js:
console.log(Buffer.from("48656c6c6f", "hex").toString("utf8"));
Output:
Hello
Browser (TextDecoder):
function hexToString(hex) {
const bytes = new Uint8Array(hex.match(/../g).map(h => parseInt(h, 16)));
return new TextDecoder().decode(bytes);
}
console.log(hexToString("48656c6c6f"));
Output:
Hello
Handling Non-ASCII Text
Both methods encode as UTF-8, so accented characters become multiple bytes:
console.log(stringToHex("café"));
Output:
636166c3a9
Here c = 63, a = 61, f = 66, and é becomes the two bytes c3 a9. The reverse works the same way:
console.log(hexToString("636166c3a9"));
Output:
café
FAQ
What is the easiest way to convert a string to hex in JavaScript?
In the browser: TextEncoder plus a byte-to-hex map. In Node.js: Buffer.from(str, "utf8").toString("hex").
Why do I need padStart(2, "0")?
Because every byte must be exactly two hex digits. A byte with value 5 must print as 05, not 5, or the hex string cannot be decoded back correctly.
How do I get uppercase hex?
Call .toUpperCase() on the result: 48656c6c6f becomes 48656C6C6F. The value is identical.
Why does café produce 10 hex digits for 4 characters?
Because é is two UTF-8 bytes (c3 a9). Four characters, five bytes, two hex digits per byte: ten digits.
Does Buffer work in the browser?
No — Buffer is a Node.js API. In browser code, use TextEncoder and TextDecoder.