# UTF-8

> Mediated Wiki article. Canonical URL: https://mediated.wiki/source/UTF-8
> Markdown URL: https://mediated.wiki/source/UTF-8.md
> Source: https://en.wikipedia.org/wiki/UTF-8
> Source revision: 1355436144
> License: Creative Commons Attribution-ShareAlike 4.0 International (https://creativecommons.org/licenses/by-sa/4.0/)

{{Short description|ASCII-compatible variable-width encoding of Unicode}}
{{Infobox character encoding
| name = UTF-8
| mime = 
| alias = 
| image = 
| caption = 
| standard = [https://www.unicode.org/versions/latest/ Unicode Standard]
| status = 
| classification = [Unicode Transformation Format](/source/Unicode_Transformation_Format), [extended ASCII](/source/extended_ASCII), [variable-length encoding](/source/variable-width_encoding)
| encodes = [ISO/IEC 10646](/source/ISO%2FIEC_10646) ([Unicode](/source/Unicode))
| extends = [ASCII](/source/ASCII)
| prev = [UTF-1](/source/UTF-1)
| next = 
}}

'''UTF-8''' is a [character encoding](/source/character_encoding) standard used for electronic communication. Defined by the [Unicode](/source/Unicode) Standard, the name is derived from ''Unicode Transformation Format{{snd}} 8-bit''.<ref name=":1">{{Cite book
 | title         = Unicode® 6.0.0: Released: 2010 October 11 (Announcement)
 | url           = https://www.unicode.org/versions/Unicode6.0.0/

 | edition       = 6.0.0
 | publisher     = [The Unicode Consortium](/source/The_Unicode_Consortium)
 | isbn          = 978-1-936213-01-6
 | location      = Mountain View, California, US
 | access-date   = 2025-08-23
 | url-status    = live
 | archive-url   = https://web.archive.org/web/20250728233736/https://www.unicode.org/versions/Unicode6.0.0/
 | archive-date  = 2025-07-28
}}</ref> As of 2026, almost every webpage (99%<!-- rounded from 98.9%; actually 99.6% of top-1000 websites could argue 100% ... -->) is transmitted as UTF-8.<ref name="W3TechsWebEncoding" />

UTF-8 supports all 1,112,064<ref>{{cite book
 | title         = Unicode 16.0.0: Core Spec / Chapter 3
 | chapter-url   = https://www.unicode.org/versions/Unicode16.0.0/core-spec/chapter-3/#G7404
 | edition       = 6.0.0
 | at            = 3.9 Unicode Encoding Forms
 | chapter       = Conformance
 | quote         = Each encoding form maps the Unicode code points U+0000..U+D7FF and U+E000..U+10FFFF
 | publisher     = [The Unicode Consortium](/source/The_Unicode_Consortium)
 | isbn          = 978-1-936213-34-4
 | location      = Mountain View, California, US
 | url-status    = live
 | archive-url   = https://web.archive.org/web/20250701110809/https://www.unicode.org/versions/Unicode16.0.0/core-spec/chapter-3/#G7404
 | archive-date  = 2025-07-01
 | access-date   = 2025-08-23
}}</ref> valid Unicode [code points](/source/Code_point) using a [variable-width encoding](/source/variable-width_encoding) of one to four one-[byte](/source/byte) (8-bit) code units.

Code points with lower numerical values, which tend to occur more frequently, are encoded using fewer bytes. It was designed for [backward compatibility](/source/backward_compatibility) with [ASCII](/source/ASCII): the first 128 characters of Unicode, which correspond one-to-one with ASCII, are encoded using a single byte with the same binary value as ASCII, so that a UTF-8-encoded file using only those characters is identical to an ASCII file. Most software designed for any [extended ASCII](/source/extended_ASCII) can read and write UTF-8, and this results in fewer internationalization issues than any alternative text encoding.<ref name="Microsoft GDK" /><ref name=":3">{{Cite web |title=Encoding Standard |url=https://encoding.spec.whatwg.org/#preface |access-date=2025-11-20 |website=encoding.spec.whatwg.org}}</ref>

UTF-8 is dominant for all countries/languages on the internet, is used in most standards, often the only allowed encoding, and is supported by all modern operating systems and programming languages.

== History ==
{{See also|Universal Coded Character Set#History}}
The [International Organization for Standardization](/source/International_Organization_for_Standardization) (ISO) set out to compose a universal multi-byte character set in 1989. The draft ISO 10646 standard contained a non-required [annex](/source/Addendum) called [UTF-1](/source/UTF-1) that provided a byte stream encoding of its [32-bit](/source/32-bit_computing) code points. This encoding was not satisfactory on performance grounds, among other problems, and the biggest problem was probably that it did not have a clear separation between ASCII and non-ASCII: new UTF-1 tools would be backward compatible with ASCII-encoded text, but UTF-1-encoded text could confuse existing code expecting ASCII (or [extended ASCII](/source/extended_ASCII)), because it could contain continuation bytes in the range {{mono|0x21}}–{{mono|0x7E}} that meant something else in ASCII, e.g., {{mono|0x2F}} for <code>/</code>, the [Unix](/source/Unix) [path](/source/Path_(computing)) directory separator.

In July 1992, the [X/Open](/source/X%2FOpen) committee XoJIG was looking for a better encoding. Dave Prosser of [Unix System Laboratories](/source/Unix_System_Laboratories) submitted a proposal for one that had faster implementation characteristics and introduced the improvement that 7-bit ASCII characters would ''only'' represent themselves; multi-byte sequences would only include bytes with the high bit set. The name ''File System Safe UCS Transformation Format'' (''FSS-UTF'')<ref>{{cite web|url=https://www.unicode.org/L2/Historical/wg20-n193-fss-utf.pdf|title=File System Safe UCS&nbsp;— Transformation Format (FSS-UTF) - X/Open Preliminary Specification|website=unicode.org}}</ref> and most of the text of this proposal were later preserved in the final specification.<ref name="FSS-UTF">{{cite journal |title=Appendix F. FSS-UTF / File System Safe UCS Transformation format |journal=The Unicode Standard 1.1 |url=https://www.unicode.org/versions/Unicode1.1.0/appF.pdf |access-date=2016-06-07 |url-status=live |archive-url=https://web.archive.org/web/20160607215950/https://www.unicode.org/versions/Unicode1.1.0/appF.pdf |archive-date=2016-06-07}}</ref><ref>{{Cite mailing list |last=Whistler |first=Kenneth |date=2001-06-12 |mailing-list=Unicode Mail List |title=FSS-UTF, UTF-2, UTF-8, and UTF-16 |url=https://unicode.org/mail-arch/unicode-ml/y2001-m06/0318.html |url-status=live |archive-url=https://web.archive.org/web/20160607220249/https://unicode.org/mail-arch/unicode-ml/y2001-m06/0318.html |archive-date=2016-06-07 |access-date=2025-11-20}}</ref><ref name="pikeviacambridge">{{cite web |url=https://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt |title=UTF-8 history |author-first=Rob |author-last=Pike |author-link=Rob Pike |date=2003-04-30 |access-date=2012-09-07}}</ref> In August 1992, this proposal was circulated by an [IBM](/source/IBM) X/Open representative to interested parties. 

A modification by [Ken Thompson](/source/Ken_Thompson) of the [Plan 9 operating system](/source/Plan_9_from_Bell_Labs) group at [Bell Labs](/source/Bell_Labs) made it [self-synchronizing](/source/Self-synchronizing_code), letting a reader start anywhere and immediately detect character boundaries, at the cost of being somewhat less bit-efficient than the previous proposal. It also abandoned the use of biases that prevented overlong encodings.<ref name=pikeviacambridge/><ref>At that time subtraction was slower than bit logic on many computers, and speed was considered necessary for acceptance.{{citation needed|date=October 2024}}</ref> Thompson's design was outlined on September 2, 1992, on a [placemat](/source/placemat) in a New Jersey diner with [Rob Pike](/source/Rob_Pike). In the following days, Pike and Thompson implemented it and updated [Plan 9](/source/Plan_9_from_Bell_Labs) to use it throughout,<ref>{{cite book |chapter-url=https://www.cl.cam.ac.uk/~mgk25/ucs/UTF-8-Plan9-paper.pdf |chapter=Hello World or Καλημέρα κόσμε or こんにちは 世界 |title=Proceedings of the Winter 1993 USENIX Conference |first1=Rob |last1=Pike |first2=Ken |last2=Thompson |year=1993}}</ref> and then communicated their success back to X/Open, which accepted it as the specification for [FSS-UTF](/source/FSS-UTF).<ref name=pikeviacambridge/> UTF-8 was first officially presented at the [USENIX](/source/USENIX) conference in [San Diego](/source/San_Diego), from January 25 to 29, 1993.<ref>{{Cite web |title=USENIX WINTER 1993 CONFERENCE PROCEEDINGS |url=https://www.usenix.org/legacy/publications/library/proceedings/sd93/ |access-date=2025-11-20 |website=www.usenix.org}}</ref> The [Internet Engineering Task Force](/source/Internet_Engineering_Task_Force) adopted UTF-8 in its Policy on Character Sets and Languages in RFC&nbsp;2277 ([<abbr title="Best Current Practice">BCP</abbr>](/source/Request_for_Comments) 18) for future internet standards work in January 1998, replacing [Single Byte Character Set](/source/Single_Byte_Character_Set)s such as [Latin-1](/source/ISO%2FIEC_8859-1) in older RFCs.<ref name="rfc2277">{{cite IETF |rfc=2277 |bcp=18 |title=IETF Policy on Character Sets and Languages |date=January 1998 |last1=Alvestrand |first1=Harald T. |author-link=Harald Alvestrand |publisher=[IETF](/source/Internet_Engineering_Task_Force)}}</ref>

In November 2003, UTF-8 was restricted by {{IETF RFC|3629}} to match the constraints of the [UTF-16](/source/UTF-16) character encoding: explicitly prohibiting code points corresponding to the high and low surrogate characters removed <!-- 2*2^10/(2^16-2^11) --> more than 3% of the three-byte sequences, and ending at {{tt|U+10FFFF}} removed <!-- (2^21-(2^16+2^20))/(2^21-2^16) --> more than 48% of the four-byte sequences and all five- and six-byte sequences.<ref>{{cite web |author-last=Pike |author-first=Rob |author-link=Rob Pike |date=2012-09-06 |title=UTF-8 turned 20 years old yesterday |url=https://plus.google.com/u/0/101960720994009339267/posts/Rz1udTvtiMg |url-status=dead |archive-url=https://web.archive.org/web/20121130120145/https://plus.google.com/u/0/101960720994009339267/posts/Rz1udTvtiMg |archive-date=2012-11-30 |access-date=2012-09-07 }}</ref>

== Description ==
UTF-8 encodes code points in one to four bytes, depending on the value of the code point. In the following table, the characters {{mono|'''u'''}} to {{mono|'''z'''}}, each representing a hexadecimal digit, are replaced by their constituent [4 bits](/source/Nibble) {{mono|''uuuu''}} to {{mono|''zzzz''}}, from the positions {{mono|U+'''uvwxyz'''}}:

{| class="wikitable"
|+ Code point ↔ UTF-8 conversion
|-
! First code point
! Last code point
! Byte 1
! Byte 2
! Byte 3
! Byte 4
|-
| style="text-align: right" | {{tt|U+0000}}
| style="text-align: right" | {{tt|U+007F}}
| {{mono|0''yyyzzzz''}}
| style="background: darkgray" colspan=3 |
|-
| style="text-align: right" | {{tt|U+0080}}
| style="text-align: right" | {{tt|U+07FF}}
| {{mono|110''xxxyy''}}
| {{mono|10''yyzzzz''}}
| style="background: darkgray" colspan=2 |
|-
| style="text-align: right" | {{tt|U+0800}}
| style="text-align: right" | {{tt|U+FFFF}}
| {{mono|1110''wwww''}}
| {{mono|10''xxxxyy''}}
| {{mono|10''yyzzzz''}}
| style="background: darkgray" |
|-
| style="text-align: right" | {{tt|U+010000}}
| style="text-align: right" | {{tt|U+10FFFF}}
| {{mono|11110''uvv''}}
| {{mono|10''vvwwww''}}
| {{mono|10''xxxxyy''}}
| {{mono|10''yyzzzz''}}
|}

As an example, the character 桁 has the hexadecimal code point {{mono|U+6841}}, which is {{mono|0110 1000 0100 0001}} in binary, which makes its UTF-8 encoding {{mono|11100110 10100001 10000001}}.

The first 128&nbsp;code points (ASCII) need 1&nbsp;byte. The next 1,920&nbsp;code points need two bytes to encode, which covers the remainder of almost all [Latin-script alphabet](/source/Latin-script_alphabet)s, and also [IPA extensions](/source/International_Phonetic_Alphabet), [Greek](/source/Greek_alphabet), [Cyrillic](/source/Cyrillic_script), [Coptic](/source/Coptic_alphabet), [Armenian](/source/Armenian_alphabet), [Hebrew](/source/Hebrew_alphabet), [Arabic](/source/Arabic_alphabet), [Syriac](/source/Syriac_alphabet), [Thaana](/source/Thaana) and [N'Ko](/source/N'Ko_script) alphabets, as well as [Combining Diacritical Marks](/source/Combining_Diacritical_Marks). Three bytes are needed for the remaining 61,440&nbsp;codepoints of the [Basic Multilingual Plane](/source/Basic_Multilingual_Plane) (BMP), including most [Chinese, Japanese and Korean characters](/source/CJK_characters). Four bytes are needed for the 1,048,576&nbsp;non-BMP code points, which include [emoji](/source/emoji), less common [CJK characters](/source/CJK_characters), and other useful characters.<ref>{{Cite web |last=Lunde |first=Dr Ken |date=2022-01-09 |title=2022 Top Ten List: Why Support Beyond-BMP Code Points? |url=https://ken-lunde.medium.com/2022-top-ten-list-why-support-beyond-bmp-code-points-6a946d7735f9 |access-date=2025-11-20 |website=Medium |language=en}}</ref>

UTF-8 is a ''[prefix code](/source/prefix_code)'' and it is unnecessary to read past the last byte of a code point to decode it. Unlike many earlier multi-byte text encodings such as [Shift-JIS](/source/Shift-JIS), it is ''[self-synchronizing](/source/Self-synchronizing_code)'' so searches for short strings or characters are possible; and the start of a code point can be found from a random position by backing up at most 3 bytes. The values chosen for the lead bytes means sorting a list of UTF-8 strings puts them in the same order as sorting [UTF-32](/source/UTF-32) strings.

=== Overlong encodings ===
{{anchor|overlong encodings}}
Using a row in the above table to encode a code point less than "First code point" (thus using more bytes than necessary) is termed an ''overlong encoding''. These are a security problem because they allow character sequences to bypass other security validations like the [blocking of <code>../</code>](/source/directory_traversal_attack) or of [malicious JavaScript](/source/Cross-site_scripting). There have been numerous high-profile vulnerabilities involving overlong encodings reported in products such as Microsoft's [IIS](/source/Internet_Information_Services) web server<ref name=MS00-078>{{ cite report | first = Marvin |last = Marin | date = 2000-10-17 | title = Windows NT UNICODE vulnerability analysis | department = Web server folder traversal | id = MS00-078 | series = Malware FAQ | website=SANS Institute | url=https://www.sans.org/resources/malwarefaq/wnt-unicode.php | url-status=dead | archive-url=https://web.archive.org/web/20140827001204/http://www.sans.org/security-resources/malwarefaq/wnt-unicode.php | archive-date=Aug 27, 2014 }}</ref> and Apache's Tomcat servlet container.<ref name="CVE-2008-2938">{{cite web |year=2008 |title=CVE-2008-2938 |url=https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2008-2938 |access-date=2025-11-20 |website=National Vulnerability Database (nvd.nist.gov) |publisher=U.S. [National Institute of Standards and Technology](/source/National_Institute_of_Standards_and_Technology)}}</ref> Overlong encodings should therefore be considered an error and never decoded.

=== Error handling ===
Not all sequences of bytes are valid UTF-8. A UTF-8 decoder should be prepared for:

* A "continuation byte" ({{tt|0x80}}{{ndash}}{{tt|0xBF}}) at the start of a character
* A non-continuation byte (or the string ending) before the end of a character
* An overlong encoding ({{tt|0xC0}}, {{tt|0xC1}}, {{tt|0xE0}} followed by less than {{tt|0xA0}}, or {{tt|0xF0}} followed by less than {{tt|0x90}})
* A multi-byte sequence that decodes to a value greater than {{tt|U+10FFFF}} ({{tt|0xF4}} followed by {{tt|0x90}} or greater, {{tt|0xF5}}{{ndash}}{{tt|0xFF}})

Many of the first UTF-8 decoders would decode these, ignoring incorrect bits. Carefully crafted invalid UTF-8 could make them either skip or create ASCII characters such as {{mono|NUL}}, slash, or quotes, leading to security vulnerabilities. {{nobr|RFC 3629}} states "Implementations of the decoding algorithm MUST protect against decoding invalid sequences."<ref name="rfc3629">{{cite IETF |title=UTF-8, a transformation format of ISO 10646 |rfc=3629 |std=63 |last1=Yergeau |first1=F. |date=November 2003 |publisher=[IETF](/source/Internet_Engineering_Task_Force) |access-date=August 20, 2020}}</ref> ''The Unicode Standard'' requires decoders to: "...&nbsp;treat any ill-formed code unit sequence as an error condition. This guarantees that it will neither interpret nor emit an ill-formed code unit sequence."<!-- anyone have a copy of ISO/IEC 10646-1:2000 annex D for comparison?  -->

It was common to throw an exception or truncate the string at an error<ref>{{Cite web |title=DataInput (Java Platform SE 8 ) |url=https://docs.oracle.com/javase/8/docs/api/java/io/DataInput.html |access-date=2025-11-20 |website=docs.oracle.com}}</ref> but this turns what would otherwise be harmless errors (i.e. "file not found") into a [denial of service](/source/denial_of_service), for instance early versions of Python 3.0 would exit immediately if the command line or [environment variable](/source/environment_variable)s contained invalid UTF-8.<ref name="pep383"/> Most code now replaces each error with a single code point (such as {{unichar|FFFD|nlink=replacement character}}) and continue decoding.{{Citation needed|reason=There are different versions of the standard and it is unclear to which version "now" refers to. A check of Unicode17.0.0 Core does not find a match of this recommendation easily|date=April 2026}}

Some decoders consider the sequence {{mono|E1,A0,20}} (a truncated 3-byte code followed by a space) as a single error. This is not a good idea as a search for a space character would find the one hidden in the error. Since Unicode&nbsp;6 (October&nbsp;2010)<ref name=":1" /> the standard (chapter&nbsp;3) has recommended a "best practice" where the error is either one continuation byte, or ends at the first byte that is disallowed, so {{mono|E1,A0,20}} is a two-byte error followed by a space. An error is no more than three bytes long, never contains the start of a valid character, and there are {{val|21952|fmt=commas}}&nbsp;different possible errors. Many decoders instead make ''each'' byte be an error, in which case {{mono|E1,A0,20}} is ''two'' errors followed by a space; there are now only 128 different errors which makes it practical to store the errors in the output string,<ref name="pep383"/> or replace them with characters from a legacy encoding.

Only a small subset of possible byte strings are error-free UTF-8: several bytes cannot appear, a byte with the high bit set cannot be alone, and in a truly random string a byte with a high bit set has only a {{frac|1|15}} chance of starting a valid UTF-8 character. This has the consequence of making it easy to detect if a legacy text encoding is accidentally used instead of UTF-8, making conversion of a system to UTF-8 easier and avoiding the need to require a [Byte Order Mark](/source/Byte_Order_Mark) or any other metadata.

=== Surrogates ===
{{anchor|WTF-8}}
Since RFC 3629 (November&nbsp;2003), the high and low surrogates used by [UTF-16](/source/UTF-16) ({{tt|U+D800}} through {{tt|U+DFFF}}) are not legal Unicode values, and their UTF-8 encodings must be treated as an invalid byte sequence.<ref name="rfc3629"/> These encodings all start with {{tt|0xED}} followed by {{tt|0xA0}} or higher. This rule is often ignored as surrogates are allowed in Windows filenames and this means there must be a way to store them in a string.<ref>{{Cite web |title=PEP 529 – Change Windows filesystem encoding to UTF-8 {{!}} peps.python.org |url=https://peps.python.org/pep-0529/ |access-date=2025-11-20 |website=Python Enhancement Proposals (PEPs) |language=en}}</ref> UTF-8 that allows these surrogate halves has been (informally) called ''WTF-8'', for "wobbly transformation format",<ref>{{Cite web |title=The WTF-8 encoding |url=https://wtf-8.codeberg.page |access-date=2025-11-30 |website=wtf-8.codeberg.page}}</ref> while another variation that also encodes all non-BMP characters as two surrogates (6&nbsp;bytes instead of 4) is called ''[CESU-8](/source/CESU-8)''.

=== Byte map ===
The chart below gives the detailed meaning of each byte in a stream encoded in UTF-8.
{{UTF-8 byte map}}

=== Byte-order mark ===
If the Unicode [byte-order mark](/source/byte-order_mark) {{tt|U+FEFF}} is at the start of a UTF-8 file, the first three bytes will be {{mono|0xEF}}, {{mono|0xBB}}, {{mono|0xBF}}.

The Unicode Standard neither requires nor recommends the use of the BOM for UTF-8, but warns that it may be encountered at the start of a file trans-coded from another encoding.<ref>{{citation | chapter-url = https://www.unicode.org/versions/Unicode15.0.0/ch02.pdf | title = The Unicode Standard&nbsp;— Version 15.0.0 | chapter = Chapter 2 | page = 39 }}</ref> While ASCII text encoded using UTF-8 is backward compatible with ASCII, this is not true when Unicode Standard recommendations are ignored and a BOM is added. A BOM can confuse software that isn't prepared for it but can otherwise accept UTF-8, e.g. programming languages that permit non-ASCII bytes in [string literal](/source/string_literal)s but not at the start of the file. Nevertheless, there was and still is software that always inserts a BOM when writing UTF-8, and refuses to correctly interpret UTF-8 unless the first character is a BOM (or the file only contains ASCII).{{citation needed|date=March 2026}}

=== Older standards ===

Earlier standards for UTF-8, like {{IETF RFC|2279}}, could encode up to 31 bits in 6 bytes, as shown in the table below.  The current {{IETF RFC|3629}} allows only up to 4 bytes.thumb|An older UTF-8 encoding scheme, defined before Unicode 4.0, that could encode up to 31 bits. For this table the characters {{mono|'''s'''}} to {{mono|'''z'''}}, each representing a hexadecimal digit, are replaced by their constituent [4 bits](/source/Nibble) {{mono|''ssss''}} to {{mono|''zzzz''}}, from the positions {{mono|U+'''stuvwxyz'''}}:

{| class="wikitable"
|+ Code point ↔ UTF-8 conversion as defined in {{IETF RFC|2279}} 
|-
! First code point
! Last code point
! Byte 1
! Byte 2
! Byte 3
! Byte 4
! Byte 5
! Byte 6
|-
| style="text-align: right" | {{tt|U+0000}}
| style="text-align: right" | {{tt|U+007F}}
| {{mono|0''yyyzzzz''}}
| style="background: darkgray" colspan=5 |
|-
| style="text-align: right" | {{tt|U+0080}}
| style="text-align: right" | {{tt|U+07FF}}
| {{mono|110''xxxyy''}}
| {{mono|10''yyzzzz''}}
| style="background: darkgray" colspan=4 |
|-
| style="text-align: right" | {{tt|U+0800}}
| style="text-align: right" | {{tt|U+FFFF}}
| {{mono|1110''wwww''}}
| {{mono|10''xxxxyy''}}
| {{mono|10''yyzzzz''}}
| style="background: darkgray" colspan=3  |
|-
| style="text-align: right" | {{tt|U+010000}}
| style="text-align: right" | {{tt|U+1FFFFF}}
| {{mono|11110''uvv''}}
| {{mono|10''vvwwww''}}
| {{mono|10''xxxxyy''}}
| {{mono|10''yyzzzz''}}
| style="background: darkgray" colspan=2  |
|-
| style="text-align: right;" |{{tt|U+200000}}
| style="text-align: right;" |{{tt|U+3FFFFFF}}
| {{mono|111110''tt''}}
| {{mono|10''uuuuvv''}}
| {{mono|10''vvwwww''}}
| {{mono|10''xxxxyy''}}
| {{mono|10''yyzzzz''}}
| style="background: darkgray;" |
|-
| style="text-align: right;" |{{tt|U+4000000}}
| style="text-align: right;" |{{tt|U+7FFFFFFF}}
| {{mono|1111110''s''}}
| {{mono|10''sstttt''}}
| {{mono|10''uuuuvv''}}
| {{mono|10''vvwwww''}}
| {{mono|10''xxxxyy''}}
| {{mono|10''yyzzzz''}}
|}

== Comparison to UTF-16 ==
{{See also|Comparison of Unicode encodings}}

For a long time there was considerable argument as to whether it was better to process text in [UTF-16](/source/UTF-16) or in UTF-8.{{citation needed|date=March 2026}} The primary advantage of UTF-16 is that the [Windows API](/source/Unicode_in_Microsoft_Windows) required it for access to all Unicode characters (UTF-8 was not fully supported in Windows until May 2019). This caused several libraries such as [Qt](/source/Qt_(software)) to also use UTF-16 strings which propagates this requirement to non-Windows platforms.

In the early days of Unicode, there were no characters greater than {{tt|U+FFFF}} and [combining characters](/source/combining_characters) were rarely used, so the 16-bit encoding was effectively fixed-size. Some believed fixed-size encoding could make processing more efficient, but any such advantages were lost as soon as UTF-16 became variable width as well.

The code points {{tt|U+0800}}–{{tt|U+FFFF}} take 3 bytes in UTF-8 but only 2 in UTF-16. This led to the idea that text in Chinese and other languages would take more space in UTF-8. However, text is only larger if there are more of these code points than 1-byte ASCII code points, and this rarely happens in real-world documents due to [markup](/source/markup_language),<ref>{{cite web |last1=Radzivilovsky |first1=Pavel |last2=Galka |first2=Yakov |last3=Novgorodov |first3=Slava |title=UTF-8 Everywhere Manifesto |url=https://utf8everywhere.org/#asian |website=UTF-8 Everywhere |access-date=25 March 2026 |ref=manifesto-asian}}</ref> along with spaces, newlines, digits, punctuation, English words, etc..

UTF-8 has the advantages of being trivial to retrofit to any system that could handle an [extended ASCII](/source/extended_ASCII), not having byte-order problems, and taking about half the space for any language using mostly [Latin letters](/source/Latin_letters).

== Implementations and adoption ==
thumb|Declared character set for the 10&nbsp;million most popular websites from 2010 to 2021
thumb|Use of the main encodings on the web from 2001 to 2012 as recorded by Google,<ref name=MarkDavis2012>{{ cite web | author-last=Davis |author-first=Mark |author-link=Mark Davis (Unicode) | date=2012-02-03 | title=Unicode over 60&nbsp;percent of the web | website=Official Google blog | url=https://googleblog.blogspot.com/2012/02/unicode-over-60-percent-of-web.html | url-status=live |access-date=2020-07-24 | archive-url=https://web.archive.org/web/20180809152828/https://googleblog.blogspot.com/2012/02/unicode-over-60-percent-of-web.html | archive-date=2018-08-09 }}</ref> with UTF-8 overtaking all others in 2008 and over 60% of the web in 2012. UTF-8 is the only encoding of Unicode (explicitly) listed there, and the rest only provide subsets of Unicode. The ASCII-only figure includes all web pages that only contain ASCII characters, regardless of the declared header.

{{See also|Popularity of text encodings}}

UTF-8 has been the most common encoding for the [World Wide Web](/source/World_Wide_Web) since 2008.<ref name="MarkDavis">{{Cite web |author-first=Mark |author-last=Davis |author-link=Mark Davis (Unicode) |date=2008-05-05|title=Moving to Unicode&nbsp;5.1 |url=https://googleblog.blogspot.com/2008/05/moving-to-unicode-51.html |access-date=2023-03-13 |website=Official Google Blog |language=en}}</ref> {{As of|2026|01}}, UTF-8 is used by 98.9% of surveyed web sites.<ref name=W3TechsWebEncoding>{{Cite web|url=https://w3techs.com/technologies/cross/character_encoding/ranking |title=Usage Survey of Character Encodings broken down by Ranking |website=W3Techs |language=en |date=January 2026 |access-date=2026-01-03}}</ref> Although many pages only use ASCII characters to display content, very few websites now declare their encoding to only be ASCII instead of UTF-8.<ref>{{cite web |url=https://w3techs.com/technologies/details/en-usascii |title = Usage statistics and market share of ASCII for websites | date = December 2025 | website = W3Techs | access-date = 2025-12-17 }}</ref> Virtually all countries and <!-- over 97% all of the tracked --> languages have 95% or more use of UTF-8 encodings on the web. <!-- Over 61% of the languages tracked have <!- currently 61.4% have at least 99.5% UTF-8 support which rounds up to 100% (44.5% have "100.0%" which means 99.95+%) -> 100% UTF-8 use. -->

Many standards only support UTF-8, e.g. [JSON](/source/JSON) exchange requires it (without a byte-order mark (BOM)).<ref name=rfc8259>{{ cite IETF | last = Bray | first = Tim | editor-last = Bray | editor-first = Tim | date = December 2017 | title = The JavaScript Object Notation (JSON) Data Interchange Format | publisher = IETF | doi = 10.17487/RFC8259 | access-date = 16 February 2018 | rfc = 8259 }}</ref> UTF-8 is also required by the [WHATWG](/source/WHATWG) for HTML and [DOM](/source/Document_Object_Model) specifications, which states "UTF-8 encoding is the most appropriate encoding for interchange of [Unicode](/source/Unicode)",<ref name=":3" /> and the [Internet Mail Consortium](/source/Internet_Mail_Consortium) recommends that all e‑mail programs be able to display and create mail using UTF-8.<ref name=IMC>{{ cite web | url = https://www.imc.org/mail-i18n.html | title = Using International Characters in Internet Mail | publisher = Internet Mail Consortium | date = 1998-08-01 | access-date = 2007-11-08 | url-status = dead | archive-url = https://web.archive.org/web/20071026103104/https://www.imc.org/mail-i18n.html | archive-date = 2007-10-26}}</ref><ref>{{Cite web |title=Encoding Standard |url=https://encoding.spec.whatwg.org/#security-background |access-date=2025-11-20 |website=encoding.spec.whatwg.org}}</ref> The [World Wide Web Consortium](/source/World_Wide_Web_Consortium) recommends UTF-8 as the default encoding in XML and HTML (and not just using UTF-8, also declaring it in metadata), "even when all characters are in the ASCII range ... Using non-UTF-8 encodings can have unexpected results". Version 5.3 of the W3C HTML specification and the current Living Standard by WHATWG both require UTF-8.<ref name=html5charset>{{cite report | section = Specifying the document's character encoding | title = HTML&nbsp;5.3 | date = 28 January 2021 | publisher = [World Wide Web Consortium](/source/World_Wide_Web_Consortium) | url = https://www.w3.org/TR/2021/NOTE-html53-20210128/document-metadata.html | section-url = https://www.w3.org/TR/2021/NOTE-html53-20210128/document-metadata.html#specifying-the-documents-character-encoding | access-date = 2026-01-06 | mode = cs1 }}</ref><ref name="html5whatwg">{{cite book |chapter-url=https://html.spec.whatwg.org/multipage/semantics.html#charset |chapter=Specifying the document's character encoding |title=HTML Standard |publisher=[WHATWG](/source/WHATWG) |date=17 December 2025 |access-date=2026-01-06}}</ref>

Many software programs have the ability to read/write UTF-8. It may require the user to change options from the normal settings, or may require a BOM (byte-order mark) as the first character to read the file. Examples of software supporting UTF-8 include [Microsoft Word](/source/Microsoft_Word),<!-- "Unicode (UTF-8)", "Unicode (Big-Endian)" and "Unicode (UTF-7)" --><ref>{{ cite web | title=Choose text encoding when you open and save files | website=Microsoft Support | url=https://support.microsoft.com/en-us/office/choose-text-encoding-when-you-open-and-save-files-60d59c21-88b5-4006-831c-d536d42fd861 | access-date=2021-11-01 }}</ref><!-- <ref>{{ cite web | last=Gao |first=Ivy | title=How to fix corrupted character encoding (corrupted text) in Microsoft ''Word'' | website=TurboFuture | url=https://turbofuture.com/computers/3-Easy-Ways-To-Fix-Corrupted-Character-Encoding-In-Plain-Text-Documents | access-date=2021-11-01 | lang=en }}</ref> --><ref>{{ cite web | title = Exporting a UTF-8 <code>.txt</code> file from ''Word'' | website = support.3playmedia.com | date = 14 March 2023 | url = https://support.3playmedia.com/hc/en-us/articles/227730088-Exporting-a-UTF-8-txt-file-from-Word }}</ref> [Microsoft Excel](/source/Microsoft_Excel) ([Office 2003](/source/Office_2003) and later),<ref>{{ cite web | author1 = Abhinav, Ankit | author2 = Xu, Jazlyn | date = April 13, 2020 | title = How to open UTF-8 <code>CSV</code> file in ''Excel'' without mis-conversion of characters in Japanese and Chinese language for both Mac and Windows? | website = Microsoft Support Community | language = en-US | url = https://answers.microsoft.com/en-us/msoffice/forum/all/how-to-open-utf-8-csv-file-in-excel-without-mis/1eb15700-d235-441e-8b99-db10fafff3c2 | access-date = 2021-11-01 }}</ref> [Google Drive](/source/Google_Drive), [LibreOffice](/source/LibreOffice),<ref>{{ cite web | title = Save a CSV file as UTF-8 | series = LibreOffice | website = RO CSVI | url = https://rolandd.com/documentation/ro-csvi/save-a-csv-file-as-utf-8 | access-date = 2025-05-20 }}</ref> and most databases.

Software that "defaults" to UTF-8 (meaning it writes it without the user changing settings, and it reads it without a BOM) has become more common since 2010.<ref>{{cite web | last=Galloway |first=Matt | date=October 2012 | title=Character encoding for iOS developers; or, UTF-8 what now? | website=www.galloway.me.uk | language=en-UK | url=https://www.galloway.me.uk/2012/10/character-encoding-for-ios-developers-utf8/ | access-date=2021-01-02 | quote = ...&nbsp;in reality, you usually just assume UTF-8 since that is by far the most common encoding. }}</ref>{{unreliable source|certain=y|reason=Personal blog|date=January 2026}} [Windows Notepad](/source/Windows_Notepad), in all currently supported versions of Windows, defaults to writing UTF-8 without a BOM (a change from {{nobr|[Windows 7](/source/Windows_7)}} ''Notepad''), bringing it into line with most other text editors.<ref>{{ cite web | title=Windows&nbsp;10 Notepad is getting better UTF-8 encoding support | website=BleepingComputer | url=https://www.bleepingcomputer.com/news/microsoft/windows-10-notepad-is-getting-better-utf-8-encoding-support/ | access-date=2021-03-24 | quote=Microsoft is now defaulting to saving new text files as UTF-8 without BOM, as shown below. | language=en-us }}</ref> Some system files on [Windows&nbsp;11](/source/Windows_11) require UTF-8<ref>{{ cite web | title = Customize the Windows&nbsp;11 ''Start'' menu | url=https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/customize-the-windows-11-start-menu | access-date=2021-06-29 | website=docs.microsoft.com | language=en-us | quote=Make sure your LayoutModification.json uses UTF-8 encoding. }}</ref> with no requirement for a BOM, and almost all files on macOS and most Linux distributions are required to be UTF-8 without a BOM.{{citation needed|date=June 2021}} Programming languages that default to UTF-8 for [I/O](/source/input%2Foutput) include [Ruby](/source/Ruby_(programming_language))&nbsp;3.0,<ref>{{ cite web | title = Set default for Encoding.default_external to UTF-8 on Windows | series = Ruby master | id = Feature&nbsp;#16604 | website = Ruby Issue Tracking System (bugs.ruby-lang.org) | url = https://bugs.ruby-lang.org/issues/16604 | access-date = 2022-08-01 }}</ref><ref>{{ cite web | title = Feature #12650: Use UTF-8 encoding for ENV on Windows | series = Ruby master | website = Ruby Issue Tracking System | url = https://bugs.ruby-lang.org/issues/12650 | access-date = 2022-08-01 }}</ref> [R](/source/R_(programming_language))&nbsp;4.2.2,<ref>{{ cite web | title = New features in R&nbsp;4.2.0 | date = 2022-04-01 | website = R&nbsp;bloggers | series = The Jumping Rivers Blog | url = https://www.r-bloggers.com/2022/04/new-features-in-r-4-2-0/ | access-date = 2022-08-01 | language = en-US }}</ref> [Raku](/source/Raku_(programming_language)) and [Java](/source/Java_(programming_language))&nbsp;18.<ref name=Java_UTF-8_and_UTF-16>{{ cite web | title = UTF-8 by default | id = JEP 400 | website = openjdk.java.net | url = https://openjdk.java.net/jeps/400 | access-date=2022-03-30 }}</ref> [Python](/source/Python_(programming_language)) 3.15 makes UTF-8 the default for I/O;<ref>{{Cite web |title=What's new in Python 3.15 |url=https://docs.python.org/3.15/whatsnew/3.15.html |access-date=2025-12-23 |website=Python documentation |language=en}}</ref><ref>{{ cite web | title = Make UTF-8 mode default | website = peps.python.org | id = PEP&nbsp;686 | url = https://peps.python.org/pep-0686/ | access-date=2023-07-26 }}</ref> previous versions require an option to <code>open()</code> to read/write UTF-8.<ref>{{cite web | title = add a new UTF-8 mode | website = peps.python.org | id = PEP&nbsp;540 | url = https://peps.python.org/pep-0540/ | access-date = 2022-09-23 }}</ref> [C++23](/source/C%2B%2B23) adopted UTF-8 as the only portable source code file format.<ref>{{ cite report | title = Support for UTF-8 as a portable source file encoding | year = 2022 | id = p2295r6 | website = open-std.org | url = https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2295r6.pdf }}</ref>

Backwards compatibility is a serious impediment to changing code and APIs using [UTF-16](/source/UTF-16) to use UTF-8, but this is happening. In May 2019, Microsoft [added the capability](/source/Unicode_in_Microsoft_Windows) for an application to set UTF-8 as the "code page" for the Windows API, removing the need to use UTF-16; and more recently has recommended programmers use UTF-8,<ref name="Microsoft-UTF-8">{{cite web | title=Use UTF-8 code pages in Windows apps | website=[Microsoft Learn](/source/Microsoft_Learn) | date=20 August 2024 |language=en-us | url=https://learn.microsoft.com/en-us/windows/apps/design/globalizing/use-utf8-code-page | access-date=2024-09-24}}</ref> and even states "UTF-16 [...] is a unique burden that Windows places on code that targets multiple platforms".<ref name="Microsoft GDK">{{cite web | title=UTF-8 support in the Microsoft GDK | series = Microsoft Game Development Kit (GDK) | website = [Microsoft Learn](/source/Microsoft_Learn) |language=en-us | url=https://learn.microsoft.com/en-us/gaming/gdk/_content/gc/system/overviews/utf-8 | access-date = 2023-03-05 }}</ref> The default string primitive in [Go](/source/Go_(programming_language)),<ref>{{cite report | section=Source code representation | title=The ''Go'' Programming Language Specification | website=golang.org | section-url=https://golang.org/ref/spec#Source_code_representation | access-date=2021-02-10 }}</ref> [Julia](/source/Julia_(programming_language)), [Rust](/source/Rust_(programming_language)), [Swift](/source/Swift_(programming_language)) (since version 5),<ref>{{cite web | last=Tsai |first=Michael J. | date=21 March 2019 | title=UTF-8 string in Swift&nbsp;5 | type=blog post |language=en | url=https://mjtsai.com/blog/2019/03/21/utf-8-string-in-swift-5/ | access-date=2021-03-15 }}</ref> and [PyPy](/source/PyPy)<ref>{{Cite web |last=Mattip |date=2019-03-24 |title=PyPy v7.1 released; now uses utf-8 internally for unicode strings |url=https://morepypy.blogspot.com/2019/03/pypy-v71-released-now-uses-utf-8.html |access-date=2025-11-20 |website=PyPy Status Blog}}</ref> uses UTF-8 internally in all cases. Python (since version 3.3) uses UTF-8 internally for Python C API extensions<ref name=PEP393>{{cite web | title = Flexible String Representation | id = PEP&nbsp;393 | website = Python.org |language=en | url = https://peps.python.org/pep-0393 | access-date = 2022-05-18 }}</ref><ref>{{Cite web |title=Common Object Structures |url=https://docs.python.org/3/c-api/structures.html |access-date=2025-11-20 |website=Python documentation |language=en}}</ref> and sometimes for strings<ref name=PEP393/><ref>{{cite web | title=Unicode objects and codecs | url=https://docs.python.org/3/c-api/unicode.html | access-date=2023-08-19 |website=Python documentation | quote=UTF-8 representation is created on demand and cached in the Unicode object.}}</ref> and a future version of Python is planned to store strings as UTF-8 by default.<ref>{{cite web | title=PEP&nbsp;623&nbsp;– remove wstr from Unicode | website=Python.org |language=en | url=https://www.python.org/dev/peps/pep-0623/ | access-date=2020-11-21 }}</ref><ref>{{ cite web | last=Wouters |first=Thomas | date=2023-07-11 | title=Python 3.12.0 beta 4 released | website = Python Insider | type = blog post | url=https://pythoninsider.blogspot.com/2023/07/pleased-to-announce-release-of-python-3.html | access-date=2023-07-26 | quote=The deprecated <code>wstr</code> and <code>wstr_length</code> members of the C implementation of unicode objects were removed, per PEP 623. }}</ref> Modern versions of [Microsoft Visual Studio](/source/Microsoft_Visual_Studio) use UTF-8 internally.<ref>{{cite web | title=validate-charset (validate for compatible characters) | website=docs.microsoft.com |language=en-us | url=https://docs.microsoft.com/en-us/cpp/build/reference/validate-charset-validate-for-compatible-characters | access-date=2021-07-19 | quote=Visual Studio uses UTF-8 as the internal character encoding during conversion between the source character set and the execution character set. }}</ref> All currently supported versions of Microsoft SQL Server <!-- i.e. including SQL Server 2016 and 2017 now on Extended support --> support UTF-8 for importing and exporting, and in addition all on mainstream support, i.e. since SQL Server 2019, support UTF-8 internally, and using it results in a 35% speed increase, and "nearly 50% reduction in storage requirements".<ref>{{cite web | title = Introducing UTF-8 support for SQL Server | date = 2019-07-02 | website = techcommunity.microsoft.com | url = https://techcommunity.microsoft.com/t5/sql-server/introducing-utf-8-support-for-sql-server/ba-p/734928 | access-date = 2021-08-24 | language = en-US }}</ref>

{{anchor|Modified UTF-8}}[Java](/source/Java_(programming_language)) internally uses UTF-16 for the <code>char</code> data type and, consequentially, the <code>Character</code>, <code>String</code>, and <code>StringBuffer</code> classes,<ref>{{cite web |title=Character (Java SE 24 & JDK 24) |url=https://docs.oracle.com/en/java/javase/24/docs/api/java.base/java/lang/Character.html#unicode |year=2025 |publisher=[Oracle Corporation](/source/Oracle_Corporation) |access-date=2025-04-08}}</ref> but for I/O uses ''"Modified UTF-8"'', which is the same as CESU-8, except the [null character](/source/null_character) {{tt|U+0000}} uses the two-byte overlong encoding {{tt|0xC0}}&nbsp;{{tt|0x80}} instead of just {{tt|0x00}}.<ref name=":2">{{cite web |title=Java SE documentation for Interface java.io.DataInput, subsection on Modified UTF-8 |url=https://docs.oracle.com/javase/8/docs/api/java/io/DataInput.html#modified-utf-8 |year=2015 |publisher=[Oracle Corporation](/source/Oracle_Corporation) |access-date=2015-10-16}}</ref> Modified UTF-8 strings never contain any actual null bytes but can contain all Unicode code points including {{tt|U+0000}},<ref name=":0">{{cite web |url=https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.7 |title=The Java Virtual Machine Specification, section 4.4.7: The CONSTANT_Utf8_info Structure |publisher=[Oracle Corporation](/source/Oracle_Corporation) |year=2015 |access-date=2015-10-16}}</ref> which allows such strings (with a null byte appended) to be processed by traditional [null-terminated string](/source/null-terminated_string) functions. Java reads and writes normal UTF-8 to files and streams,<ref>{{Javadoc:SE|java/io|InputStreamReader}} and {{Javadoc:SE|java/io|OutputStreamWriter}}</ref> but it uses Modified UTF-8 for object [serialization](/source/Java_serialization),<ref>{{cite web |title=Java Object Serialization Specification, chapter 6: Object Serialization Stream Protocol, section 2: Stream Elements |url=https://docs.oracle.com/javase/8/docs/platform/serialization/spec/protocol.html#a8299 |year=2010 |publisher=[Oracle Corporation](/source/Oracle_Corporation) |access-date=2015-10-16}}</ref><ref>{{Javadoc:SE|java/io|DataInput}} and {{Javadoc:SE|java/io|DataOutput}}</ref> for the [Java Native Interface](/source/Java_Native_Interface),<ref>{{cite web |url=https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/types.html#modified_utf_8_strings |title=Java Native Interface Specification, chapter 3: JNI Types and Data Structures, section: Modified UTF-8 Strings |publisher=[Oracle Corporation](/source/Oracle_Corporation) |year=2015 |access-date=2015-10-16}}</ref> and for embedding constant strings in [Java class file](/source/Java_class_file)s.<ref name=":0" /> The dex format defined by [Dalvik](/source/Dalvik_(software)) also uses the same modified UTF-8 to represent string values.<ref>{{cite web |url=https://source.android.com/tech/dalvik/dex-format.html |title=ART and Dalvik |work=Android Open Source Project |access-date=2013-04-09 |url-status=dead |archive-url=https://web.archive.org/web/20130426010617/https://source.android.com/tech/dalvik/dex-format.html |archive-date=2013-04-26 }}</ref> [Tcl](/source/Tcl_(programming_language)) also uses the same modified UTF-8<ref>{{cite web |title=UTF-8 bit by bit |date=2001-02-28 |url=https://wiki.tcl-lang.org/page/UTF-8+bit+by+bit |access-date=2022-09-03 |website=Tcler's Wiki}}</ref> as Java for internal representation of Unicode data, but uses strict CESU-8 for external data.

The [Raku](/source/Raku_(programming_language)) programming language (formerly Perl 6) uses <code>utf-8</code> encoding by default for I/O ([Perl](/source/Perl) 5 also supports it<!-- "utf8 - Perl pragma to enable/disable UTF-8 (or UTF-EBCDIC) in source code" -->)<!-- "Raku applies normalization by default to all input and output except for file names, which are read and written as UTF8-C8" -->; though that choice in Raku also implies "normalization into Unicode [NFC (normalization form canonical)](/source/Unicode_equivalence). In some cases the user will want to ensure no normalization is done; for this "<code>utf8-c8</code>" can be used.<ref>{{Cite web |title=encoding |website=Raku Documentation |url=https://docs.raku.org/routine/encoding |access-date=2025-11-20}}</ref> That ''UTF-8 Clean-8'' variant, implemented by Raku, is an encoder/decoder <!-- that primarily works as the UTF-8 one. However, upon encountering a byte sequence that will either not decode as valid UTF-8, or that would not round-trip due to normalization, it will use NFG synthetics to keep track of the original bytes involved. This means that encoding back to UTF-8 Clean-8 will be able to recreate the bytes as they originally existed. The synthetics contain four codepoints: ... --> that preserves bytes as is (even illegal UTF-8 sequences) and allows for Normal Form Grapheme synthetics.<ref>{{Cite web |title=Unicode |website=Raku Documentation |url=https://docs.raku.org/language/unicode#UTF8-C8 |access-date=2025-11-20}}</ref>

Version 3 of the [Python](/source/Python_(programming_language)) programming language treats each byte of an invalid UTF-8 bytestream as an error (see also changes with new UTF-8 mode in Python 3.7<ref>{{Cite web |title=PEP 540 – Add a new UTF-8 Mode |url=https://peps.python.org/pep-0540/ |access-date=2025-11-20 |website=Python Enhancement Proposals (PEPs) |language=en}}</ref>); this gives 128 different possible errors. Extensions have been created to allow any byte sequence that is assumed to be UTF-8 to be losslessly transformed to UTF-16 or UTF-32, by translating the 128 possible error bytes to 128 reserved code points, and transforming those code points back to error bytes to output UTF-8. The most common approach is to translate the codes to {{tt|U+DC80}}...{{tt|U+DCFF}} which are low (trailing) surrogate values and thus "invalid" UTF-16, as used by [Python](/source/Python_(programming_language))'s [PEP](/source/Python_Enhancement_Proposal) 383 (or "surrogateescape") approach.<ref name="pep383">{{cite web |last=von Löwis |first=Martin |date=2009-04-22 |title=Non-decodable Bytes in System Character Interfaces |url=https://www.python.org/dev/peps/pep-0383 |access-date=2025-11-20 |publisher=[Python Software Foundation](/source/Python_Software_Foundation) |language=en |id=PEP 383}}</ref> [NumPy](/source/NumPy) version 2.0, and its file formats, support UTF-8 (adding StringDType for it).<ref>{{Cite web |title=NEP 55 – Add a UTF-8 variable-width string DType to NumPy |website=NumPy Enhancement Proposals |url=https://numpy.org/neps/nep-0055-string_dtype.html |access-date=2025-11-20}}</ref> Another encoding called [MirBSD](/source/MirBSD) OPTU-8/16 converts them to {{tt|U+EF80}}...{{tt|U+EFFF}} in a [Private Use Area](/source/Private_Use_Area).<ref>{{cite web |title=RTFM optu8to16(3), optu8to16vis(3) |url=https://www.mirbsd.org/htman/i386/man3/optu8to16.htm |access-date=2025-11-20 |website=MirBSD}}</ref> In either approach, the byte value is encoded in the low eight bits of the output code point. These encodings are needed if invalid UTF-8 is to survive translation to and then back from the UTF-16 used internally by Python, and as Unix filenames can contain invalid UTF-8 it is necessary for this to work.<ref name="davis383">{{cite web |last1=Davis |first1=Mark |author-link1=Mark Davis (Unicode) |last2=Suignard |first2=Michel |year=2014 |title=3.7 Enabling Lossless Conversion |url=https://www.unicode.org/reports/tr36/#EnablingLosslessConversion |access-date=2025-11-20 |work=Unicode Security Considerations |id=Unicode Technical Report #36}}</ref>

Most file systems on [Unix-like](/source/Unix-like) systems can use UTF-8 to encode file names, as looking up file names is done by comparing the bytes of file names. Linux's [ext4](/source/ext4) and macOS's [APFS](/source/Apple_File_System) file systems support case-insensitive file name lookups, which require that the encoding of file names be specified; ext4 supports UTF-8 and uses it by default,<ref>{{cite web |title=Ext4 General Information |website=Linux Kernel documentation |url=https://www.kernel.org/doc/html/latest/admin-guide/ext4.html |access-date=2025-11-20}}</ref> and APFS requires UTF-8.<ref>{{cite web |title=Frequently Asked Questions |url=https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/APFS_Guide/FAQ/FAQ.html |access-date=2025-11-20 |work=Apple File System Guide |publisher=[Apple](/source/Apple_Inc.)}}</ref> Apple's older [HFS Plus](/source/HFS_Plus) uses [UTF-16](/source/UTF-16) for file names, but uses UTF-8 in [symbolic link](/source/symbolic_link)s.<ref>{{cite web |title=Technical Note TN1150: HFS Plus Volume Format |url=https://developer.apple.com/library/archive/technotes/tn/tn1150.html |access-date=2025-11-20 |publisher=[Apple](/source/Apple_Inc.)}}</ref> Windows' filesystem, [NTFS](/source/NTFS), uses UTF-16 for file names.

== Standards ==
The official name for the encoding is {{code|UTF-8}}, the spelling used in all Unicode Consortium documents. The [hyphen-minus](/source/hyphen-minus) is required and no spaces are allowed. Some other names used are:

* Many standards are case-insensitive and {{code|utf-8}} is often used.{{citation needed|date=March 2023}}
* Web standards (which include [CSS](/source/Cascading_Style_Sheets), [HTML](/source/HTML), [XML](/source/XML), and [HTTP headers](/source/HTTP_headers)) also allow {{code|utf8}} and many other aliases<!-- e.g. "unicode20utf8" for UTF-8, likely not useful to list any or all, just stating "many"-->.<ref>{{cite web|url=https://encoding.spec.whatwg.org/#names-and-labels|title=Encoding Standard § 4.2. Names and labels|publisher=[WHATWG](/source/WHATWG)|access-date=2018-04-29}}</ref> HTML documents, however, must have their encoding specified as "an ASCII case-insensitive match for the string 'utf-8{{'"}}.<ref name="html5charset"/>
* The official [Internet Assigned Numbers Authority](/source/Internet_Assigned_Numbers_Authority) lists {{code|csUTF8}} as the only alias,<ref name="IANA_2013_CS">{{cite web |publisher=[Internet Assigned Numbers Authority](/source/Internet_Assigned_Numbers_Authority) |url=https://www.iana.org/assignments/character-sets |title=Character Sets |date=2013-01-23 |access-date=2013-02-08}}</ref> which is rarely used.
* In some locales {{code|UTF-8N}} means UTF-8 ''without'' a [byte-order mark](/source/byte_order_mark) (BOM), and in this case {{code|UTF-8}} ''may'' imply there ''is'' a BOM.<ref>{{cite web |url=https://suika.fam.cx/~wakaba/wiki/sw/n/BOM |title=BOM | work = suikawiki |archive-url=https://web.archive.org/web/20090117052232/https://suika.fam.cx/~wakaba/wiki/sw/n/BOM |archive-date=2009-01-17 |language=ja}}</ref><ref>{{cite web |author-last=Davis |author-first=Mark |author-link=Mark Davis (Unicode) |title=Forms of Unicode |publisher=[IBM](/source/IBM) |url=https://www-128.ibm.com/developerworks/library/utfencodingforms/index.html |access-date=2013-09-18 |archive-url=https://web.archive.org/web/20050506211548/https://www-128.ibm.com/developerworks/library/utfencodingforms/index.html |archive-date=2005-05-06}}</ref>
* In [Windows](/source/Windows), UTF-8 is [codepage](/source/Windows_code_page) {{code|65001}}<ref>{{Cite web |url=https://www.dostips.com/forum/viewtopic.php?t=5357 |title=UTF-8 codepage 65001 in Windows 7 - part I |author=Liviu |quote=Previously under XP (and, unverified, but probably Vista, too) for loops simply did not work while codepage 65001 was active |language=en-gb |date=2014-02-07 |access-date=2018-01-30}}</ref> with the symbolic name {{code|CP_UTF8}} in source code.
* In [MySQL](/source/MySQL), UTF-8 is called {{code|utf8mb4}},<ref>{{Cite web |title=MySQL :: MySQL 8.0 Reference Manual :: 10.9.1 The utf8mb4 Character Set (4-Byte UTF-8 Unicode Encoding) |url=https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8mb4.html |work=MySQL 8.0 Reference Manual |publisher=[Oracle Corporation](/source/Oracle_Corporation) |access-date=2023-03-14}}</ref> while {{code|utf8}} and {{code|utf8mb3}} refer to the obsolete [CESU-8](/source/CESU-8) variant.<ref name="mysql3-utf8mb3">{{Cite web |title=MySQL :: MySQL 8.0 Reference Manual :: 10.9.2 The utf8mb3 Character Set (3-Byte UTF-8 Unicode Encoding) |url=https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8mb3.html |work=MySQL 8.0 Reference Manual |publisher=[Oracle Corporation](/source/Oracle_Corporation) |access-date=2023-02-24}}</ref>
* In [Oracle Database](/source/Oracle_Database), {{code|AL32UTF8}} means UTF-8 (since version 9.0), while {{code|UTF8}} means CESU-8 (since 8.0),<ref>{{Cite web |title=Database Globalization Support Guide |url=https://docs.oracle.com/cd/E11882_01/server.112/e10729/ch6unicode.htm |access-date=2023-03-16 |website=docs.oracle.com |language=en}}</ref> and is not recommended for use.<ref>{{Cite web |last=Hood |first=Doug |date=July 10, 2025 |title=Why the Database Character Set Matters |url=https://blogs.oracle.com/timesten/post/why-databasecharacterset-matters |access-date=2025-11-20 |website=blogs.oracle.com}}</ref>
* In HP [PCL](/source/Printer_Command_Language), the Symbol-ID for UTF-8 is {{code|18N}}.<ref>{{Cite web|url=https://pclhelp.com/pcl-symbol-sets/ |archive-url=https://web.archive.org/web/20150219212843/http://pclhelp.com/pcl-symbol-sets/|url-status=dead|archive-date=2015-02-19|title=HP PCL Symbol Sets {{!}} Printer Control Language (PCL & PXL) Support Blog|date=2015-02-19|access-date=2018-01-30}}</ref>

There are several current definitions of UTF-8 in various standards documents:

* {{IETF RFC|3629|link=no}} / STD 63 (2003), which establishes UTF-8 as a standard internet protocol element
* {{IETF RFC|5198|link=no}} defines UTF-8 [NFC](/source/Unicode_equivalence) for Network Interchange (2008)
* ISO/IEC 10646:2020/Amd 1:2023<!-- §9.1 (2023? or 2020)--><ref>{{Cite web |title=ISO/IEC 10646:2020/Amd 1:2023 |url=https://www.iso.org/standard/83362.html |access-date=2025-11-20 |website=ISO |language=en}}</ref>
* ''The Unicode Standard, Version 17.0.0'' (2025)<!-- <ref>''[https://www.unicode.org/versions/Unicode16.0.0/ The Unicode Standard, Version 16.0]'' [https://www.unicode.org/versions/Unicode15.0.0/ch03.pdf#G31703 §3.9 D92, §3.10 D95], 2021.</ref> -->

They supersede the definitions given in the following obsolete works:

* ''The Unicode Standard, Version 2.0'', Appendix A (1996)
* ISO/IEC 10646-1:1993 Amendment 2 / Annex R (1996)
* {{IETF RFC|2044|link=no}} (1996)
* {{IETF RFC|2279|link=no}} (1998)
* ''The Unicode Standard, Version 3.0'', §2.3 (2000) plus Corrigendum #1 : UTF-8 Shortest Form (2000)
* ''Unicode Standard Annex #27: Unicode 3.1'' (2001)<ref>{{Cite web |title=UAX #27: Unicode 3.1 |url=https://www.unicode.org/reports/tr27/tr27-3.html |access-date=2025-11-20 |website=www.unicode.org}}</ref>
* <!-- Is there a reason to single out 5.0 and 6.0, but not e.g. 15? Skip all after 3.0, since only then encoding of UTF-8 changed? -->''The Unicode Standard, Version 5.0'' (2006)<ref>[https://www.unicode.org/versions/Unicode5.0.0/ ''The Unicode Standard, Version 5.0''] [https://www.unicode.org/versions/Unicode5.0.0/ch03.pdf §3.9–§3.10 ch. 3], 2006.</ref>
* ''The Unicode Standard, Version 6.0'' (2010)<ref name=":1" />

They are all the same in their general mechanics, with the main differences being on issues such as allowed range of code point values and safe handling of invalid input.

== See also ==
* {{annotated link|Character encodings in HTML}}
* {{annotated link|Comparison of Unicode encodings}}
* {{annotated link|GB 18030}}
* {{annotated link|Iconv}}
* {{annotated link|Unicode and email}}
* {{annotated link|Unicode and HTML}}
* {{annotated link|UTF-EBCDIC}}
* {{annotated link|List of Unicode characters}}

== References ==
{{reflist}}

== External links ==
* [https://doc.cat-v.org/plan_9/4th_edition/papers/utf Original UTF-8 paper] ([https://web.archive.org/web/20000917055036/http://plan9.bell-labs.com/sys/doc/utf.pdf or pdf]) for [Plan 9 from Bell Labs](/source/Plan_9_from_Bell_Labs)
* [https://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt History of UTF-8 by Rob Pike]
* {{YouTube|id=MijmeoH9LT4|title=Characters, Symbols and the Unicode Miracle}}

{{Unicode navigation}}
{{Character encoding}}
{{Rob Pike navbox}}
{{Ken Thompson navbox}}

Category:Character encoding
Category:Computer-related introductions in 1993
Category:Encodings
Category:Unicode Transformation Formats

---
Adapted from the Wikipedia article [UTF-8](https://en.wikipedia.org/wiki/UTF-8) by Wikipedia contributors ([contributor history](https://en.wikipedia.org/wiki/UTF-8?action=history)). Available under [Creative Commons Attribution-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-sa/4.0/). Changes may have been made.
