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

Basic Usage

Minimal code example to get started


Overview

This page walks you through the minimum setup needed to start using BeautifulCLI's two core tools: degit for scaffolding new projects from git repository templates, and chalk for styling terminal output with colors and text formatting. By the end of this guide you will have both tools installed, a new project scaffolded from a remote template, and your first styled console output running in Node.js. Whether you are bootstrapping a new application or adding polished CLI output to an existing script, this is the right place to start.


Prerequisites

Before you begin, make sure you have the following installed:

  • Node.js ≥ 8.0.0 — required by both degit and chalk
  • npm — used to install both packages
  • git — optional; only required if you use --mode=git for private repository access (the default tar mode does not need git)

To verify your Node.js version, run:

node --version

Installation
  1. Install degit globally so the degit command is available anywhere in your terminal:

    npm install -g degit
    
  2. Install chalk as a dependency in your Node.js project:

    npm install chalk
    

    Note: Chalk 5 is ESM-only. If your project uses CommonJS (require) or a TypeScript build tool, install Chalk 4 instead:

    npm install chalk@4
    
  3. Verify the degit installation by checking the version:

    degit --help
    

Once these steps are complete, you are ready to scaffold a project and start styling terminal output.


Configuration

degit options

When you run degit from the CLI, the most commonly used options are:

OptionDefaultEffect
--mode=tartarDownloads the repository as a compressed tarball over HTTPS. Fastest option; does not require git.
--mode=git—Uses SSH-based git cloning. Required for private repositories. Slower than tar mode.
--forcefalseOverwrites the destination directory if it already exists.
--verbosefalsePrints additional progress information during download.

Degit automatically caches downloaded snapshots at ~/.degit/<user>/<repo>/<commithash>.tar.gz. If you scaffold the same commit again, degit reuses the cached file — no network request needed.

chalk: color level

Chalk automatically detects your terminal's color support. You can read or override this with the chalk.level property:

LevelDescription
0All colors disabled
1Basic 16-color support
2256-color support
3Truecolor support (16 million colors)

Only override chalk.level in your own top-level application code — changing it globally affects all chalk consumers. If you need an isolated instance with a specific level, create one with the Chalk constructor:

import { Chalk } from 'chalk';

const customChalk = new Chalk({ level: 1 });

You can also force a color level from the environment without changing code:

FORCE_COLOR=3 node your-script.js

Usage

Scaffold a new project with degit

The most common workflow is to download the default branch of a GitHub repository into a new folder:

degit user/repo my-new-project

This downloads a snapshot of user/repo — without any git history — into ./my-new-project. If you omit the destination folder, the files land in the current directory.

You can also pull from GitLab, BitBucket, or Sourcehut using equivalent syntax:

# GitHub (all equivalent)
degit user/repo
degit github:user/repo
degit https://github.com/user/repo

# GitLab
degit gitlab:user/repo

# BitBucket
degit bitbucket:user/repo

# Sourcehut
degit git.sr.ht/user/repo

To target a specific branch, tag, or commit hash, append it after a #:

degit user/repo#dev          # branch
degit user/repo#v1.2.3       # release tag
degit user/repo#1234abcd     # commit hash

To download only a subfolder of the repository:

degit user/repo/packages/my-template my-project

Style terminal output with chalk

Import chalk and call any style as a chained method. The styled string is returned, ready to pass to console.log or any other output mechanism:

import chalk from 'chalk';

console.log(chalk.blue('Hello world!'));

Chain multiple styles together in a single expression — order generally does not matter, and later styles take precedence on conflicts:

import chalk from 'chalk';

// Bold red text on a white background
console.log(chalk.bold.red.bgWhite('Critical error'));

// Mix styled and plain strings
console.log(chalk.green('Success:') + ' build complete');

// Use template literals for inline styling
const cpu = 91;
console.log(`CPU: ${chalk.red(cpu + '%')}`);

Define reusable theme variables to keep your logging consistent across a large codebase:

import chalk from 'chalk';

const error   = chalk.bold.red;
const warning = chalk.hex('#FFA500');  // orange
const success = chalk.green;

console.log(error('Build failed'));
console.log(warning('Deprecation notice'));
console.log(success('Tests passed'));

Examples

Example 1 — Scaffold a project from a GitHub template

Download the latest commit from user/my-template into a new folder called my-app:

degit user/my-template my-app

Expected output:

> cloned user/my-template#abc123 to my-app

The folder my-app now contains all files from the template repository with no .git directory.


Example 2 — Basic chalk colors

