Unicode vs UTF-8: What Is the Difference?

Unicode defines characters and assigns them code points. UTF-8 is one way to encode those code points as bytes so they can be stored in files, databases, web pages and network messages.

On this page

Unicode vs UTF-8 at a glance

FeatureUnicodeUTF-8
PurposeDefines characters and code pointsEncodes Unicode code points as bytes
Example for éU+00E9C3 A9
TypeCharacter standardVariable-length character encoding
Data representationAbstract code pointsOne to four bytes
ASCII compatibilityIncludes ASCII code pointsPreserves ASCII byte values
Used forDefining text charactersFiles, web pages, APIs, databases and network data

Unicode answers “Which character is this?” UTF-8 answers “Which bytes should represent it?” The two belong together in modern software, but they describe different layers of text handling.

What is Unicode?

Unicode is an international character standard. It assigns unique code points to letters, punctuation, symbols, control characters, emoji and many other text elements used by software. A code point is usually written as U+ followed by hexadecimal digits, such as U+0041 for A.

Unicode does not by itself define one single byte representation for a file or network message. It defines the coded character set and related rules. Encodings such as UTF-8, UTF-16 and UTF-32 define how Unicode scalar values are represented for storage or transmission.

CharacterUnicode nameCode point
ALATIN CAPITAL LETTER AU+0041
éLATIN SMALL LETTER E WITH ACUTEU+00E9
ЖCYRILLIC CAPITAL LETTER ZHEU+0416
CJK UNIFIED IDEOGRAPH-5B57U+5B57
😀GRINNING FACEU+1F600

For more background, read What Is Unicode?, inspect real input with the Unicode Character Inspector, or search characters with Unicode Character Lookup.

What is UTF-8?

UTF-8 stands for Unicode Transformation Format, 8-bit. It converts Unicode code points into byte sequences. ASCII-range code points use one byte, many accented letters and scripts such as Cyrillic use two bytes, many other scripts use three bytes, and emoji or other supplementary characters commonly use four bytes.

That byte length applies per code point, not necessarily per visible character. A single grapheme cluster can contain multiple code points, such as a base letter plus combining mark or an emoji sequence joined by zero-width joiners.

Code-point rangeUTF-8 length
U+0000–U+007F1 byte
U+0080–U+07FF2 bytes
U+0800–U+FFFF3 bytes
U+10000–U+10FFFF4 bytes

Surrogate code points, U+D800 through U+DFFF, are not valid Unicode scalar values and must not be encoded directly in UTF-8. They are used only as part of UTF-16 surrogate-pair machinery.

How Unicode becomes UTF-8 bytes

AU+004141

éU+00E9C3 A9

ЖU+0416D0 96

U+5B57E5 AD 97

😀U+1F600F0 9F 98 80

CharacterCode pointUTF-8 hexadecimal bytesByte count
AU+0041411
éU+00E9C3 A92
ЖU+0416D0 962
U+5B57E5 AD 973
😀U+1F600F0 9F 98 804

The code point remains conceptually the same. The UTF-8 byte sequence is the serialized representation used outside the abstract text model. Hexadecimal byte notation such as C3 A9 is not the same notation as Unicode code-point notation such as U+00E9. Use Text to Unicode Code Points and Unicode Code Points to Text to move between text and code-point notation.

Interactive UTF-8 example

This local inspector shows the same distinction for your own input. It uses browser APIs, does not call the backend, and limits input size so the page stays responsive.

UTF-8 inspector

Enter text to inspect code points, UTF-8 bytes, grapheme clusters and UTF-16 code units.

Processed locally in your browser

Limit: 2,000 UTF-16 code units. Input is not sent to UnicodeNow servers.

Open full UTF-8 Encoder and Decoder
Character Code point UTF-8 bytes Byte count Unicode name

Why UTF-8 is compatible with ASCII

ASCII defines 128 values from 0 to 127. Unicode uses the same code points for that repertoire, and UTF-8 encodes those code points with identical single-byte values. That means plain ASCII text is also valid UTF-8.

