String.fromCodePoint()
The Unicode-correct counterpart to fromCharCode. It accepts the full code point range, encodes surrogate pairs for you, and refuses invalid input instead of truncating it.
Demo
The second case is the whole difference: the single code point 128512 produces a complete emoji, where fromCharCode would truncate it to its low 16 bits and give an unrelated character. The surrogate pair is constructed internally, so the resulting string has length 2 even though it is one character — the encoding detail is handled, not hidden. ASCII values behave identically to fromCharCode, which is why the two are easy to confuse until non-BMP text appears.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| ...codePoints | number | no (none) | Any number of Unicode code points from 0 to 0x10FFFF. Non-integers and out-of-range values throw RangeError. With no arguments you get an empty string. |
Return value
string — A string built from the given code points, with surrogate pairs constructed automatically. Throws RangeError for anything outside 0 to 0x10FFFF.
Common patterns
String.fromCodePoint(0x1f600);
String.fromCodePoint(s.codePointAt(0)) === [...s][0];
const grin = '\u{1F600}';
Examples
Pitfalls
String.fromCodePoint(128512).length
[...String.fromCodePoint(128512)].length
String.fromCodePoint(0x110000)
if (cp >= 0 && cp <= 0x10ffff) String.fromCodePoint(cp);
String.fromCodePoint(65.5)
String.fromCodePoint(Math.trunc(65.5))
'a'.fromCodePoint(65)
String.fromCodePoint(65)
When to use
- Building characters from code points of any value
- Anything involving emoji or non-Latin scripts
- Round-tripping with codePointAt
- Decoding escape sequences from data
- The character is a known constant → a \u{...} escape in a literal
- You hold UTF-16 code units already → fromCharCode is the matching inverse
- Decoding byte data → TextDecoder
- Very large arrays → chunk the spread, or TextDecoder
Notes
FAQ
When the code point is computed or comes from data. For a constant character the escape is clearer and needs no function call — the method exists for the dynamic case.
const ch = '\u{1F600}'; // constant const ch2 = String.fromCodePoint(cp); // computed