String length

Count text five ways at once: characters as you see them, Unicode code points (Python's len()), UTF-16 units (JavaScript's .length), words and lines.

Input
Characters
0
Code points
0
UTF-16 units
0
Words
0
Lines
0

Why "how long is this string?" has more than one answer

It sounds like a trivial question, but the length of a piece of text depends entirely on what you are counting. A person counts the characters they can see. A database counts the storage a value takes. JavaScript counts something different again. When these numbers disagree — and they often do for emoji, accented letters and non-Latin scripts — a single "length" is misleading. This tool shows five meaningful measures side by side so you can pick the one that matters for your situation.

The five metrics explained

  • Characters (graphemes): what a human perceives as one character. An emoji family like 👨‍👩‍👧, or a letter with a combining accent, counts as one — this is the count that matches "by eye".
  • Code points: the number of Unicode scalar values. A single visible character can be built from several code points joined together, so this number is often higher than the grapheme count.
  • UTF-16 units: the value JavaScript reports from a string's .length property. Characters outside the Basic Multilingual Plane (most emoji) take two UTF-16 units each.
  • Words: the number of word-like tokens, detected in a Unicode-aware way rather than by naively splitting on spaces.
  • Lines: the number of lines, counting every line break.

Why emoji and accents break naïve counting

Modern text is built from Unicode, which represents many visible characters as sequences rather than single units. A flag emoji is two regional-indicator symbols. A family emoji is several people joined by invisible "zero-width joiner" characters. An accented é can be a single code point or a plain e followed by a combining accent. Each of these looks like one character but can count as two, three or more depending on the metric. That is exactly why counting by hand, or trusting one number, leads to bugs.

Which count should you use?

  • Character limits people see (a bio, a tweet-style field, an SMS preview): use Characters (graphemes), because that matches what the user counts.
  • JavaScript string handling, array indexing or slicing: use UTF-16 units, since that is what .length and string indices are based on.
  • Database column sizes: check whether your column is measured in characters or bytes — many are byte-limited, and UTF-8 bytes differ again from all of these counts.
  • Word or line counts for editors and readability: use the Words and Lines metrics.

What Python and JavaScript each call the length

Two of the five counts above are the ones people arrive here looking for, and they belong to different languages. Python's len() and JavaScript's .length are both described as the length of a string, and on anything past plain ASCII they answer differently for the same text at the same moment. Neither is wrong: they count different units, and the boxes above show both, so the gap is something you can read rather than guess at.

  • Python: len() returns the number of Unicode code points, because a string in Python 3 is a sequence of code points. Read the Code points box — that is the number len() gives you.
  • JavaScript: .length returns the number of UTF-16 code units, because a JavaScript string is held as UTF-16. Read the UTF-16 units box. Array.from(text).length walks the string by code point instead, so it agrees with Python.
  • Neither of them counts what you see. The Characters box is the grapheme count, and no built-in length in either language produces it: JavaScript needs Intl.Segmenter and Python needs a third-party package. If the limit you are enforcing is one a person will read, that is the box to use.
  • Words and Lines belong to neither language either. Both can approximate them by splitting on whitespace and on line breaks, and both drift from the counts here, which are Unicode-aware — on text written without spaces, on punctuation, and on a line break that ends the text.

The example behind Load example is the quickest way to see the gap. Its family emoji is one character to a reader, five code points to Python and eight UTF-16 units to JavaScript: three of those five code points sit outside the Basic Multilingual Plane and cost two units each, and the two invisible joiners between them cost one each. So a field that lets someone write twenty characters really does hold twenty by eye, while a naive check written in either language rejects text that fits.

Length is not size in bytes

None of the five counts above is a byte count, and the two are easy to conflate. A count is a property of the text itself; a size in bytes is a property of the text once it has been written down in some encoding, so the same string has one size in UTF-8 and a different one in UTF-16. Anything measured in bytes therefore has to be measured after encoding, and which encoding was chosen is part of the answer.

  • UTF-8 is what almost everything uses, and it is variable-width: an ASCII letter, digit or punctuation mark is one byte, most accented and non-Latin characters are two or three, and many emoji are four. A hundred characters is a hundred bytes only when every one of them is ASCII — the same hundred characters of Greek, Hebrew, Arabic or Chinese come to two to three times that.
  • Python: len() counts code points, so encode before you measure. len(text.encode('utf-8')) is the number of UTF-8 bytes, and naming a different codec there gives a different number, which is exactly the point.
  • JavaScript: .length counts UTF-16 units, so it is not a byte count either. new TextEncoder().encode(text).length is the UTF-8 byte count, in the browser and in Node alike, and TextEncoder only ever produces UTF-8, so there is no codec to name.
  • Check which unit your limit is written in before you count anything. Some database engines declare a column in characters and others in bytes, an HTTP header value and a file size are bytes, and a rule written for people is what the Characters box shows. Everything measured in characters is already above; everything measured in bytes needs an encoded length.

Once you have a byte count, the Byte size converter is where to take it further: it turns a raw number of bytes into both unit systems at once — the one built on powers of a thousand and the one built on powers of two — and shows how the tools on your machine will each report the same size. This page stops where the encoding begins; that one starts from a number of bytes.

Frequently asked questions

Which count matches JavaScript's string length?
The UTF-16 units value matches the raw .length property in JavaScript. If your code slices or indexes strings, this is the number that governs its behaviour.
Why does one emoji count as several characters?
Many emoji are composed of several Unicode code points joined together. As a grapheme (what you see) it is one character, but its code point and UTF-16 counts are higher, which is why each measure is shown separately.
Does it count trailing spaces and newlines?
Yes. Every character you paste is counted, including leading and trailing whitespace and line breaks. If your totals look higher than expected, check for invisible trailing whitespace.
Is my text sent anywhere?
No. All counting happens in your browser. The text you type or paste never leaves your device.
What is a grapheme?
A grapheme, or "grapheme cluster", is a user-perceived character — the smallest unit a reader would call a single character, even if it is built from several underlying code points.
How are bytes different from these counts?
Bytes depend on the encoding. In UTF-8, an ASCII letter is one byte, most accented and non-Latin characters are two or three, and many emoji are four. None of the five metrics here is a byte count, so for byte-limited fields you should encode to UTF-8 first.

Related tools

  • Byte size converter

    None of the counts here is a size in bytes — a size exists only once the text has been encoded. Once you have that number, that page reads it in decimal and binary units side by side and says what each operating system will call it.

  • Regex tester

    Test regular expressions — match, replace, split.

  • Text diff

    Compare two texts — every changed line and word.

  • Unicode character inspector

    See exactly which characters a string is made of.