A → ASCII 0x41 → UTF-8 0x41
7 → ASCII 0x37 → UTF-8 0x37
? → ASCII 0x3F → UTF-8 0x3F

Is Unicode an encoding?

People sometimes say “Unicode encoding” informally, but the precise statement matters when debugging files and protocols. Unicode defines a coded character set and related standards. UTF-8, UTF-16 and UTF-32 are encodings for representing Unicode code points.

Incorrectly vague: The file is Unicode.
Better: The file is encoded as UTF-8.

Software should normally identify the encoding explicitly in file-reading APIs, HTTP headers, HTML metadata, import settings and database connections.

UTF-8 vs UTF-16 vs UTF-32

EncodingStorage unitTypical sizeASCII compatibilityCommon usage
UTF-88-bit byte1–4 bytes per code pointYesWeb, APIs, files, Unix-like systems
UTF-1616-bit code unit1–2 code unitsNo byte-level compatibilityJavaScript, Java, some Windows APIs
UTF-3232-bit code unit1 code unit per code pointNoSpecialized processing

UTF-8 is generally preferred for web content and data interchange. UTF-16 uses surrogate pairs for supplementary code points. UTF-32 offers fixed-width code points but uses more space. None of these guarantees that one storage unit equals one visible character because grapheme clusters may contain multiple code points.

Compare the details in UTF-8 vs UTF-16, then inspect sequences with the Unicode Sequence Analyzer.

Character count vs byte count

Counts differ because software can count bytes, UTF-16 code units, Unicode code points, or user-perceived grapheme clusters. A has 1 code point, 1 grapheme cluster, 1 UTF-8 byte and 1 UTF-16 code unit. 😀 has 1 code point and usually 1 grapheme cluster, but 4 UTF-8 bytes and 2 UTF-16 code units.

TextVisible charactersCode pointsUTF-8 bytesUTF-16 code units
A1111
é1121
e◌́1232
😀1142
👨‍👩‍👧‍👦1 grapheme cluster in most renderers72511

Use the Unicode Character Counter for text-length checks, or the Byte Length Calculator when you need byte-level visibility.

Unicode normalization does not change the encoding

The character é can be represented as the single code point U+00E9, or as e plus a combining acute accent: U+0065 U+0301. Both forms can be encoded in UTF-8.

U+00E9 → C3 A9
U+0065 U+0301 → 65 CC 81

Normalization changes the code-point sequence. Encoding changes code points into bytes. They solve different problems. Read Unicode Normalization Explained, then try the Unicode Normalizer or Unicode Normalization Checker.

Common Unicode and UTF-8 mistakes

Treating bytes as characters

Slicing or counting raw bytes can split a multi-byte UTF-8 sequence. Decode bytes once, then process text with Unicode-aware APIs.

Decoding UTF-8 as Windows-1252 or ISO-8859-1

Wrong decoding causes mojibake: café can become café, and It’s can become It’s. Read What Is Mojibake?, then use Mojibake Repair and the UTF-8 Validator.

Encoding text twice

Double encoding happens when software treats already decoded text as bytes and encodes it again. It can create repeated corruption that becomes harder to repair.

Assuming one character equals one byte

This only works for ASCII-range text. Most non-ASCII text uses multiple UTF-8 bytes per code point.

Assuming one code point equals one visible character

Combining marks, emoji sequences and grapheme clusters can make several code points appear as one visible unit. Read Code Points, Code Units and Grapheme Clusters.

Omitting encoding declarations

Be explicit in HTML charset tags, HTTP content types, CSV import settings, database connection encodings and file-reading APIs.

Using UTF-8 byte length as a character limit

Database storage limits, API payload limits, user-facing character limits, SMS limits and platform-specific limits may all count different units. Choose the count that matches the actual constraint.

UTF-8 on the web

HTML pages should declare UTF-8 early, and HTTP responses should use an appropriate content type. JSON is normally exchanged as Unicode text and is commonly encoded as UTF-8. URLs use percent-encoded bytes in relevant components. HTML source, HTML entities and rendered text are related but different abstractions.

<meta charset="utf-8">
Content-Type: text/html; charset=utf-8

