Development Guide
How to contribute and build the library
This guide explains how to set up a local development environment for the ansi-regex library, contribute changes, and build the project from source. Whether you want to fix a bug, add a feature, or simply understand the internals, this page walks you through every step. Following these instructions ensures your contributions are consistent with the project's structure and can be reviewed efficiently.
Before you begin, make sure you have the following in place:
- Node.js — A supported LTS version is recommended. The library targets environments compatible with
'use strict'and ES6+RegExp. - npm (bundled with Node.js) or a compatible package manager such as Yarn.
- Git — Required to clone the repository and manage branches.
- A code editor with JavaScript support (e.g., VS Code).
- Basic familiarity with CommonJS modules (
require/module.exports) and regular expressions.
Follow these steps to get the project running locally:
-
Fork and clone the repository.
git clone https://github.com/your-username/ansi-regex.git cd ansi-regex -
Install dependencies.
npm install -
Verify the setup by running the existing tests.
npm testA passing test suite confirms your environment is configured correctly.
-
Create a feature or fix branch before making changes.
git checkout -b my-feature-branch
The library itself exposes a single factory function with no user-facing configuration options — calling it always produces a consistent, globally-flagged RegExp. However, there are a few environment-level considerations relevant during development:
| Concern | Detail |
|---|---|
| Strict mode | The source file declares 'use strict' at the top. All contributions must remain compatible with strict mode. |
| RegExp flags | The generated pattern is compiled with the g (global) flag. Do not alter this in core logic without understanding downstream effects on stateful regex iteration. |
| Pattern structure | The ANSI escape pattern is split across two array entries and joined with ` |
During development, you will primarily work with the core factory function in index.js. Understanding how it is structured helps you reason about changes before writing them.
The function builds the ANSI escape sequence pattern from two string fragments and joins them with the alternation operator |:
'use strict';
module.exports = () => {
const pattern = [
'[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[a-zA-Z\\d]*)*)?\\u0007)',
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))'
].join('|');
return new RegExp(pattern, 'g');
};
When you modify the regex pattern, test it against both the existing test cases and any new edge cases you are targeting. Because the regex is compiled fresh on every call, you do not need to worry about resetting lastIndex between calls — each invocation returns a new RegExp instance.
To verify your changes interactively during development:
const ansiRegex = require('.');
const regex = ansiRegex();
console.log(regex.test('\u001B[4mUnderline\u001B[0m')); // true
console.log(regex.source); // inspect the compiled pattern
Example 1 — Manually testing the compiled regex during development
const ansiRegex = require('.');
const regex = ansiRegex();
const sample = '\u001B[31mRed text\u001B[0m and plain text';
console.log(regex.test(sample));
Expected output:
true
Example 2 — Extracting all matched escape sequences
const ansiRegex = require('.');
const sample = '\u001B[4mUnderline\u001B[0m and \u001B[31mred\u001B[0m';
const matches = sample.match(ansiRegex());
console.log(matches);
Expected output:
[ '\u001B[4m', '\u001B[0m', '\u001B[31m', '\u001B[0m' ]
Example 3 — Stripping ANSI codes (common use case to validate against)
const ansiRegex = require('.');
const raw = '\u001B[1mBold\u001B[0m';
const stripped = raw.replace(ansiRegex(), '');
console.log(stripped);
Expected output:
Bold
Use this pattern in your tests to confirm that modifications to the regex do not accidentally strip non-ANSI characters or leave partial sequences behind.
Issue: npm test fails immediately after cloning
- Symptom: Running
npm testthrows an error before any tests execute. - Likely cause: Dependencies were not installed, or the Node.js version is incompatible.
- Fix: Run
npm installfirst. Confirm your Node.js version withnode --versionand upgrade to a current LTS release if needed.
Issue: Modified regex matches too aggressively (false positives)
- Symptom: Plain text or partial sequences are incorrectly matched after editing the pattern.
- Likely cause: A quantifier or character class was broadened unintentionally.
- Fix: Review the two pattern fragments in the array individually. Test the modified pattern against both ANSI-containing strings and plain text strings to confirm boundaries are respected.
Issue: lastIndex behaves unexpectedly during testing
- Symptom: Calling
.test()on the same regex instance alternates betweentrueandfalse. - Likely cause: The
gflag causesRegExpto tracklastIndexstate across calls on the same instance. - Fix: Call
ansiRegex()to get a fresh instance for each independent test, or resetregex.lastIndex = 0between calls. This is expected JavaScript behavior, not a bug in the library.
Issue: Changes to index.js are not reflected when requiring the module
- Symptom: Your edits appear to have no effect during manual testing in a Node.js REPL.
- Likely cause: Node.js module caching is serving the previously loaded version.
- Fix: Restart your Node.js process or REPL session after saving changes to
index.js.