BeautifulCLITerminal string styling done right — a chainable, zero-dependency library for adding color and style to Node.js CLI output.
Guide

Development Guide

How to contribute and build the library


Overview

This page explains how to contribute to BeautifulCLI — the combined toolkit that includes chalk for terminal styling and degit for project scaffolding. You will find everything you need to set up a local development environment, build the library, and submit quality contributions. Following these guidelines helps maintainers review and merge your work efficiently and keeps the project healthy for everyone.


Prerequisites

Before contributing, make sure you have the following installed and configured:

  • Node.js ≥ 8.0.0
  • npm (bundled with Node.js)
  • git — required to clone the repository and submit pull requests
  • A working terminal with a shell that supports standard UNIX commands
  • Familiarity with Node.js module authoring and ES module syntax (the codebase uses import/export)

You should also read and agree to the Contributor Covenant Code of Conduct before participating.


Installation

Follow these steps to set up the BeautifulCLI repository locally.

  1. Fork and clone the repository

    git clone https://github.com/<your-username>/beautifulcli.git
    cd beautifulcli
    
  2. Install all dependencies

    npm install
    
  3. Build the degit bundle

    The degit component uses Rollup to produce a CommonJS distribution in dist/. After editing source files under src/, rebuild with:

    npx rollup --config members/degit/rollup.config.js
    

    Rollup bundles two entry points — src/index.js (the programmatic API) and src/bin.js (the CLI binary) — into dist/index.js and dist/bin.js respectively, with source maps.

  4. Verify your setup

    Run the benchmark suite to confirm chalk is wired up correctly:

    node benchmark.js
    

    You should see timing output for each style combination (1 style, 2 styles, 3 styles, cached variants, and template literal usage).


Configuration

Most build-time behaviour is controlled by the Rollup configuration in members/degit/rollup.config.js. The key options and their effects are described below.

OptionDefaultEffect
input.indexsrc/index.jsEntry point for the programmatic API that consumers import from degit.
input.binsrc/bin.jsEntry point for the degit CLI binary.
output.dirdistDirectory where compiled files are written. Do not commit the dist/ folder; it is generated on release.
output.formatcjsOutput module format. CommonJS is used for broadest Node.js compatibility.
output.sourcemaptrueEmits .js.map files alongside each bundle so stack traces point to original source lines. Change to false only when debugging bundle size.
output.exportsautoLets Rollup decide between named and default exports automatically.
externalAll dependencies + Node.js built-insPackages listed in package.json dependencies and all Node.js built-in modules are excluded from the bundle and expected to be present at runtime.

For the chalk component, there is no separate build step — chalk ships its source directly as ES modules. No additional configuration is required.


Usage

Writing and testing chalk changes

Chalk's API is entirely contained in index.js. When you modify a style, color, or chaining behaviour, validate your change by writing a small script that exercises the affected code path:

import chalk from './index.js';

// Test a single style
console.log(chalk.red('Changed style'));

// Test chaining
console.log(chalk.bold.blue.bgWhite('Chained styles'));

// Test 256-color and RGB
console.log(chalk.ansi256(196)('256-color red'));
console.log(chalk.rgb(255, 136, 0)('RGB orange'));

Run the script with:

node my-test.js

Benchmarking chalk changes

If your change touches the hot path (style resolution or ANSI code generation), run the benchmark before and after to check for regressions:

node benchmark.js

The benchmark covers the most common patterns: single styles, chained styles (2–3 modifiers), cached style instances, strings with embedded newlines, nested styles, and template literal usage.

Building and testing degit changes

After editing files under src/, rebuild the dist bundle:

npx rollup --config members/degit/rollup.config.js

Then test the CLI directly from the built output:

node dist/bin.js user/repo my-output-dir

Or exercise the programmatic API:

import degit from './dist/index.js';

const emitter = degit('user/repo', { cache: false, verbose: true });
await emitter.clone('my-output-dir');

Submitting a pull request

  1. Create a feature branch: git checkout -b feat/my-improvement
  2. Make your changes and rebuild as needed.
  3. Commit with a clear message describing what and why.
  4. Push and open a pull request against the main branch.

Examples

Example 1 — Running the chalk benchmark to establish a performance baseline

node benchmark.js

Expected output (timings will vary by machine):

chalk
  1 style           .............. 1,234,567 ops/sec
  2 styles          ..............   987,654 ops/sec
  3 styles          ..............   876,543 ops/sec
  cached: 1 style   .............. 2,345,678 ops/sec
  ...

Use these numbers as a reference. If a pull request causes a measurable drop in ops/sec for cached or single-style cases, investigate before merging.


Example 2 — Building the degit bundle with Rollup and verifying the output

npx rollup --config members/degit/rollup.config.js
ls dist/

Expected output:

bin.js        bin.js.map
index.js      index.js.map

The two .map files confirm source maps were emitted. If they are missing, check that output.sourcemap is true in members/degit/rollup.config.js.


Example 3 — Manually verifying a chalk style change

// verify-style.js
import chalk from './index.js';

console.log(chalk.green('✔ Success'));
console.log(chalk.bold.red('✖ Error'));
console.log(chalk.blue.bgWhite.underline('ℹ Info'));
node verify-style.js

Expected terminal output: three lines of styled text — a green success message, a bold red error, and a blue underlined info message on a white background.


Example 4 — Smoke-testing the rebuilt degit CLI

node dist/bin.js tiged/tiged test-output --verbose
ls test-output/

Expected: the repository files appear in test-output/ with no .git directory present, confirming that history was stripped and only a snapshot was downloaded.


Troubleshooting

Issue: rollup command not found after npm install

  • Symptom: Running npx rollup --config members/degit/rollup.config.js outputs command not found or Cannot find module.
  • Cause: Rollup and its plugins are declared as dev dependencies. If npm install was skipped or failed, the local binary is missing.
  • Fix: Run npm install from the repository root, then retry the Rollup command.

Issue: dist/ files are stale or missing after editing src/

  • Symptom: Changes to src/index.js or src/bin.js are not reflected when running node dist/index.js or node dist/bin.js.
  • Cause: The dist/ folder is not rebuilt automatically; it requires an explicit Rollup invocation.
  • Fix: Always run npx rollup --config members/degit/rollup.config.js after editing source files before testing the built output.

Issue: benchmark.js fails with a syntax or import error

  • Symptom: Running node benchmark.js throws SyntaxError: Cannot use import statement or similar.
  • Cause: The benchmark uses ES module import syntax. Node.js requires either a .mjs extension or "type": "module" in package.json to treat .js files as ES modules.
  • Fix: Run with a Node.js version ≥ 8.0.0 and confirm package.json includes "type": "module". Do not rename benchmark.js to work around this — fix the project configuration instead.

Issue: Chalk produces no color output in the terminal during development

  • Symptom: Styled strings print as plain text with no ANSI codes.
  • Cause: Chalk automatically disables color when it detects that the output is not a TTY (for example, when output is piped), or when the NO_COLOR environment variable is set.
  • Fix: Run your script directly in a terminal rather than piping output. If you need to force colors for testing purposes, you can check chalk's color-level detection behavior, but do not hard-code ANSI escape codes manually — let chalk manage them.

Issue: Rollup emits warnings about missing named exports

  • Symptom: During the build you see (!) Missing exports or Mixing named and default exports warnings.
  • Cause: The output.exports: 'auto' setting infers export style. If src/index.js mixes default and named exports inconsistently, Rollup may warn.
  • Fix: Ensure src/index.js uses a single consistent export style. If the module has one primary export, use export default. Do not change output.exports to suppress the warning without fixing the underlying inconsistency.