Get the real length of a string by correctly counting astral symbols and ignoring ANSI escape codes
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
String Length provides accurate string length calculation by correctly counting Unicode astral symbols (like emojis) as single characters and optionally ignoring ANSI escape codes. Unlike JavaScript's native String#length which erroneously counts astral symbols as multiple characters, this library uses the modern Intl.Segmenter API for precise Unicode grapheme cluster segmentation.
npm install string-lengthimport stringLength from "string-length";For TypeScript:
import stringLength from "string-length";
import type { Options } from "string-length";Note: This is an ES module only package. For CommonJS environments, use dynamic import:
const { default: stringLength } = await import("string-length");import stringLength from "string-length";
// Standard JavaScript string length vs string-length
'🐴'.length; // 2 (incorrect - counts UTF-16 code units)
stringLength('🐴'); // 1 (correct - counts visual character)
// ANSI escape codes are ignored by default
stringLength('\u001B[1municorn\u001B[22m'); // 7 (ignores ANSI codes)
// Complex Unicode sequences (emoji with skin tone modifiers)
stringLength('👊🏽'); // 1 (correct - single visual character)Calculates the real visual length of a string by properly handling Unicode characters and ANSI escape codes.
/**
* Get the real length of a string by correctly counting astral symbols and ignoring ANSI escape codes
* @param string - The input string to measure
* @param options - Configuration options
* @returns The visual character count
*/
export default function stringLength(string: string, options?: Options): number;Usage Examples:
import stringLength from "string-length";
// Unicode astral symbols (emojis, mathematical symbols)
stringLength('🐴'); // 1
stringLength('𠀔'); // 1 (CJK ideograph)
stringLength('foo𠁐bar𠀃'); // 8
stringLength('🏴❤️谢👪'); // 4 (complex emoji sequence)
// ANSI escape codes handling
stringLength('\u001B[1mfoo\u001B[22m'); // 3 (ignores ANSI by default)
stringLength('\u001B[1mfoo\u001B[22m', {
countAnsiEscapeCodes: true
}); // 12 (includes ANSI codes)
// Empty strings
stringLength(''); // 0
stringLength('\u001B[1m\u001B[22m'); // 0 (only ANSI codes)
// Complex Unicode with modifiers
stringLength('👩👧👦'); // 1 (family emoji)
stringLength('❤️'); // 1 (heart with variation selector)export type Options = {
/**
* Whether ANSI escape codes should be counted. They are ignored by default.
* @default false
*/
readonly countAnsiEscapeCodes?: boolean;
};Intl.Segmenter() for Unicode-aware string segmentationstrip-ansi package for ANSI escape code removalIntl.Segmenter supportThe function handles edge cases gracefully:
countAnsiEscapeCodes is false)Intl.Segmenter implementation