grapheme-splitter

Split JavaScript strings into user-perceived characters, not raw UTF-16 code units

Library
npm
v1.0.4
986stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
34/100Needs Attention
Development Activity0
Maintenance0
Community48
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
73/100Good
Architecture68
Code Quality62
Innovation75
Learning Curve88

grapheme-splitter is a zero-dependency JavaScript library that splits strings into extended grapheme clusters — what a human reader would call individual “letters” — by implementing the Unicode UAX #29 default grapheme cluster boundary algorithm. Plain JavaScript string indexing operates on UTF-16 code units, which cuts multi-byte emoji, combined emoji sequences, and letters with combining marks (accents, Hindi matras, etc.) in the wrong place; grapheme-splitter fixes this with splitGraphemes, iterateGraphemes, and countGraphemes methods that return correct results for these cases.

What You Get

  • A GraphemeSplitter class with splitGraphemes(string) returning an array of individual grapheme clusters
  • iterateGraphemes(string) for iterating grapheme clusters lazily without building a full array upfront
  • countGraphemes(string) for getting an accurate user-perceived character count in a single call
  • Correct handling of multi-codepoint emoji, ZWJ emoji sequences, and combining-mark-heavy scripts like Hindi and Korean Jamo
  • Bundled TypeScript declarations (index.d.ts) for typed usage without extra @types packages

Common Use Cases

  • Enforcing accurate character-count limits (e.g. a tweet-like composer) that shouldn’t split an emoji or accented letter in half
  • Implementing cursor movement or text selection in a custom text editor that must move one visual character at a time
  • Truncating user-generated strings for display (e.g. ...) without cutting a multi-codepoint emoji or diacritic mid-sequence
  • Validating or normalizing internationalized text input where combining marks and pre-composed characters must be treated as equivalent letters

Under The Hood

Architecture The entire implementation lives in one file (index.js, ~115KB) centered on a single GraphemeSplitter class: large generated lookup tables encode Unicode grapheme-break property ranges, and a state-machine-style walk over the input string consults those tables plus a small set of boundary rules (from UAX #29) to decide where to place each grapheme boundary, exposing the result through splitGraphemes/iterateGraphemes/countGraphemes.

Tech Stack Plain JavaScript (ES5-style, no build step) with zero runtime dependencies, bundled hand-written TypeScript declarations (index.d.ts), and a tests/ directory run via the tape test framework as the only devDependency.

Code Quality The public surface is small and the tests directory (tests/grapheme_splitter_tests.js) covers emoji, combining-mark, and multi-script cases drawn directly from the README’s own examples, but the file has not been touched since 2021 (activity_status: inactive) and offers no ES module build, so consumers relying on tree-shaking get the full table regardless of usage.

API Design The API is deliberately minimal — instantiate GraphemeSplitter once, then call one of three methods — with README examples covering exactly the tricky cases (emoji, Hindi, Korean Jamo, pathological combining-mark strings) that justify using the library over Array.from or .length, making the learning curve very low despite the repo’s inactivity.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search