JavaScript strings can contain Unicode characters directly, but real-world data often arrives in escaped, encoded, or numeric forms. You may see `\u00E9`, `\u{1F600}`, HTML entities such as `©`, or arrays of Unicode code points from an API or database. Knowing how to convert unicode to string in javascript helps you display those values correctly without corrupting accents, emoji, non-Latin text, or special symbols.
The right solution depends on the format you have. A Unicode escape inside JavaScript source behaves differently from a literal backslash sequence stored in a variable. Likewise, a code point such as `128512` needs a different method than a UTF-8 byte array. This article explains the practical conversion methods, when to use `String.fromCodePoint()`, why `JSON.parse()` can help with escaped text, and the mistakes that often cause broken characters. By the end, you will be able to identify your input format and reliably turn it into readable JavaScript text.
Unicode Values and JavaScript Strings
Unicode is a standard that assigns a numeric value, called a code point, to characters. For example, `A` is U+0041, `é` is U+00E9, and 😀 is U+1F600. JavaScript strings use UTF-16 internally, which supports Unicode text but has a few details worth knowing.
Most ordinary text needs no special conversion. You can write `const city = “München”;` or `const greeting = “こんにちは”;`, and JavaScript stores those values as strings. Conversion becomes necessary when text arrives as code points, escape sequences, bytes, or entities rather than readable characters.
Unicode Escape Sequences in Source Code
JavaScript recognizes Unicode escapes written directly in string literals. The common form uses four hexadecimal digits: `”\u00A9″` becomes `©`. Modern JavaScript also supports brace notation, which accepts full Unicode code points: `”\u{1F600}”` becomes 😀.
This works only when JavaScript parses the source code itself. If a variable contains the characters `\`, `u`, `0`, `0`, `A`, and `9`, JavaScript does not automatically reinterpret them as an escape sequence. That distinction explains many Unicode conversion issues.
Using String.fromCodePoint for Numeric Unicode Values
`String.fromCodePoint()` is usually the best method when you have one or more Unicode code points as numbers. It handles both Basic Multilingual Plane characters and characters above U+FFFF, including many emoji and historical scripts.
For example:
“`javascript
const copyright = String.fromCodePoint(0x00A9);
const smile = String.fromCodePoint(0x1F600);
console.log(copyright); // ©
console.log(smile); // 😀
“`
You can also pass multiple values at once. This is useful when an API returns a sequence of code points, or when you need to build a string from numeric character data.
“`javascript
const word = String.fromCodePoint(72, 101, 108, 108, 111);
console.log(word); // Hello
“`
Why fromCodePoint Is Better Than fromCharCode
Older JavaScript code often uses `String.fromCharCode()`. It works for code units up to U+FFFF, but it does not correctly represent a full Unicode code point above that range by itself. Many emoji require two UTF-16 code units, known as a surrogate pair.
`String.fromCodePoint()` handles that work for you. For modern code, it is clearer and safer whenever the input represents Unicode code points rather than explicitly calculated UTF-16 code units.
Practical differences to remember:
- Use `String.fromCodePoint(0x1F680)` for 🚀.
- Use `String.fromCharCode(0x1F680)` only if you specifically need its lower UTF-16 code unit, which is rarely the goal.
- Use `String.fromCharCode(0xD83D, 0xDE80)` only when working deliberately with a surrogate pair.
- Prefer `fromCodePoint()` when text may include emoji, mathematical symbols, or non-BMP characters.
Converting Hexadecimal Code Points
Unicode values are often displayed in hexadecimal notation, such as `U+1F44B` for 👋. Before passing such a value to `String.fromCodePoint()`, remove the `U+` prefix and convert the remaining hexadecimal text into a number.
“`javascript
const unicodeValue = “U+1F44B”;
const codePoint = parseInt(unicodeValue.replace(“U+”, “”), 16);
const character = String.fromCodePoint(codePoint);
console.log(character); // 👋
“`
If the input contains only hexadecimal digits, use `parseInt(value, 16)`. Always include the radix of `16`; it makes your code explicit and avoids confusion for future maintainers.
Converting Multiple Unicode Code Point Strings
A value may contain several code points separated by spaces, commas, or another delimiter. Split the value, normalize each code point, convert it to a number, and then pass the resulting array into `String.fromCodePoint()`.
“`javascript
const values = “U+0048 U+0065 U+006C U+006C U+006F”;
const result = String.fromCodePoint(
…values.split(” “).map(value =>
parseInt(value.replace(“U+”, “”), 16)
)
);
console.log(result); // Hello
“`
This pattern is useful for Unicode lists copied from specifications, design files, or data exports. Validate the source format first, especially if it may contain blank values, commas, or lowercase prefixes.
Decoding Literal Unicode Escape Sequences
A string that contains literal escape text requires parsing before it becomes readable Unicode. For example, data received from a service may look like `”\\u00E9″` in JavaScript, even though the intended result is `é`.
A practical technique is to use `JSON.parse()` when the input contains valid JSON-compatible string escapes. Wrap the value in double quotes, escape any existing double quotes, and parse it as JSON.
“`javascript
function decodeUnicodeEscapes(value) {
return JSON.parse(`”${value.replace(/”/g, ‘\\”‘)}”`);
}
console.log(decodeUnicodeEscapes(“\\u00E9”)); // é
console.log(decodeUnicodeEscapes(“\\u{1F600}”)); // Error in JSON
“`
JSON Escape Rules and Limitations
`JSON.parse()` supports the standard `\uXXXX` format, where exactly four hexadecimal digits follow `\u`. It does not support JavaScript’s brace-style form, such as `\u{1F600}`. That format must be handled with a custom replacement function.
Also avoid using `eval()` or `Function()` merely to decode Unicode text. They can execute untrusted input and create a security risk. Parsing targeted character patterns is safer and easier to review.
Use this checklist before decoding escaped text:
- Confirm that the value contains literal escapes rather than already-decoded characters.
- Use `JSON.parse()` for valid `\uXXXX` sequences in controlled string data.
- Use custom parsing for `\u{…}` escapes or mixed input formats.
- Catch parsing errors when input comes from users or external systems.
- Never use `eval()` to process text encoding.
Decoding Both Four-Digit and Brace Escapes
When your input may contain both `\uXXXX` and `\u{…}` forms, a replacement callback gives you more control. The callback can inspect the matched code point, convert it from hexadecimal, and return the real character.
“`javascript
function decodeUnicodeEscapes(value) {
return value.replace(
/\\u(?:\{([0-9a-fA-F]+)\}|([0-9a-fA-F]{4}))/g,
(_, braced, fixed) => {
const hex = braced || fixed;
return String.fromCodePoint(parseInt(hex, 16));
}
);
}
console.log(decodeUnicodeEscapes(“Caf\\u00E9”)); // Café
console.log(decodeUnicodeEscapes(“Hello \\u{1F44B}”)); // Hello 👋
“`
This example handles escape sequences embedded inside regular text. It does not decode every possible encoding convention, which is a benefit: predictable conversion is safer than making assumptions about arbitrary input.
Validating Code Point Ranges
Unicode code points range from `0` through `0x10FFFF`. Values outside that range are invalid, and surrogate code point values from `0xD800` through `0xDFFF` should generally not be treated as independent Unicode characters.
A defensive conversion helper can reject invalid input before it reaches your UI, database, or export process. That gives you clearer error handling than allowing malformed data to quietly produce unexpected results.
“`javascript
function unicodeToCharacter(value) {
const codePoint = Number(value);
if (
!Number.isInteger(codePoint) ||
codePoint < 0 ||
codePoint > 0x10FFFF ||
(codePoint >= 0xD800 && codePoint <= 0xDFFF)
) {
throw new RangeError(“Invalid Unicode code point”);
}
return String.fromCodePoint(codePoint);
}
“`
Converting UTF-8 Bytes to Text
Unicode code points are not the same as UTF-8 bytes. If you receive byte data from a file, network response, encryption process, or binary storage layer, use `TextDecoder` rather than `String.fromCodePoint()`.
“`javascript
const bytes = new Uint8Array([72, 101, 108, 108, 111, 32, 240, 159, 152, 128]);
const text = new TextDecoder(“utf-8”).decode(bytes);
console.log(text); // Hello 😀
“`
`TextDecoder` interprets the bytes according to the specified encoding. In browsers and current Node.js versions, UTF-8 is widely supported. This is also the right direction to take when troubleshooting encoding problems in API responses. For related handling techniques, see [Internal Link: JavaScript UTF-8 Encoding Guide].
Comparing Common Unicode Conversion Methods
| Input format | Example input | Recommended method |
| — | — | — |
| Numeric code point | `128512` | `String.fromCodePoint(128512)` |
| Hex code point | `”1F600″` | `String.fromCodePoint(parseInt(value, 16))` |
| Unicode label | `”U+1F600″` | Remove `U+`, parse as hex, use `fromCodePoint()` |
| Literal `\uXXXX` text | `”\\u00E9″` | `JSON.parse()` or targeted replacement |
| Literal `\u{…}` text | `”\\u{1F600}”` | Custom regular-expression replacement |
| UTF-8 byte array | `Uint8Array(…)` | `new TextDecoder(“utf-8”).decode(bytes)` |
| HTML numeric entity | `”©”` | Decode as HTML or parse the entity format |
Decoding HTML Unicode Entities
Web content sometimes contains HTML numeric entities rather than JavaScript escapes. For example, `©` represents © and `😀` represents 😀. In a browser, you can decode trusted entity text using a temporary element.
“`javascript
function decodeHtmlEntities(value) {
const textarea = document.createElement(“textarea”);
textarea.innerHTML = value;
return textarea.value;
}
console.log(decodeHtmlEntities(“© 2026”)); // © 2026
“`
Use this approach carefully with untrusted HTML. A textarea is suitable for converting text entities, but inserting untrusted values into the page through `innerHTML` in other contexts can expose your application to cross-site scripting risks.
Handling Unicode in JSON Responses
Valid JSON can include actual Unicode characters or escaped four-digit Unicode sequences. When you call `response.json()` or `JSON.parse()`, compliant JSON escapes are decoded automatically.
“`javascript
const json = ‘{“message”:”Caf\\u00E9″}’;
const data = JSON.parse(json);
console.log(data.message); // Café
“`
If you still see `\u00E9` after parsing, the data may have been escaped twice. In that case, inspect the original response and determine whether the field is intentionally storing an escaped string. Decode only that field rather than running broad replacements across the entire object.
Unicode Normalization for Matching Text
Two strings can look identical but use different Unicode sequences. For example, `é` may be a single code point or a combination of `e` plus a combining accent. This matters when comparing usernames, search terms, filenames, or imported data.
JavaScript provides `String.prototype.normalize()` to standardize a representation. NFC is a common choice for display and comparison, while NFD separates combined characters into base characters and marks.
“`javascript
const composed = “é”;
const decomposed = “e\u0301”;
console.log(composed === decomposed); // false
console.log(composed.normalize(“NFC”) === decomposed.normalize(“NFC”)); // true
“`
Normalization is not a conversion substitute. It does not decode escaped strings or byte arrays. Use it after you have decoded the text when consistent matching or storage is important.
Common Unicode Conversion Mistakes
The most frequent error is treating every Unicode value as though it were a four-digit escape. Emoji and many other characters require code points larger than `FFFF`, so a four-digit-only solution will either fail or produce an incorrect result.
Another issue is confusing encoded bytes with numeric code points. Passing UTF-8 byte values one by one into `String.fromCodePoint()` produces mojibake, which is text rendered as the wrong characters. Decode byte arrays with `TextDecoder` instead.
Avoid these common mistakes:
- Using `fromCharCode()` for emoji and other non-BMP characters.
- Passing `&quot;U+1F600&quot;` directly to `String.fromCodePoint()` without converting it to a number.
- Decoding already-correct text a second time.
- Assuming `JSON.parse()` supports `\u{1F600}` syntax.
- Using `decodeURIComponent()` as a general Unicode decoder.
- Ignoring normalization when visually identical strings fail equality checks.
Choosing the Right Method in Real Projects
Start by looking at the exact input you receive, not the character you expect to display. Log the value with `JSON.stringify()` when necessary, because it reveals backslashes and invisible characters more clearly than a plain console output.
For user-facing text, preserve the original data when possible and decode only at a well-defined boundary, such as API parsing or file import. That approach keeps encoding logic out of your UI components and makes bugs easier to trace. [Internal Link: JavaScript String Methods] can also help when cleaning and validating converted text.
A Reusable Conversion Utility
For applications that accept code point labels, hexadecimal values, and decimal values, a small utility can centralize the conversion logic. It should accept known formats, reject invalid values, and avoid guessing at bytes or HTML entities.
“`javascript
function convertUnicodeValue(value) {
const input = String(value).trim();
let codePoint;
if (/^U\+[0-9A-F]+$/i.test(input)) {
codePoint = parseInt(input.slice(2), 16);
} else if (/^0x[0-9A-F]+$/i.test(input)) {
codePoint = parseInt(input, 16);
} else if (/^\d+$/.test(input)) {
codePoint = Number(input);
} else {
throw new TypeError(“Use a decimal, hexadecimal, or U+ Unicode value”);
}
if (codePoint > 0x10FFFF) {
throw new RangeError(“Unicode code point is out of range”);
}
return String.fromCodePoint(codePoint);
}
console.log(convertUnicodeValue(“U+2764”)); // ❤
console.log(convertUnicodeValue(“0x1F680”)); // 🚀
console.log(convertUnicodeValue(“169”)); // ©
“`
This utility intentionally keeps different data types separate. If your application also receives escaped JavaScript strings or UTF-8 bytes, create dedicated functions for those inputs rather than merging every conversion rule into one unpredictable helper.
Conclusion
The reliable way to convert Unicode data depends on what you actually have. Use `String.fromCodePoint()` for numeric code points, parse hexadecimal values before conversion, and use `TextDecoder` when working with UTF-8 bytes. Literal escape text such as `\u00E9` needs explicit decoding, while JSON parsing handles standard four-digit escapes automatically.
It is equally important to avoid shortcuts that only appear to work. `fromCharCode()` can break characters outside the Basic Multilingual Plane, `eval()` is unsafe for decoding text, and byte values should never be treated as if they were Unicode code points. Normalization can also prevent subtle comparison errors after text is decoded.
Once you identify whether your input is a code point, escaped sequence, HTML entity, or byte array, the implementation becomes straightforward. That is the practical foundation for knowing how to convert unicode to string in javascript without losing characters or introducing encoding bugs.
Frequently Asked Questions
Can JavaScript display Unicode characters directly?
Yes. JavaScript strings can contain Unicode characters directly, including accented letters, Arabic text, Chinese characters, and emoji. Conversion is only needed when your source data uses code points, escape sequences, byte arrays, or encoded entities.
When should I use String.fromCodePoint?
Use `String.fromCodePoint()` when you have a Unicode character’s numeric code point, such as `169` or `0x1F600`. It correctly handles values above U+FFFF, unlike `String.fromCharCode()` used with a single argument.
Why does my Unicode escape show as text?
Your value likely contains a literal backslash sequence, not a parsed JavaScript escape. For standard `\uXXXX` input, decode it with `JSON.parse()` or a controlled replacement function instead of expecting automatic conversion.
How do I convert U plus Unicode notation?
Remove the `U+` prefix, parse the remaining characters as a hexadecimal number, then pass the result to `String.fromCodePoint()`. For example, `U+00A9` becomes `String.fromCodePoint(parseInt(“00A9”, 16))`.
Does JSON parse Unicode escapes automatically?
Yes, `JSON.parse()` decodes valid JSON `\uXXXX` escape sequences into characters. It does not support JavaScript brace escapes such as `\u{1F600}`, so those values require a custom decoding function.