A vendorable bundle of strip-ansi with ansi-regex inlined. Useful when you want the package behavior locally without carrying the dependency pair in your app.
Why copy this?
This page ships a source-faithful strip-ansi bundle with ansi-regex inlined. The point is to keep a tiny, inspectable ANSI stripping helper in your repo without installing both packages.
Native alternative: Node.js offers util.stripVTControlCharacters, but teams may still want a vendorable cross-runtime helper with fixed behavior in local code.
Note: This snippet is extracted rather than copied as-is because the published strip-ansi file imports ansi-regex.
This copy is your responsibility once you adopt it. It does not
automatically receive upstream bug fixes or security updates.
Snippet
Copy-first distribution
Project-specific, rule-based variant for easier Node.js and Bun copy-paste use. Not an official upstream distribution.
Keeps the published package shape as-is.
Normalized
ESM / TS / normalized
Runtime: node, bun
/**
* Derived from strip-ansi@7.1.2
* Rule-based normalized variant generated by this repository.
* Preserve the upstream license and attribution notices when copying this file.
*/
/**
* Derived from strip-ansi@7.1.2
* Rule-based normalized variant generated by this repository.
* See THIRD_PARTY_NOTICES.md for upstream license and attribution details.
*/
type AnsiRegexOptions = {
readonly onlyFirst?: boolean;
};
function ansiRegex({ onlyFirst = false }: AnsiRegexOptions = {}): RegExp {
// Valid string terminator sequences are BEL, ESC\, and 0x9c
const ST = "(?:\\u0007|\\u001B\\u005C|\\u009C)";
// OSC sequences only: ESC ] ... ST (non-greedy until the first ST)
const osc = `(?:\\u001B\\][\\s\\S]*?${ST})`;
// CSI and related: ESC/C1, optional intermediates, optional params (supports ; and :) then final byte
const csi = "[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]";
const pattern = `${osc}|${csi}`;
return new RegExp(pattern, onlyFirst ? undefined : "g");
}
const regex = ansiRegex();
export default function stripAnsi(string: string): string {
if (typeof string !== "string") {
throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
}
// Even though the regex is global, we don't need to reset the `.lastIndex`
// because unlike `.exec()` and `.test()`, `.replace()` does it automatically
// and doing it manually has a performance penalty.
return string.replace(regex, "");
}
Variant note: Source-faithful bundle with upstream TypeScript signature folded in for copy-paste into modern TS projects.
Validation: This
normalized variant is intended to stay oxlint and
oxfmt clean in this repo.
Raw
ESM / JS / raw
Runtime: node, bun
function ansiRegex({onlyFirst = false} = {}) {
// Valid string terminator sequences are BEL, ESC\, and 0x9c
const ST = "(?:\\u0007|\\u001B\\u005C|\\u009C)";
// OSC sequences only: ESC ] ... ST (non-greedy until the first ST)
const osc = `(?:\\u001B\\][\\s\\S]*?${ST})`;
// CSI and related: ESC/C1, optional intermediates, optional params (supports ; and :) then final byte
const csi =
"[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]";
const pattern = `${osc}|${csi}`;
return new RegExp(pattern, onlyFirst ? undefined : "g");
}
const regex = ansiRegex();
export default function stripAnsi(string) {
if (typeof string !== "string") {
throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
}
// Even though the regex is global, we don't need to reset the `.lastIndex`
// because unlike `.exec()` and `.test()`, `.replace()` does it automatically
// and doing it manually has a performance penalty.
return string.replace(regex, "");
}
Variant note: Source-faithful extracted bundle from strip-ansi with its ansi-regex dependency inlined into a single ESM file.