function buf2hex(buffer) { // buffer is an ArrayBuffer
  return [...new Uint8Array(buffer)]
      .map(x => x.toString(16).padStart(2, '0'))
      .join('');
}

// EXAMPLE:
const buffer = new Uint8Array([ 4, 8, 12, 16 ]).buffer;
console.log(buf2hex(buffer)); // = 04080c10
Run code snippetEdit code snippet Hide Results Copy to answer Expand

This function works in four steps:

  1. Converts the buffer into an array.
  2. For each x the array, it converts that element to a hex string (e.g., 12 becomes c).
  3. Then it takes that hex string and left pads it with zeros (e.g., c becomes 0c).
  4. Finally, it takes all of the hex values and joins them into a single string.

Below is another longer implementation that is a little easier to understand, but essentially does the same thing:

Show code snippet

function buf2hex(buffer) { // buffer is an ArrayBuffer
  // create a byte array (Uint8Array) that we can use to read the array buffer
  const byteArray = new Uint8Array(buffer);
  
  // for each element, we want to get its two-digit hexadecimal representation
  const hexParts = [];
  for(let i = 0; i < byteArray.length; i++) {
    // convert value to hexadecimal
    const hex = byteArray[i].toString(16);
    
    // pad with zeros to length 2
    const paddedHex = ('00' + hex).slice(-2);
    
    // push to array
    hexParts.push(paddedHex);
  }
  
  // join all the hex values of the elements into a single string
  return hexParts.join('');
}

// EXAMPLE:
const buffer = new Uint8Array([ 4, 8, 12, 16 ]).buffer;
console.log(buf2hex(buffer)); // = 04080c10
Run code snippetEdit code snippet Hide Results Copy to answer Expand

Answer from Freyja on Stack Overflow
Top answer
1 of 14
143

function buf2hex(buffer) { // buffer is an ArrayBuffer
  return [...new Uint8Array(buffer)]
      .map(x => x.toString(16).padStart(2, '0'))
      .join('');
}

// EXAMPLE:
const buffer = new Uint8Array([ 4, 8, 12, 16 ]).buffer;
console.log(buf2hex(buffer)); // = 04080c10
Run code snippetEdit code snippet Hide Results Copy to answer Expand

This function works in four steps:

  1. Converts the buffer into an array.
  2. For each x the array, it converts that element to a hex string (e.g., 12 becomes c).
  3. Then it takes that hex string and left pads it with zeros (e.g., c becomes 0c).
  4. Finally, it takes all of the hex values and joins them into a single string.

Below is another longer implementation that is a little easier to understand, but essentially does the same thing:

Show code snippet

function buf2hex(buffer) { // buffer is an ArrayBuffer
  // create a byte array (Uint8Array) that we can use to read the array buffer
  const byteArray = new Uint8Array(buffer);
  
  // for each element, we want to get its two-digit hexadecimal representation
  const hexParts = [];
  for(let i = 0; i < byteArray.length; i++) {
    // convert value to hexadecimal
    const hex = byteArray[i].toString(16);
    
    // pad with zeros to length 2
    const paddedHex = ('00' + hex).slice(-2);
    
    // push to array
    hexParts.push(paddedHex);
  }
  
  // join all the hex values of the elements into a single string
  return hexParts.join('');
}

// EXAMPLE:
const buffer = new Uint8Array([ 4, 8, 12, 16 ]).buffer;
console.log(buf2hex(buffer)); // = 04080c10
Run code snippetEdit code snippet Hide Results Copy to answer Expand

2 of 14
49

Here are several methods for encoding an ArrayBuffer to hex, in order of speed. All methods were tested in Firefox initially, but afterwards I went and tested in Chrome (V8). In Chrome the methods were mostly in the same order but it did have slight differenences--the important thing is that #1 is the fastest method in all environments by a huge margin.

If you want to see how slow the currently selected answer is, you can go ahead and scroll to the bottom of this list.

TL;DR

Method #1 (just below this) is the fastest method I tested for encoding to a hex string. If, for some very good reason, you need to support IE, you may need to replace the .padStart call with the .slice trick used in method #6 when precomputing the hex octets to make sure every octet is 2 characters.

1. Precomputed Hex Octets w/ for Loop (Fastest/Baseline)

This approach computes the 2-character hex octets for every possible value of an unsigned byte: [0, 255], and then just maps each value in the ArrayBuffer through the array of octet strings. Credit to Aaron Watters for the original answer using this method.

