All free skills / Other majors
string-width 8.x
Use string-width ^8.0.0 to calculate the terminal column width of strings, including Unicode, emoji, ANSI escape codes, ambiguous-width characters, tabs, and non-printing grapheme clusters.
- For
string-width@8.2.2- Verified
- 2026-09-08, 4 examples executed
- Skill package
@modootoday/pmcp-string-width@8.0.0
Use this skill for free
No PMCP login or subscription is required. Download the original instructions, or install the content-only archive with your project's package manager.
Download SKILL.md · Download package archive
npm install --save-dev https://pmcp.build/skills/string-width/8/package.tgz
PMCP discovers the installed package's instructions. Connect your runtime after installation.
Archive integrity
sha512-gQEzUcshCZP6PpyDdlXyGS3M8qxQwesMTQxVY45iefKD8YDKHN//okJnuO9Hs3VbCWlbY3H6y3CPjJaPDkgF4w==Complete instructions
Verified against string-width@8.2.2 on 2026-09-08. 4 of 4 examples executed.
string-width
Runtime and module shape
- This is an ESM package and requires Node.js
>=20. - Import the default export:
import stringWidth from 'string-width';
- The v8 API is
stringWidth(string, options?)and returns a number. - Do not use the older/common
require('string-width')shape. v8 exposes a default ESM export. - This package is a standalone function: it does not require a test runner, CLI, framework globals, or a build step.
Basic width calculation
The result is the number of terminal columns needed to display the string.
- Ordinary characters generally count as one column.
- Fullwidth characters such as
古count as two columns. - ANSI escape codes do not affect the result by default.
- Tabs are ignored by design rather than expanded to a tab-stop width.
- Non-printing grapheme clusters do not contribute to the width.
import assert from 'node:assert/strict';
import stringWidth from 'string-width';
assert.equal(stringWidth('a'), 1);
assert.equal(stringWidth('hello'), 5);
assert.equal(stringWidth('古'), 2);
assert.equal(stringWidth('古a'), 3);
assert.equal(stringWidth('\t'), 0);
assert.equal(stringWidth('\n'), 0);
Options
ambiguousIsNarrow
ambiguousIsNarrow defaults to true. With the default, East Asian Ambiguous characters count as one column. Set it to false to count them as wide.
The middle dot · is an example of an ambiguous-width character:
import assert from 'node:assert/strict';
import stringWidth from 'string-width';
assert.equal(stringWidth('·'), 1);
assert.equal(stringWidth('·', {ambiguousIsNarrow: true}), 1);
assert.equal(stringWidth('·', {ambiguousIsNarrow: false}), 2);
countAnsiEscapeCodes
ANSI escape codes are excluded by default. Set countAnsiEscapeCodes: true when those codes should contribute to the returned width.
import assert from 'node:assert/strict';
import stringWidth from 'string-width';
const styled = '\u001B[1m古\u001B[22m';
assert.equal(stringWidth(styled), 2);
assert.ok(stringWidth(styled, {countAnsiEscapeCodes: true}) > stringWidth(styled));
Unicode and grapheme behavior
The v8 implementation segments grapheme clusters and applies emoji-specific width rules before East Asian Width handling. A displayed emoji such as 😀 occupies two columns:
import assert from 'node:assert/strict';
import stringWidth from 'string-width';
assert.equal(stringWidth('😀'), 2);
assert.equal(stringWidth('a😀古'), 5);
This means do not calculate width by simply using JavaScript string.length: surrogate pairs, combined graphemes, emoji, fullwidth characters, and control sequences do not map directly to terminal columns.
Common mistakes
- Using
require: v8 is ESM-only in its documented package shape. Use a defaultimportand run under a Node version satisfying>=20. - Treating
string.lengthas display width: usestringWidthbecause fullwidth Unicode characters and emoji can occupy two columns, while controls and ANSI sequences may occupy none. - Assuming ANSI styling changes visual width: ANSI escape codes are ignored by default. Pass
countAnsiEscapeCodes: trueonly when the escape-code characters themselves should be included. - Assuming ambiguous characters are always wide: the default is narrow (
ambiguousIsNarrow: true). Set it tofalsefor wide treatment. - Expecting tabs to expand to tab stops: tabs are ignored by this implementation.
- Copying the v6 dependency/runtime assumptions: v8 requires Node
>=20and uses the v8 ESM export shape. The older v6 package supported Node>=16, which is not the v8 requirement.
Not covered
This skill does not cover terminal-specific rendering differences, custom tab-stop calculations, layout or padding APIs, ANSI code generation, or behavior outside the documented v8 options and string-width calculation.