or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-string-width

Get the visual width of a string - the number of columns required to display it in terminals

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/string-width@8.1.x

To install, run

npx @tessl/cli install tessl/npm-string-width@8.1.0

0

# String Width

1

2

String Width is a JavaScript utility library that calculates the visual width of strings in terminal applications. It accurately accounts for Unicode characters that display at different widths, including fullwidth CJK characters, ANSI escape codes, and emoji sequences, making it essential for CLI tools and terminal applications that need proper text alignment.

3

4

## Package Information

5

6

- **Package Name**: string-width

7

- **Package Type**: npm

8

- **Language**: JavaScript (ES modules) with TypeScript definitions

9

- **Installation**: `npm install string-width`

10

11

## Core Imports

12

13

```javascript

14

import stringWidth from 'string-width';

15

```

16

17

For TypeScript with type imports:

18

19

```typescript

20

import stringWidth, { type Options } from 'string-width';

21

```

22

23

## Basic Usage

24

25

```javascript

26

import stringWidth from 'string-width';

27

28

// Basic ASCII string

29

stringWidth('hello world');

30

//=> 11

31

32

// Fullwidth CJK characters (display as 2 columns each)

33

stringWidth('古');

34

//=> 2

35

36

// Mixed content

37

stringWidth('hello世界');

38

//=> 9 (hello=5, 世=2, 界=2)

39

40

// ANSI escape codes are stripped by default

41

stringWidth('\u001B[1m古\u001B[22m');

42

//=> 2

43

44

// With options

45

stringWidth('±', { ambiguousIsNarrow: false });

46

//=> 2 (ambiguous character treated as wide)

47

```

48

49

## Capabilities

50

51

### Visual Width Calculation

52

53

Calculates the visual width of a string - the number of columns required to display it in a terminal.

54

55

```javascript { .api }

56

/**

57

* Get the visual width of a string - the number of columns required to display it

58

* @param string - The string to measure

59

* @param options - Configuration options

60

* @returns The visual width in columns

61

*/

62

function stringWidth(string: string, options?: Options): number;

63

```

64

65

The function handles:

66

- **ASCII characters**: Standard single-width characters (width = 1)

67

- **Fullwidth characters**: CJK characters, fullwidth forms (width = 2)

68

- **Zero-width characters**: Control characters, marks, default ignorable (width = 0)

69

- **Emoji sequences**: RGI emoji clusters (width = 2)

70

- **ANSI escape codes**: Stripped by default unless configured otherwise

71

- **Ambiguous characters**: Configurable treatment as narrow (1) or wide (2)

72

- **Grapheme clusters**: Proper segmentation using Intl.Segmenter

73

- **Halfwidth forms**: Correct handling of Japanese dakuten/handakuten marks

74

75

**Usage Examples:**

76

77

```javascript

78

import stringWidth from 'string-width';

79

80

// Edge cases and special characters

81

stringWidth(''); // => 0 (empty string)

82

stringWidth('\t'); // => 0 (tab ignored by design)

83

stringWidth('a\tb'); // => 2 (tab doesn't count)

84

stringWidth('\n'); // => 0 (newline is control char)

85

stringWidth('你好'); // => 4 (2 chars × 2 width each)

86

stringWidth('バ'); // => 2 (halfwidth + dakuten)

87

stringWidth('👨‍👩‍👧‍👦'); // => 2 (family emoji sequence)

88

stringWidth('🇺🇸'); // => 2 (flag emoji sequence)

89

stringWidth('👋🏽'); // => 2 (emoji with skin tone)

90

91

// Zero-width and combining characters

92

stringWidth('e\u0301'); // => 1 (combining diacritical mark)

93

stringWidth('\u200B'); // => 0 (zero-width space)

94

stringWidth('\u200C'); // => 0 (zero-width non-joiner)

95

stringWidth('\u200D'); // => 0 (zero-width joiner)

96

97

// Non-string inputs return 0

98

stringWidth(123); // => 0

99

stringWidth(null); // => 0

100

stringWidth(undefined); // => 0

101

102

// ANSI escape codes

103

const redText = '\u001B[31mRed\u001B[0m';

104

stringWidth(redText); // => 3 (ANSI codes stripped)

105

stringWidth(redText, { countAnsiEscapeCodes: true }); // => 11 (codes counted)

106

107

// Ambiguous characters

108

stringWidth('±§©®'); // => 4 (treated as narrow by default)

109

stringWidth('±§©®', { ambiguousIsNarrow: false }); // => 8 (treated as wide)

110

```

111

112

## Options

113

114

Configuration options for controlling width calculation behavior.

115

116

```typescript { .api }

117

interface Options {

118

/**

119

* Count ambiguous width characters as having narrow width (count of 1)

120

* instead of wide width (count of 2).

121

*

122

* Ambiguous characters behave like wide or narrow characters depending

123

* on context. If context cannot be established reliably, they should

124

* be treated as narrow characters by default.

125

*

126

* @default true

127

*/

128

readonly ambiguousIsNarrow?: boolean;

129

130

/**

131

* Whether ANSI escape codes should be counted towards the width.

132

* By default, ANSI codes are stripped and don't affect width calculation.

133

*

134

* @default false

135

*/

136

readonly countAnsiEscapeCodes?: boolean;

137

}

138

```

139

140

**Option Examples:**

141

142

```javascript

143

import stringWidth from 'string-width';

144

145

// Ambiguous character handling

146

const ambiguous = '±';

147

stringWidth(ambiguous); // => 1 (narrow)

148

stringWidth(ambiguous, { ambiguousIsNarrow: false }); // => 2 (wide)

149

150

// ANSI escape code handling

151

const colored = '\u001B[31mHello\u001B[0m';

152

stringWidth(colored); // => 5 (codes stripped)

153

stringWidth(colored, { countAnsiEscapeCodes: true }); // => 13 (codes counted)

154

155

// Combined options

156

stringWidth('±\u001B[31mTest\u001B[0m', {

157

ambiguousIsNarrow: false,

158

countAnsiEscapeCodes: true

159

}); // => 14 (± as wide + ANSI codes counted + Test)

160

```