JavaScript String toWellFormed() Method

Beginner
5 min read
Updated: Nov 2026
3 examples
Method

Definition

String.prototype.toWellFormed() returns a new string where every lone UTF-16 surrogate is replaced with U+FFFD (�). Well-formed text (including valid emoji pairs) is left intact. It takes no parameters (ES2024).

Pass the required arguments shown below. Check return values and browser support before you rely on the result.

Syntax

Call string.toWellFormed. Start with this line.

JavaScript
string.toWellFormed()
CallWhat it does
string.toWellFormed()Primary signature.
string.toWellFormed(...)Call with the arguments your case needs.

Built into JavaScript. Call toWellFormed(...) on a string (or String instance) — no import required.

Library declarations
JavaScript
string.toWellFormed()

Parameters

This member has no parameters beyond those shown in the signature.

Return Value

Return ValueDescription
*New well-formed string (lone surrogates → �)

JavaScript Examples

Example 1 — Repair Lone Surrogates

Well-formed text stays; orphan surrogates become �.

JavaScript
console.log("Hello".toWellFormed());          // "Hello"
console.log("\uD800".toWellFormed());         // "\uFFFD" → �
console.log("A\uD83D\uDE00".toWellFormed());  // "A😀"
console.log("ab\uD800c".toWellFormed());      // "ab�c"
Try It Yourself

How It Works

  1. Clean input. "Hello" has no surrogates → same text back.
  2. Lone high. "\uD800" is invalid alone → replaced with �.
  3. Valid emoji. \uD83D\uDE00 is a proper pair → 😀 kept.
  4. Mixed string. Only the orphan unit in the middle is replaced.

Example 2 — Pair with isWellFormed()

Check first, then repair only when needed.

JavaScript
function clean(str) {
  if (str.isWellFormed()) {
    return str;
  }
  return str.toWellFormed();
}

console.log(clean("OK"));           // "OK"
console.log(clean("\uD800"));       // "�"
console.log(clean("Hi").length);    // 2
Try It Yourself

How It Works

  1. Check. isWellFormed() returns a boolean.
  2. Skip work. If already valid, return the original string reference.
  3. Repair. Otherwise call toWellFormed() for a cleaned copy.
  4. Pattern. Check → fix is the usual pair for these two methods.

Example 3 — Safe encodeURI()

Ill-formed strings throw in encodeURI; repair first.

JavaScript
const lone = "\uD800";

try {
  console.log(encodeURI(lone));
} catch (e) {
  console.log(e.name);  // "URIError"
}

console.log(encodeURI(lone.toWellFormed()));
// "%EF%BF%BD"
Try It Yourself

How It Works

  1. Raw encode fails. encodeURI rejects lone surrogates → URIError.
  2. Repair first. toWellFormed() swaps the orphan for �.
  3. Encode succeeds. � encodes as %EF%BF%BD.
  4. Rule of thumb. Sanitize untrusted UTF-16 before URI APIs.

Browser & Runtime Support

String.prototype.toWellFormed() is part of ES2024. It reached Baseline Widely available around October 2023.

✓ Baseline · ES2024

String.prototype.toWellFormed()

Supported in Chrome 111+, Firefox 119+, Safari 16.4+, Edge 111+, and Node.js 20+. Not available in Internet Explorer.

90% Modern browser support
Google Chrome Supported · Desktop & Mobile
Full support
Mozilla Firefox Supported · Desktop & Mobile
Full support
Apple Safari Supported · macOS & iOS
Full support
Microsoft Edge Supported · Chromium
Full support
Internet Explorer No native support · Use a polyfill
Polyfill
Opera Supported · Modern versions
Full support
Samsung Internet Supported · Android
Full support
Bun Supported · JavaScript runtime
Supported
Deno Supported · JavaScript runtime
Supported
Node.js Supported · Server runtime
Supported
Android WebView Supported · Modern WebView
Full support
toWellFormed() Excellent

Bottom line: Safe for modern web apps and Node 20+. For older targets, feature-detect with if ("toWellFormed" in String.prototype) and polyfill, or skip repair when unsupported.

Frequently Asked Questions

toWellFormed() returns a new string where every lone UTF-16 surrogate is replaced with the Unicode replacement character U+FFFD (�). Well-formed strings keep the same text content.
UTF-16 uses pairs of code units for characters above U+FFFF. A lone (orphan) surrogate is one half without its matching partner — for example "\uD800" alone.
No. Call it with empty parentheses: str.toWellFormed().
isWellFormed() returns true or false. toWellFormed() returns a repaired string. Check with isWellFormed(); fix with toWellFormed().
encodeURI throws URIError on ill-formed strings. Passing str.toWellFormed() replaces lone surrogates first so encoding succeeds (the replacement becomes %EF%BF%BD).
No. Strings are immutable. It always returns a new string — even when the input was already well-formed.

Next: normalize()

Learn Unicode normalization forms so equivalent characters compare and store consistently.

normalize() tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful