FileDummy Logo
FileDummy
File Formats & Deep Dives

UTF-8 vs UTF-16 vs UTF-32: Text File Encoding Explained Simply

Understand the difference between UTF-8, UTF-16, and UTF-32 text encoding. Learn BOM, code points, byte order, and when each encoding is the right choice for developers.

September 20, 20269 min read1,420 views
encodingutf-8utf-16unicodetext-files

Text encoding bugs—mojibake characters like é instead of é—happen when software misinterprets the byte sequences representing Unicode code points. Understanding how UTF-8, UTF-16, and UTF-32 encode characters is essential for building resilient file processing pipelines.

The Unicode Model: Code Points vs Bytes

Unicode maps abstract characters to numeric code points (e.g. U+0041 for 'A', U+1F600 for '😀'). The transformation format (UTF) dictates how those numbers are serialized into binary bytes.

EncodingBytes per CharacterSelf-Synchronizing?Web Adoption
UTF-81 to 4 bytes (Variable)Yes98.2% of all websites
UTF-162 or 4 bytes (Variable)No (Requires BOM/Endianness)Windows internal / JVM / JS engine
UTF-32Exactly 4 bytes (Fixed)YesRare (high memory overhead)
Verified Test Asset.txt

Download our 1MB UTF-8 text file to test character decoding and multibyte parsing.

Download 1MB TXT Sample →

How UTF-8 Variable Length Works

  • ASCII characters (0-127): Encoded in 1 byte (0xxxxxxx), maintaining 100% backwards compatibility with legacy ASCII.
  • Latin, Greek, Cyrillic (128-2047): Encoded in 2 bytes.
  • Asian scripts, CJK (2048-65535): Encoded in 3 bytes.
  • Emojis & rare symbols (65536+): Encoded in 4 bytes.
TypeScript
// Decoding bytes safely in Node.js
import { TextDecoder } from 'util';

export function decodeTextSafely(buffer: Buffer): string {
  // fatal: true throws an exception instead of inserting  replacement characters
  const decoder = new TextDecoder('utf-8', { fatal: true });
  return decoder.decode(buffer);
}

The Byte Order Mark (BOM)

UTF-8 does not require a Byte Order Mark because bytes are ordered identically on big-endian and little-endian machines. However, some Windows software (Notepad, Excel) prepends 0xEF 0xBB 0xBF. Always strip leading BOM bytes when parsing text files in Node.js.

NDL

Nguyen Dai Long

Author

Backend Lead • Distributed Systems & Cloud Edge Architecture Specialist

4+ years designing high-throughput file ingestion pipelines, database architectures, and distributed edge storage on Cloudflare R2 & AWS S3. Founder of FileDummy and the NDL Ecosystem.

Was this article helpful?

Click Like to support the author and help other developers discover this guide.

Engineering Discussion & Feedback (0)

Share benchmark results, report edge cases, or ask technical questions.

0/3000

No comments yet. Be the first developer to start the discussion!

Frequently Asked Questions

Why is UTF-8 dominant on the web?â–¾

UTF-8 is backward-compatible with ASCII, self-synchronizing (character boundaries are detectable without reading from the start), has no byte order ambiguity, and is space-efficient for ASCII-heavy text. HTTP, HTML5, JSON, and XML all default to UTF-8.

What is a BOM (Byte Order Mark) and do I need it?â–¾

A BOM is a special Unicode character (U+FEFF) that indicates byte order for UTF-16/UTF-32, or identifies UTF-8. UTF-8 BOM (EF BB BF) is optional and often causes problems with parsers. Modern tooling recommends UTF-8 without BOM.

When should I use UTF-16 instead of UTF-8?â–¾

UTF-16 is used internally by Windows APIs, Java, JavaScript engines, and .NET — they store strings as UTF-16 in memory. For file storage and network transmission, prefer UTF-8. Use UTF-16 only when required by specific APIs.

Related Articles