NOTE: as mentioned by Cref, you may get a performance boost in V8 (Chromium/Chrome/Edge/Brave/etc.) by using the loop to just concatenate hex octets into one big string as you go and then returning the string after the loop. V8 seems to optimize string concatenation very well while Firefox performed better with building up an array and then .joining it into a string at the end as I did in the code below. That would probably be a micro-optimization subject to change with the whims of optimizing JS compilers though..

const byteToHex = [];

for (let n = 0; n <= 0xff; ++n)
{
    const hexOctet = n.toString(16).padStart(2, "0");
    byteToHex.push(hexOctet);
}

function hex(arrayBuffer)
{
    const buff = new Uint8Array(arrayBuffer);
    const hexOctets = []; // new Array(buff.length) is even faster (preallocates necessary array size), then use hexOctets[i] instead of .push()

    for (let i = 0; i < buff.length; ++i)
        hexOctets.push(byteToHex[buff[i]]);

    return hexOctets.join("");
}

2. Precomputed Hex Octets w/ Array.map (~30% slower)

Same as the above method, where we precompute an array in which the value for each index is the hex string for the index's value, but we use a hack where we call the Array prototype's map() method with the buffer. This is a more functional approach, but if you really want speed you will always use for loops rather than ES6 array methods, as all modern JS engines optimize them much better.

IMPORTANT: You cannot use new Uint8Array(arrayBuffer).map(...). Although Uint8Array implements the ArrayLike interface, its map method will return another Uint8Array which cannot contain strings (hex octets in our case), hence the Array prototype hack.

function hex(arrayBuffer)
{
    return Array.prototype.map.call(
        new Uint8Array(arrayBuffer),
        n => byteToHex[n]
    ).join("");
}

3. Precomputed ASCII Character Codes (~230% slower)

Well this was a disappointing experiment. I wrote up this function because I thought it would be even faster than Aaron's precomputed hex octets--boy was I wrong LOL. While Aaron maps entire bytes to their corresponding 2-character hex codes, this solution uses bitshifting to get the hex character for the first 4 bits in each byte and then the one for the last 4 and uses String.fromCharCode(). Honestly I think String.fromCharCode() must just be poorly optimized, since it is not used by very many people and is low on browser vendors' lists of priorities.

const asciiCodes = new Uint8Array(
    Array.prototype.map.call(
        "0123456789abcdef",
        char => char.charCodeAt()
    )
);

function hex(arrayBuffer)
{
    const buff = new Uint8Array(arrayBuffer);
    const charCodes = new Uint8Array(buff.length * 2);

    for (let i = 0; i < buff.length; ++i)
    {
        charCodes[i * 2] = asciiCodes[buff[i] >>> 4];
        charCodes[i * 2 + 1] = asciiCodes[buff[i] & 0xf];
    }

    return String.fromCharCode(...charCodes);
}

4. Array.prototype.map() w/ padStart() (~290% slower)

This method maps an array of bytes using the Number.toString() method to get the hex and then padding the octet with a "0" if necessary via the String.padStart() method.

IMPORTANT: String.padStart() is a relative new standard, so you should not use this or method #5 if you are planning on supporting browsers older than 2017 or so or Internet Explorer. TBH if your users are still using IE you should probably just go to their houses at this point and install Chrome/Firefox. Do us all a favor. :^D

function hex(arrayBuffer)
{
    return Array.prototype.map.call(
        new Uint8Array(arrayBuffer),
        n => n.toString(16).padStart(2, "0")
    ).join("");
}

5. Array.from().map() w/ padStart() (~370% slower)

This is the same as #4 but instead of the Array prototype hack, we create an actual number array from the Uint8Array and call map() on that directly. We pay in speed though.

function hex(arrayBuffer)
{
    return Array.from(new Uint8Array(arrayBuffer))
        .map(n => n.toString(16).padStart(2, "0"))
        .join("");
}

6. Array.prototype.map() w/ slice() (~450% slower)

