What Is UTF-8? Character Encoding and Garbled Text (Mojibake) Explained
UTF-8 is the character encoding that lets computers store every language and emoji as bytes — and it's the default almost everywhere now. How encoding works, why you see garbled text like ’ or é, and how to fix it in HTML, databases, CSV files and code.
UTF-8 is the most common way computers turn text into bytes and back again. It can represent every character in Unicode — English letters, accented letters, Arabic, Chinese, emoji — and it's the default for the web, JSON, Linux, and most modern databases.
You usually only notice it when it goes wrong, and your app shows café instead of café, or it’s instead of it's.
Characters, code points and bytes
Computers only store numbers. Text needs two agreements:
- A character set that gives every character a number. Unicode is the universal one:
Ais 65,éis 233,😀is 128512. These numbers are called code points. - An encoding that says how to write those numbers as bytes. UTF-8 is one encoding of Unicode.
UTF-8's clever trick is that it uses 1 byte for ASCII characters, including English letters, digits and basic punctuation (so old ASCII text is valid UTF-8 unchanged), and 2 to 4 bytes for non-ASCII characters.
| Character | Bytes in UTF-8 |
|---|---|
A |
1 |
é |
2 |
€ |
3 |
😀 |
4 |
Why text gets garbled ("mojibake")
Garbled text happens when bytes are written in one encoding and read in another. The classic case: text saved as UTF-8 but read as Windows-1252 (which differs from ISO-8859-1, also called Latin-1):
| Should be | Shows as |
|---|---|
é |
é |
’ (curly apostrophe) |
’ |
“ (opening curly quote) |
“ |
😀 |
😀 |
If you see à and †patterns, something likely read UTF-8 bytes as Windows-1252 or another legacy encoding. The data itself is often fine — the reader is wrong.
How to fix it, by where it shows up
Web pages: declare UTF-8 at the top of your HTML and make sure the server sends it:
<meta charset="utf-8">
The Content-Type: text/html; charset=utf-8 header should agree. (HTTP Headers Explained)
Databases: Postgres databases are normally created with UTF-8 encoding — check with SHOW server_encoding;. In MySQL, use utf8mb4, not the older utf8, which can't store emoji. (Postgres vs MySQL)
CSV files from Excel: Excel may save CSVs in a legacy encoding, or need a "BOM" to open UTF-8 CSVs correctly. Use "CSV UTF-8" when saving, and when importing, tell your tool the file is UTF-8. (Import a CSV Into Postgres)
Code: be explicit when reading files:
open('data.txt', encoding='utf-8')
fs.readFileSync('data.txt', 'utf8')
Text that was double-encoded
Sometimes text was decoded wrongly and saved that way — the garbage is now in your database. Fixing it means reversing the specific mistake: encode back using the encoding that was wrongly used (Windows-1252 for the examples above), then decode those bytes as UTF-8. This only works if no bytes were lost or replaced. Test on a copy first, and back up before running anything over real data. (Backups for Beginners)
The summary
- Unicode numbers every character; UTF-8 turns those numbers into 1–4 bytes.
- Garbled text like
’means UTF-8 was read as a different encoding. - Use UTF-8 everywhere: HTML meta tag, headers, database (
utf8mb4in MySQL), file reads.
EasySpawn runs your app and its Postgres database together on one server, set up with UTF-8 from the start, with Claude Code there to untangle the odd file that isn't. See how it works or join the waitlist.
Related: What Is Base64? · How to Read an Error Message · What Is JSON? · Debugging for Beginners
Keep reading
Postgres Connection Strings Explained: Format, Examples, and Common Errors
What every part of a PostgreSQL connection string (DATABASE_URL) means, how to write one, special characters in passwords, sslmode options, pooled vs direct connections (including Supabase's ports), and how to fix the errors people hit most.
Dates and Time Zones in Apps: How Not to Get Them Wrong
Reminders sent an hour late, bookings on the wrong day, 'yesterday' that's actually today. Why dates are hard, the golden rule (store UTC, display local), ISO 8601, time zones vs offsets, daylight saving traps, and how to check your AI-built app handles them.