import chalk from 'chalk';

console.log(chalk.blue('Hello world!'));
console.log(chalk.red('Error occurred'));
console.log(chalk.green('All systems go'));

Expected output (colors rendered by your terminal):

Hello world!       ← blue
Error occurred     ← red
All systems go     ← green

Example 3 — Chaining styles

Combine multiple modifiers and colors in one expression:

import chalk from 'chalk';

console.log(chalk.blue.bgRed.bold('Hello world!'));
console.log(chalk.red('Error:', chalk.underline.bgBlue('disk full') + '!'));

Expected output:

Hello world!           ← bold, blue text on red background
Error: disk full!      ← 'disk full' is underlined on a blue background, rest is red

Example 4 — RGB and hex colors

Use true-color methods when you need precise brand colors or shades beyond the standard 16:

import chalk from 'chalk';

console.log(chalk.rgb(123, 45, 67).underline('Underlined reddish color'));
console.log(chalk.hex('#DEADED').bold('Bold gray!'));
console.log(chalk.bgHex('#DEADED').underline('Gray background'));

Expected output (in a Truecolor terminal):

Underlined reddish color   ← underlined, custom RGB color
Bold gray!                 ← bold, hex color
Gray background            ← underlined, hex background color

Example 5 — System status dashboard with chalk

A practical pattern that combines template literals with multiple styles:

import chalk from 'chalk';

const log = console.log;

log(`
CPU:  ${chalk.red('90%')}
RAM:  ${chalk.green('40%')}
DISK: ${chalk.yellow('70%')}
`);

Expected output:

CPU:  90%    ← red
RAM:  40%    ← green
DISK: 70%    ← yellow

Example 6 — Use degit programmatically

For scripts that need to scaffold a project as part of a larger workflow, use degit's JavaScript API:

const degit = require('degit');

const emitter = degit('user/repo', {
  cache: true,
  force: true,
  verbose: true,
});

emitter.on('info', info => {
  console.log(info.message);
});

emitter.clone('path/to/dest').then(() => {
  console.log('done');
});

Expected output:

> cloned user/repo#abc123 to path/to/dest
done

Troubleshooting

Destination directory already exists

Symptom: degit exits with an error saying the destination folder is not empty.

Cause: By default, degit refuses to overwrite an existing directory to prevent accidental data loss.

Fix: Pass the --force flag to allow overwriting:

degit user/repo my-project --force

No output colors — terminal shows raw escape codes or plain text

Symptom: Chalk output appears as plain text or shows raw ANSI sequences like \u001b[32m.

Cause: Color support is auto-detected and may be disabled for your terminal or environment (e.g., CI pipelines, non-TTY streams).

Fix: Force a color level using the FORCE_COLOR environment variable:

FORCE_COLOR=3 node your-script.js

Or pass the --color flag when running your script:

node your-script.js --color

chalk.level is 0 and colors are disabled

Symptom: Chalk produces unstyled output even in a color-capable terminal.

Cause: Something in the environment (a CI flag, piped output, or another package) set chalk.level to 0.

Fix: Check the level at runtime and override it only in your top-level application code:

import chalk from 'chalk';
console.log(chalk.level); // inspect current level

If you need an isolated instance that won't be affected by other packages:

import { Chalk } from 'chalk';
const customChalk = new Chalk({ level: 3 });

require('chalk') fails — ERR_REQUIRE_ESM

Symptom: Node.js throws ERR_REQUIRE_ESM when you use require('chalk').

Cause: Chalk 5 is ESM-only and cannot be loaded with require.

Fix: Either convert your file to ESM (import chalk from 'chalk') or downgrade to Chalk 4, which supports CommonJS:

npm install chalk@4

degit fails to download a private repository

Symptom: degit returns a network error or 404 when targeting a private repository.

Cause: The default tar mode fetches over HTTPS and cannot authenticate with private repositories.

Fix: Use --mode=git, which clones over SSH and can use your existing SSH key configuration:

degit user/private-repo my-project --mode=git

Make sure your SSH key is added to your git host account before running this command.


Slow or repeated downloads of the same template

Symptom: degit re-downloads a repository even though you have scaffolded it before.

Cause: If the commit hash has changed (e.g., the branch has new commits), degit fetches a fresh tarball. If the cache file exists for that exact commit, degit reuses it automatically.

Fix: Pin to a specific commit hash or tag to guarantee cache reuse:

degit user/repo#v1.2.3 my-project

Cached tarballs are stored at ~/.degit/<user>/<repo>/<commithash>.tar.gz.