Use URL Encoder and Decoder, JSON Escape and Unescape and HTML Entity Encoder and Decoder when web text crosses syntax boundaries.

UTF-8 in programming languages

Python

text = "café"

encoded = text.encode("utf-8")
decoded = encoded.decode("utf-8")

print(encoded.hex())

Python str represents text, while bytes represents encoded data. Encoding converts text to bytes; decoding converts bytes to text.

JavaScript

const text = "café";
const bytes = new TextEncoder().encode(text);
const decoded = new TextDecoder("utf-8").decode(bytes);

console.log([...bytes]);

JavaScript strings use UTF-16 code units internally. TextEncoder produces UTF-8 bytes, and TextDecoder converts bytes back to text.

PHP

$text = "café";

$bytes = unpack("C*", $text);
$length = strlen($text);
$characters = mb_strlen($text, "UTF-8");

strlen() counts bytes. mb_strlen() can count characters in a specified encoding. PHP string handling depends on the function being used.

How to verify that text is valid UTF-8

Validate byte sequences before decoding untrusted files. Do not assume a file is UTF-8 based only on its extension. Automatic encoding detection is probabilistic, a byte order mark may be present but is not required for UTF-8, and replacement characters often indicate an earlier decoding failure.

  1. Keep the original bytes.
  2. Check for a BOM.
  3. Validate UTF-8.
  4. Detect likely alternative encodings if validation fails.
  5. Decode once.
  6. Inspect suspicious characters.
  7. Avoid repeatedly encoding and decoding text.

Start with the UTF-8 Validator, Unicode Character Inspector and Mojibake Repair.

Which should you use: Unicode or UTF-8?

This is usually the wrong comparison because they serve different roles. Use Unicode-aware software for text, and use UTF-8 as the default encoding for web pages, APIs, configuration files, source files and data exchange unless a specific system requires something else.

Exceptions include existing UTF-16 APIs, legacy file formats, protocol-specific requirements, systems requiring fixed-width processing and compatibility with older software. UTF-8 is a strong default, not a universal mandate.

Try these UnicodeNow tools

These tools connect the concepts in this guide to the text you are debugging. They help you inspect code points, byte sequences, length counts and common encoding damage.

Unicode Character Inspector

Inspect each Unicode character, encoding, category, script and normalization form.

UnicodeProcessed locally

Unicode Character Counter

Count code points, grapheme clusters, words, bytes and invisible characters.

Text ComparisonProcessed locally

Byte Length Calculator

Count UTF-8 bytes, code points, grapheme clusters and UTF-16 code units for text.

EncodingProcessed locally

UTF-8 Validator

Validate hexadecimal byte sequences as UTF-8.

EncodingServer tool

Unicode Sequence Analyzer

Analyze code points, grapheme clusters, bytes, scripts and directionality.

UnicodeProcessed locally

Mojibake Repair

Try common repairs for text decoded with the wrong encoding.

ConvertersServer tool

Frequently asked questions

Is Unicode the same as UTF-8?

No. Unicode defines characters and code points. UTF-8 encodes code points as bytes.

Is UTF-8 part of Unicode?

UTF-8 is a Unicode encoding form defined for representing Unicode code points as byte sequences.

Is every Unicode file UTF-8?

No. Unicode text may be stored using UTF-8, UTF-16, UTF-32 or another supported transformation or format.

Is ASCII valid UTF-8?

Yes. Standard ASCII byte sequences are also valid UTF-8.

How many bytes does UTF-8 use?

UTF-8 uses one to four bytes per Unicode code point.

Why does é use two bytes in UTF-8?

Because U+00E9 falls outside the one-byte ASCII range, so UTF-8 represents it as C3 A9.

Does one UTF-8 byte equal one character?

Only for ASCII-range characters. Other code points require multiple bytes.

Does one Unicode code point equal one visible character?

Not always. A visible grapheme may contain multiple code points.

Should databases use UTF-8?

UTF-8 is generally a strong default, but database-specific character-set and collation configuration must also be correct.

What causes mojibake?

Mojibake usually occurs when bytes encoded in one character encoding are decoded using another.

References