Examples
Real-world code examples
This page collects real-world, runnable examples for both BeautifulCLI tools — chalk and degit. You will find copy-paste-ready code snippets that demonstrate the most useful patterns: scaffolding projects from templates, targeting specific refs, composing templates with actions, styling terminal output with colors and themes, using extended RGB and hex colors, and animating strings in the terminal. Work through the examples in order for a guided tour, or jump directly to the pattern you need.
Before running any example on this page, make sure you have the following in place:
- Node.js ≥ 8.0.0 — both chalk and degit require it; check with
node --version - npm — used to install packages; check with
npm --version - git (optional) — only required when using
--mode=gitfor private repositories - degit installed globally (for CLI examples):
npm install -g degit
- chalk installed in your project (for chalk examples):
npm install chalk
Note: Chalk 5 is ESM-only. All chalk examples on this page use ES module
importsyntax. If your project uses CommonJS, use Chalk 4 instead.
- Install degit globally so the
degitcommand is available in your terminal:
npm install -g degit
- Verify the installation:
degit --help
- Create or navigate to your project directory:
mkdir my-project && cd my-project
- Install chalk as a dependency of your Node.js project:
npm install chalk
- Confirm chalk is available by creating a quick smoke-test file:
// test.js
import chalk from 'chalk';
console.log(chalk.green('chalk is working!'));
node test.js
You should see chalk is working! printed in green.
degit options
When using degit programmatically, you can pass an options object as the second argument:
| Option | Default | Valid values | Effect |
|---|---|---|---|
cache | true | true, false | When true, degit reuses a previously downloaded tarball from ~/.degit/<user>/<repo>/<commithash>.tar.gz instead of fetching it again. Set to false to always fetch fresh. |
force | false | true, false | When true, degit will overwrite files in the destination directory. When false, it stops if the destination is non-empty. |
verbose | false | true, false | When true, degit emits detailed info events during cloning, useful for debugging. |
--mode (CLI) | tar | tar, git | tar fetches a compressed snapshot over HTTPS — fastest option. git uses SSH-based cloning and is required for private repositories. |
Example — programmatic options:
import degit from 'degit';
const emitter = degit('user/repo', {
cache: true,
force: true,
verbose: true,
});
chalk — color level
Chalk auto-detects your terminal's color support, but you can override it with chalk.level:
| Level | Description |
|---|---|
0 | All colors disabled |
1 | Basic color support (16 colors) |
2 | 256 color support |
3 | Truecolor support (16 million colors) |
Overriding chalk.level applies globally. To avoid affecting other consumers, create a scoped instance instead:
import { Chalk } from 'chalk';
const chalk = new Chalk({ level: 2 }); // 256-color mode for this instance only
You can also force color support at the environment level without code changes:
FORCE_COLOR=3 node my-script.js # force truecolor
FORCE_COLOR=0 node my-script.js # disable all color
Scaffold a project from a GitHub template
The simplest degit command downloads the default branch of any public repository into your current directory:
degit user/repo
To create a named folder at the same time:
degit user/repo my-new-project
Degit stores the downloaded snapshot at ~/.degit/user/repo/<commithash>.tar.gz. The next time you scaffold from the same commit, degit reuses that local cache — no internet connection required.
Style terminal output with chalk
Import chalk and chain style modifiers to produce colored output:
import chalk from 'chalk';
console.log(chalk.blue('Hello world!'));
console.log(chalk.bold.red('Error: something went wrong'));
console.log(chalk.blue.bgRed.bold('Alert!'));
Passing multiple arguments joins them with a space:
console.log(chalk.blue('Hello', 'World!', 'from', 'chalk'));
// => Hello World! from chalk (all in blue)
Define reusable style themes
Assign chalk chains to variables to create a consistent style system across your CLI:
import chalk from 'chalk';
const error = chalk.bold.red;
const warning = chalk.hex('#FFA500'); // orange
const success = chalk.green;
const info = chalk.blue;
console.log(error('Build failed!'));
console.log(warning('Deprecated API in use'));
console.log(success('Deployment complete'));
console.log(info('Listening on port 3000'));
Use chalk in template literals
Template literals let you mix styled and plain strings cleanly:
import chalk from 'chalk';
const cpu = 90;
const ram = 40;
const disk = 70;
console.log(`
CPU: ${chalk.red(`${cpu}%`)}
RAM: ${chalk.green(`${ram}%`)}
DISK: ${chalk.yellow(`${disk}%`)}
`);
Example 1 — Scaffold from GitHub, GitLab, and Bitbucket
Degit accepts multiple URL forms for each host. All of the following commands are equivalent for GitHub:
degit user/repo my-project
degit github:user/repo my-project
degit git@github.com:user/repo my-project
degit https://github.com/user/repo my-project
For GitLab and Bitbucket:
# GitLab
degit gitlab:user/repo my-project
degit https://gitlab.com/user/repo my-project
# Bitbucket
degit bitbucket:user/repo my-project
degit https://bitbucket.org/user/repo my-project
# Sourcehut
degit git.sr.ht/user/repo my-project
Expected result: A new my-project/ directory containing the repository's files — no .git folder, no commit history.
Example 2 — Target a specific branch, tag, or commit
Append #ref to pin the scaffold to an exact point in history:
degit user/repo#dev # a branch named 'dev'
degit user/repo#v1.2.3 # a release tag
degit user/repo#1234abcd # a specific commit hash
Expected result: The files from that exact ref are downloaded, not the latest default branch.
Example 3 — Clone only a subdirectory
When a template repository contains multiple project starters, you can download just one folder:
degit user/repo/packages/template-svelte my-svelte-app
Expected result: Only the contents of packages/template-svelte/ are extracted into my-svelte-app/.
Example 4 — Use a private repository with git mode
For SSH-accessible private repositories, switch to --mode=git:
degit --mode=git git@github.com:your-org/private-repo my-project
Expected result: Degit uses git over SSH to clone the repository, then strips the history, producing a clean working directory. Note this is slower than the default tar mode.
Example 5 — Compose templates with degit.json actions
Place a degit.json file at the root of your working directory to run post-scaffold steps automatically. You can clone additional repositories into the same folder and remove unwanted files:
[
{
"action": "clone",
"src": "user/shared-configs"
},
{
"action": "remove",
"files": ["LICENSE"]
}
]
What this does:
- After the primary scaffold completes, degit clones
user/shared-configsinto the same working directory, merging its files. - The
LICENSEfile is then deleted from the result.
Expected result: Your project directory contains files from both repositories, minus LICENSE.
Example 6 — Use degit programmatically inside a Node.js script
import degit from 'degit';
const emitter = degit('user/repo', {
cache: true,
force: true,
verbose: true,
});
emitter.on('info', info => {
console.log(info.message);
});
await emitter.clone('path/to/dest');
console.log('Scaffold complete!');
Expected output:
cloned user/repo#abc1234 to path/to/dest
Scaffold complete!
Example 7 — Basic chalk colors and styles
import chalk from 'chalk';
// Single color
console.log(chalk.blue('Hello world!'));
// Combine styled and plain strings
console.log(chalk.blue('Hello') + ' World' + chalk.red('!'));
// Chain multiple styles
console.log(chalk.blue.bgRed.bold('Hello world!'));
// Nest styles
console.log(chalk.red('Hello', chalk.underline.bgBlue('world') + '!'));
Expected output: Each line is printed with the corresponding ANSI colors and styles applied.
Example 8 — RGB and hex colors
For terminals that support 256 or truecolor, you can specify exact colors:
import chalk from 'chalk';
// Hex color
console.log(chalk.hex('#DEADED').bold('Bold gray!'));
// RGB color with underline
console.log(chalk.rgb(123, 45, 67).underline('Underlined reddish color'));
// Background hex
console.log(chalk.bgHex('#DEADED').underline('Hello, world!'));
// Background RGB with inverse
console.log(chalk.bgRgb(15, 100, 204).inverse('Hello!'));
// ansi256
console.log(chalk.bgAnsi256(194)('Honeydew, more or less'));
Expected output: Each string is rendered with the specified extended color in terminals that support it. On terminals with lower color support, chalk automatically downsamples the color to the closest available match.
Example 9 — Animated rainbow string
This example (adapted from examples/rainbow.js) combines chalk's hex() method with HSL color cycling to animate a rainbow across a string in the terminal. It depends on the color-convert and log-update packages:
npm install color-convert log-update
import { setTimeout as delay } from 'node:timers/promises';
import convertColor from 'color-convert';
import updateLog from 'log-update';
import chalk from 'chalk';
const ignoreChars = /[^!-~]/g;
function rainbow(string, offset) {
if (!string || string.length === 0) return string;
const hueStep = 360 / string.replaceAll(ignoreChars, '').length;
let hue = offset % 360;
const characters = [];
for (const character of string) {
if (ignoreChars.test(character)) {
characters.push(character);
} else {
characters.push(chalk.hex(convertColor.hsl.hex(hue, 100, 50))(character));
hue = (hue + hueStep) % 360;
}
}
return characters.join('');
}
async function animateString(string) {
for (let index = 0; index < 360 * 5; index++) {
updateLog(rainbow(string, index));
await delay(2);
}
}
console.log();
await animateString('We hope you enjoy Chalk! <3');
console.log();
Expected output: The string We hope you enjoy Chalk! <3 cycles through the full color spectrum for approximately 3.6 seconds, with each character rendered in a distinct, smoothly shifting hue.
Example 10 — Input validation with style name arrays
Chalk exposes arrays of valid style names you can use to validate user input in your own wrappers:
import { modifierNames, foregroundColorNames } from 'chalk';
console.log(modifierNames.includes('bold')); // => true
console.log(foregroundColorNames.includes('pink')); // => false
console.log(foregroundColorNames.includes('cyan')); // => true
Expected output:
true
false
true
Issue: degit command not found
Symptom: Running degit user/repo produces command not found: degit.
Cause: degit was not installed globally, or your npm global bin directory is not on your PATH.
Fix:
npm install -g degit
If the command is still not found, check your npm global prefix and ensure it is on PATH:
npm config get prefix
# Add <prefix>/bin to your PATH in your shell profile
Issue: Destination directory is not empty
Symptom: degit exits with an error saying the destination directory already contains files.
Cause: By default, degit will not overwrite an existing non-empty directory.
Fix: Pass force: true when using the programmatic API, or delete / empty the target folder before running degit:
const emitter = degit('user/repo', { force: true });
Or from the CLI, ensure your target directory does not exist yet:
degit user/repo fresh-folder # 'fresh-folder' must not already exist
Issue: Private repository download fails with tar mode
Symptom: degit user/private-repo returns an authentication or access error.
Cause: The default tar mode fetches over HTTPS without authentication and cannot access private repositories.
Fix: Switch to git mode, which uses SSH authentication:
degit --mode=git git@github.com:your-org/private-repo my-project
Ensure your SSH key is loaded and authorised for the repository.
Issue: chalk produces no color output
Symptom: chalk calls print plain text with no color or styling.
Cause: Chalk detected that your terminal does not support color (chalk.level is 0). This can happen in CI environments, when output is piped, or when running in a terminal with no color support.
Fix: Force a color level using the FORCE_COLOR environment variable:
FORCE_COLOR=1 node my-script.js # 16 colors
FORCE_COLOR=3 node my-script.js # truecolor
Or create a chalk instance with an explicit level:
import { Chalk } from 'chalk';
const chalk = new Chalk({ level: 3 });
Issue: import chalk from 'chalk' fails with a module error
Symptom: Node.js throws ERR_REQUIRE_ESM or a similar module error when loading chalk.
Cause: Chalk 5 is ESM-only. If your project uses CommonJS (require()), it cannot import Chalk 5 directly.
Fix: Either migrate your project to ESM by adding "type": "module" to your package.json, or downgrade to Chalk 4 which supports CommonJS:
npm install chalk@4
Issue: degit.json actions do not run
Symptom: After scaffolding, the additional clone or file removal steps defined in degit.json are not executed.
Cause: The degit.json file must be located at the root of the working directory that degit is writing into — not inside the source template repository.
Fix: Ensure degit.json exists at the top level of your destination folder and is valid JSON matching the expected action schema:
[
{ "action": "clone", "src": "user/another-repo" },
{ "action": "remove", "files": ["LICENSE"] }
]