This is the selected answer, do not use this unless you are a typical web developer and performance makes you uneasy (answer #1 is supported by just as many browsers).

function hex(arrayBuffer)
{
    return Array.prototype.map.call(
        new Uint8Array(arrayBuffer),
        n => ("0" + n.toString(16)).slice(-2)
    ).join("");
}

Lesson #1

Precomputing stuff can be a very effective memory-for-speed tradeoff sometimes. In theory, the array of precomputed hex octets can be stored in just 1024 bytes (256 possible hex values ⨉ 2 characters/value ⨉ 2 bytes/character for a UTF-16 string representation used by most/all browsers), which is nothing in a modern computer. Realistically there are some more bytes in there used for storing the array and string lengths and maybe type information since this is JavaScript, but the memory usage is still negligible for a massive performance improvement.

Lesson #2

Help out the optimizing compiler. The browser's JavaScript compiler regularly attempts to understand your code and break it down to the fastest possible machine code for your CPU to execute. Because JavaScript is a very dynamic language, this can be hard to do and sometimes the browser just gives up and leaves all sorts of type checks and worse under-the-hood because it can't be sure that x will indeed be a string or number, and vice versa. Using modern functional programming additions like the .map method of the built-in Array class can cause headaches for the browser because callback functions can capture outside variables and do all sorts of other things that often hurt performance. For-loops are well-studied and relatively simple constructs, so the browser developers have incorporated all sorts of tricks for the compiler to optimize your JavaScript for-loops. Keep it simple.

🌐
GitHub
github.com › LinusU › array-buffer-to-hex
GitHub - LinusU/array-buffer-to-hex: Turn an `ArrayBuffer` into a string of hexadecimal characters · GitHub
const arrayBufferToHex = require('array-buffer-to-hex') const randomData = crypto.getRandomValues(new Uint8Array(16)).buffer const string = arrayBufferToHex(randomData) console.log(string) //=> "a2c57b9bc22056336ce5a3ec917819e0"
Author: LinusU
🌐
Medium
medium.com › deno-the-complete-reference › deno-nuggets-buffer-to-hex-one-liner-701e4ce074a2
Deno nuggets: Buffer to hex one-liner | Tech Tonic
April 6, 2023 - Just to make it a complete solution, we’ll use a string that’ll be converted to buffer before it gets converted to hex string. Here is the complete code: const buf = new TextEncoder().encode("Hello from JS ArrayBuffer!"); const hex = Array.from(buf).map((b) => b.toString(16).padStart(2, "0")).join(""); console.log("// -- BUFFER:\n\n", buf, "\n\n// -- HEX:\n\n", hex);
🌐
npm
npmjs.com › package › array-buffer-to-hex
array-buffer-to-hex - npm
October 19, 2017 - Latest version: 1.0.0, last published: 9 years ago. Start using array-buffer-to-hex in your project by running `npm i array-buffer-to-hex`. There are 40 other projects in the npm registry using array-buffer-to-hex.
      » npm install array-buffer-to-hex
    
Published: Oct 19, 2017
Version: 1.0.0
🌐
GitHub
github.com › miguelmota › arraybuffer-to-hex
GitHub - miguelmota/arraybuffer-to-hex · GitHub
const arrayBufferToHex = require('arraybuffer-to-hex') const buffer = new Uint8Array([4, 8, 12, 16]) console.log(arrayBufferToHex(buffer)) // "04080c10" MIT
Author: miguelmota
🌐
Yarn
yarnpkg.com › package
array-buffer-to-hex | Yarn
const arrayBufferToHex = require('array-buffer-to-hex') const randomData = crypto.getRandomValues(new Uint8Array(16)).buffer const string = arrayBufferToHex(randomData) console.log(string) //=> "a2c57b9bc22056336ce5a3ec917819e0"
🌐
MeasureThat
measurethat.net › Benchmarks › Show › 29182 › 0 › array-buffer-to-hex-conversion
Benchmark: array buffer to hex conversion - MeasureThat.net
parse hex-string to 'bytes like object' (Uint8Array) in javascript · hex to array buffer · array buffer to hex conversion 2 · sha1-js-rusha-vs-native-10mb · Comments · Do you really want to delete benchmark?
🌐
YouTube
youtube.com › watch
Converting a Large ArrayBuffer to Hexadecimal String in JavaScript - YouTube
Discover an efficient method to convert a large `ArrayBuffer` into a hex-string representation in JavaScript, and learn how to reverse the process effectivel...
Published: August 5, 2025
Views: 0
🌐
Tabnine
tabnine.com › home › code library
Code Library - Tabnine
July 25, 2024 - Get the answers and suggestions you need from our AI code assistant. Get started in minutes with a free 90 day trial of Tabnine Pro.
Find elsewhere
🌐
BLINGDOT
blingdot.com › home › javascript arraybuffer to hex
Javascript Arraybuffer To Hex - BLINGDOT
August 24, 2021 - If, for a few excellent reason, ... Loop (Fastest/Baseline) This method computes the two-person hex octets for each feasible value of an unsigned byte: [0, 255], and HEX then just maps each value inside the ArrayBuffer via the array of octet strings....
🌐
Stack Overflow
stackoverflow.com › questions › 76647647 › convert-a-large-arraybuffer-into-hexadecimal-string-representation-in-javascript
Convert a large ArrayBuffer into hexadecimal string representation in JavaScript - Stack Overflow
Related: JavaScript does not need a StringBuilder, Does JavaScript have a built-in stringbuilder class?, and How can I build/concatenate strings in JavaScript? ... @PeterMortensen The answer to that question is probably. However to make a robust interface that does not expose problems with variable byte length may be difficult. But, having an efficient StringBuilder causes people to think about time complexity, which by itself is good for developing programming skills. ... function to_hex_string(bytes) { let tmp = new Uint8Array(2*bytes.length); for(let k = 0; k != bytes.length; ++k) { let value = bytes[k]; let msb = value >> 4; let lsb = value & 0xf; tmp[2*k] = msb < 10 ?
🌐
jsDelivr
jsdelivr.com › package › npm › array-buffer-to-hex
array-buffer-to-hex CDN by jsDelivr - A CDN for npm and GitHub
October 19, 2017 - A free, fast, and reliable CDN for array-buffer-to-hex. Turn an `ArrayBuffer` into a string of hexadecimal characters.
Published: Oct 19, 2017
🌐
Italypaleale
italypaleale.github.io › arraybuffer
arraybuffer-encoding-encode - v1.1.0
Encode and decode ArrayBuffer objects (and typed arrays like Uint8Array, and strings) to base64 and hex, for the browser and Node.js
🌐
Xaymar
xaymar.com › articles › 2020 › 12 › 08 › fastest-uint8array-to-hex-string-conversion-in-javascript
Convert Uint8Array to Hex quickly in JS | Xaymar - Pushing 1 Pixel at a time
December 8, 2020 - // Pre-Init const LUT_HEX_4b = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']; const LUT_HEX_8b = new Array(0x100); for (let n = 0; n < 0x100; n++) { LUT_HEX_8b[n] = `${LUT_HEX_4b[(n >>> 4) & 0xF]}${LUT_HEX_4b[n & 0xF]}`; } // End Pre-Init function toHex(buffer) { const out = new Array(); for (let idx = 0; idx < buffer.length; idx++) { out.push(LUT_HEX_8b[buffer[idx]]); } return out.join(''); } Breaking out from the same idea is #5, which builds an array manually instead of letting the JavaScript runtime handle it for us.
🌐
npm
npmjs.com › package › @obsessiveo › arraybuffer-to-hex
@obsessiveo/arraybuffer-to-hex - npm
September 6, 2022 - import { arrayBufferToHex } from '@obsessiveo/arraybuffer-to-hex'; const view = new Uint8Array([10, 255, 171]); const result = arrayBufferToHex(view.buffer); console.log(result); // 0affab
      » npm install @obsessiveo/arraybuffer-to-hex
    
Published: Sep 06, 2022
Version: 1.0.1
Author: Obsessiveo
🌐
GitHub
gist.github.com › hatappo › 6e9412b82a597b4d2bc17508fe9dc849
String の SHA-1 ハッシュ値を計算し、その ArrayBuffer を16進数(HEX)に変換する。
Javascript ArrayBuffer to Hex - Stack Overflow https://stackoverflow.com/questions/40031688/javascript-arraybuffer-to-hex/40031979#40031979 · Node.js だと Buffer オブジェクトがあるからもっと楽みたい。 https://qiita.com/masakielastic/items/8eb4bf4efc2310ee7baf#文字列と-bufferuint8array-の相互変換 ·
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Global_Objects › Uint8Array › toHex
Uint8Array.prototype.toHex() - JavaScript - MDN Web Docs
This example encodes data from a Uint8Array into a hex string. ... const uint8Array = new Uint8Array([202, 254, 208, 13]); console.log(uint8Array.toHex()); // "cafed00d" const data = new Uint8Array([255, 0, 0, 0, 255, 0, 0, 0, 255]); for (let i = 0; i < data.length; i += 3) { console.log(data.slice(i, i + 3).toHex()); } // "ff0000" // "00ff00" // "0000ff"