String.fromCharCode()
Builds a string from a sequence of UTF-16 code unit numbers.
String.fromCharCode()
String.fromCharCode(num1)
String.fromCharCode(num1, num2)
String.fromCharCode(num1, num2, /* …, */ numN)- Added in JavaScript ES1
Parameters
| Parameter | Type | Description |
|---|---|---|
$num1, …, numNoptional | number | Numbers between 0 and 65535 (0xFFFF) representing UTF-16 code units. Values above 0xFFFF are truncated to their last 16 bits, and no validity checks are performed. |
Return value
stringA string of length N consisting of the N specified UTF-16 code units.
String.fromCharCode() is a static method — call it on String, never on a string instance. It turns raw UTF-16 code unit numbers back into text, and is the inverse of charCodeAt().
When to reach for it
Use it when you already hold code units: decoding a byte or UInt16 array, implementing a cipher or checksum by hand, generating a run of letters from their numeric codes, or reconstructing text from a wire format that transmits numbers.
fromCharCode or fromCodePoint?
If your numbers are genuine Unicode code points — anything that might exceed 0xFFFF, such as emoji — use String.fromCodePoint() instead. fromCharCode() performs no validation: a value above 0xFFFF is silently truncated to its low 16 bits, so 0x12014 quietly becomes 0x2014, an em dash. That silence is the method's sharpest edge.
To emit an astral character with fromCharCode() you must supply the surrogate pair yourself: String.fromCharCode(0xd83c, 0xdf03).
What trips people up
Spreading a very large array — String.fromCharCode(...bytes) — can overflow the call stack. Chunk the array into slices of a few thousand and join the results.
Example
When to use it
- Rebuild text from an array of char codes produced by charCodeAt
- Generate the letters A–Z programmatically for a column header row
- Decode a simple substitution or Caesar cipher character by character
Frequently asked questions
How do I convert a number to a character in JavaScript?
Call String.fromCharCode(n) for a UTF-16 code unit, or String.fromCodePoint(n) when n is a full Unicode code point that may exceed 0xFFFF. Both are static methods on String, not methods on a string instance.
What is the difference between fromCharCode and fromCodePoint?
fromCharCode takes UTF-16 code units and silently truncates anything above 0xFFFF, while fromCodePoint takes real code points up to 0x10FFFF and generates the surrogate pair for you. Use fromCodePoint unless you are deliberately working with code units.
Why does String.fromCharCode(...arr) throw a RangeError for a big array?
Spreading a large array exceeds the engine's maximum argument count and overflows the call stack. Process the array in chunks of a few thousand elements and join the resulting strings.
More examples
Silent truncation above 0xFFFF
0x12014 loses its leading 1 and collapses onto the em dash — no error, no warning, just wrong text. Reaching an astral character with fromCharCode requires passing the two surrogates yourself, which is exactly what fromCodePoint does for you.
console.log(String.fromCharCode(0x2014)); // em dash, fits in 16 bits
console.log(String.fromCharCode(0x12014)); // high bits discarded
console.log(String.fromCharCode(0x12014) === String.fromCharCode(0x2014));
// The correct ways to get an astral character:
console.log(String.fromCharCode(0xd83c, 0xdf03)); // explicit surrogate pair
console.log(String.fromCodePoint(0x1f303)); // code point directlyA Caesar shift
Arithmetic happens on the numeric code and fromCharCode turns the result back into a character; non-letters pass through untouched. Shifting by 3 and then by 23 returns the original text, confirming the round trip.
function shift(text, by) {
return [...text]
.map((ch) => {
const code = ch.charCodeAt(0);
if (code < 97 || code > 122) return ch;
return String.fromCharCode(((code - 97 + by) % 26) + 97);
})
.join("");
}
console.log(shift("attack at dawn", 3));
console.log(shift(shift("attack at dawn", 3), 23));
Discussion