Development Guide
How to contribute and build the library
This guide explains how to set up a local development environment for the Chalk library, run the test suite, and submit contributions. Whether you want to fix a bug, add a feature, or improve documentation, this page walks you through everything you need to get started. Following these steps ensures your changes are consistent with the project's conventions and pass CI before review.
Before you begin, make sure you have the following installed and configured:
- Node.js — Use the latest LTS release (check the project's
package.jsonenginesfield for the minimum supported version) - npm — Comes bundled with Node.js; used for installing dependencies and running scripts
- Git — Required to clone the repository and manage branches
- A GitHub account — Required to fork the repository and open pull requests
- Familiarity with the Chalk public API — Review the usage documentation before making changes so you understand what you are modifying
Note: Chalk is an ES module. Your local Node.js version must support native ESM (
import/exportsyntax) to build and test the library correctly.
Follow these steps to get a local copy of Chalk ready for development.
-
Fork the repository on GitHub so you have your own copy to push changes to.
-
Clone your fork to your local machine:
git clone https://github.com/<your-username>/chalk.git cd chalk -
Add the upstream remote so you can pull future changes from the official repository:
git remote add upstream https://github.com/chalk/chalk.git -
Install dependencies using npm:
npm install -
Verify the setup by running the test suite:
npm testAll tests should pass on a clean checkout. If any fail before you make changes, check that your Node.js version meets the minimum requirement and that the install completed without errors.
-
Create a feature branch before making any changes:
git checkout -b fix/my-bug-description
Chalk's development workflow is controlled through the scripts and settings in package.json. Understanding these options helps you run only the checks you need during active development.
| Setting / Script | Default / Value | Effect |
|---|---|---|
npm test | Runs the full test suite | Executes all unit tests using the project's test runner and reports results |
npm run lint | Uses the project's ESLint config | Checks source files for style and correctness issues; failures block CI |
chalk.level (runtime) | Auto-detected (0–3) | Controls the color depth used when the library is imported; useful when writing integration tests that assert on color output |
Color level during testing
When writing tests that assert on the exact string output of Chalk, you should explicitly set chalk.level to a known value so the output is deterministic regardless of the CI environment's terminal capabilities:
import chalk from './source/index.js';
chalk.level = 1; // Force basic ANSI colors for predictable test output
Valid levels are:
0— Disable all styling (plain text)1— Basic 16-color ANSI2— 256-color support3— Truecolor (16 million colors)
Setting the level to 0 is especially useful when testing that fallback or plain-text paths work correctly.
Once your environment is set up, the typical development loop involves editing source files, running tests, and linting before committing.
Running tests in watch mode
If the project's test runner supports watch mode, use it during active development to get instant feedback as you edit files:
npm test -- --watch
Running a single test file
To focus on a specific area without running the full suite:
npm test -- test/chalk.js
Linting before committing
Run the linter to catch style issues before pushing your branch:
npm run lint
Importing from source during development
When writing new tests or experimenting locally, import directly from the source directory rather than a compiled output, since Chalk ships ESM source directly:
import chalk from './source/index.js';
console.log(chalk.green('Local development build working!'));
Keeping your fork up to date
Regularly sync your fork with the upstream repository to avoid merge conflicts:
git fetch upstream
git merge upstream/main
The following examples demonstrate common scenarios you will encounter while developing and testing Chalk.
Verifying a basic style in a test
This pattern checks that Chalk wraps a string with the correct ANSI escape codes at a known color level.
import chalk from './source/index.js';
chalk.level = 1;
const result = chalk.red('error');
console.log(result);
// Expected output (raw bytes): \u001B[31merror\u001B[39m
Expected console output:
error (rendered in red in a color-capable terminal)
Testing a chained style
Chaining verifies that multiple ANSI codes are combined correctly:
import chalk from './source/index.js';
chalk.level = 1;
const result = chalk.bold.underline('heading');
console.log(result);
// Expected: bold + underline escape sequences wrapping "heading"
Expected console output:
heading (bold and underlined in a supporting terminal)
Asserting that level 0 strips all styles
This is useful for confirming that plain-text fallback paths work correctly:
import chalk from './source/index.js';
chalk.level = 0;
const result = chalk.bold.red('no styling');
console.log(result === 'no styling'); // true
Expected output:
true
Testing template literal usage
Chalk supports tagged or inline template literals; verify they produce the same output as method calls:
import chalk from './source/index.js';
chalk.level = 3;
const name = 'world';
console.log(chalk.cyan(`Hello, ${name}!`));
// Expected: "Hello, world!" styled in cyan
Expected console output:
Hello, world! (cyan text)
Use this section when something goes wrong during setup, testing, or development.
Tests fail immediately after cloning
- Symptom: Running
npm testright afternpm installproduces test failures or import errors. - Likely cause: Your Node.js version does not support ES modules natively, or dependencies were not installed correctly.
- Fix: Run
node --versionand confirm it meets the minimum LTS requirement. Deletenode_modulesand rerunnpm install. If the error mentions ESM syntax, upgrade Node.js.
chalk.level is 0 and all output is unstyled
- Symptom: Chalk returns plain strings with no ANSI codes in your local scripts or tests.
- Likely cause: The terminal or CI environment reports no color support, so Chalk auto-detects level
0. - Fix: Explicitly set
chalk.level = 1(or higher) at the top of your test or script file to override auto-detection.
Linting fails with Parsing error on source files
- Symptom:
npm run lintreports parsing errors even though the code runs fine. - Likely cause: ESLint is not configured for ES module syntax, or the wrong Node.js version is active.
- Fix: Confirm that
.eslintrcor the ESLint config inpackage.jsonsets the parser options forsourceType: 'module'. Ensure you are using the same Node.js version used by the project.
Changes to source files are not reflected when running tests
- Symptom: Editing a source file does not change test output.
- Likely cause: You may be importing from a cached or incorrect path (e.g., a previously installed global version).
- Fix: Confirm your test files import from
./source/index.jsor the path specified in the project'sexportsfield inpackage.json, not fromnode_modules/chalk.
Pull request CI fails but local tests pass
- Symptom: All tests pass on your machine but the CI pipeline reports failures.
- Likely cause: The CI environment runs tests against multiple Node.js versions, or the color level is detected differently in a headless environment.
- Fix: Check the CI configuration (e.g.,
.github/workflows) to see which Node.js versions are tested. Reproduce the failure locally by switching to that version with a version manager such asnvm. For color-level issues, ensure tests do not rely on auto-detected levels.