Inspect Unicode · browser-local
UTF-8 Byte Counter
Measure the encoded size of text and see why a single visible character can occupy multiple bytes or code points. This is useful for APIs, databases, payloads, and fields whose limits are not human-visible character counts.
- Index state
- eligible
- Reviewed
- 2026-08-24
- Input limit
- 5,000 graphemes
UTF-8 Byte Counter
Good fit
Use this tool when
- An API or database field has a UTF-8 byte limit.
- Emoji make a string larger than expected.
- You need to explain different definitions of character length.
Keep the original
Avoid it when
- The destination limit is explicitly measured in graphemes.
- You need compressed, encrypted, or transport-framed size.
- The target encoding is not UTF-8.
Reviewed truth vectors
Examples that expose the edge cases
A1 byte · 1 code point · 1 graphemeASCII uses one UTF-8 byte.
é2 bytes · 1 code point · 1 graphemeThe precomposed letter needs two UTF-8 bytes.
👨👩👧👦25 bytes · 7 code points · 1 graphemeA visible family emoji is a sequence.
Transparent implementation
How it works
- 01
Encode the string with the browser TextEncoder.
- 02
Segment user-perceived graphemes with Intl.Segmenter.
- 03
Count code points and UTF-16 units separately for comparison.
Known limitations
What the result cannot promise
The count excludes HTTP, JSON escaping, compression, and protocol overhead.
A platform may document characters without defining its counting model.
Ill-formed UTF-16 is replaced during UTF-8 encoding.
Questions before copying
Frequently asked questions
Why is an emoji four bytes?
Most single emoji code points are outside the Basic Multilingual Plane and encode as four UTF-8 bytes.
Why can one grapheme have many bytes?
A grapheme can combine several code points, such as a family emoji joined by zero-width joiners.
Does JSON have the same size?
Not always. Escaping, quotes, property names, and the transport envelope add bytes beyond the text itself.
Experience, expertise & trust
How we verify this tool
Automated evidence
- Tool-contract & coverage suite30 deterministic cases
tests/tools-30.test.mjs mirrors the ToolRunner dispatch and asserts every registered engineId returns the contracted output shape, plus a coverage guard so no tool silently drops characters.
Run in: node --test after a production build (vinext build) - Rendered-HTML suite12 deterministic cases
tests/rendered-html.test.mjs renders the deployed server bundle and asserts the Unicode-version manifest and each wave's tool markup are present in the server-rendered HTML.
Run in: node --test against the built dist/server bundle - Unicode inspection suite11 deterministic cases
tests/unicode-inspection.test.mjs verifies grapheme/code-point/byte counting and hidden-control detection using explicit \u escapes for combining and bidirectional characters.
Run in: node --test against the runtime's Unicode data - Compatibility risk suite13 deterministic cases
tests/compatibility.test.mjs checks that bidirectional controls, invisible characters, mixed scripts, and NFKC-changing input raise the documented risk status, and that safe-text stripping preserves ordinary content.
Run in: node --test, deterministic analyzer
Standards this tool follows
- UTS #39: Unicode Security Mechanisms
Confusable and mixed-script detection methodology.
- UAX #9: Unicode Bidirectional Algorithm
Bidirectional control characters flagged during inspection.
- UAX #15: Unicode Normalization Forms
NFC/NFKC normalization comparisons.
- RFC 3629: UTF-8
Byte-length counting for the UTF-8 encoding.