Key Concepts
Core abstractions and design patterns
This page explains the core abstractions that underpin BeautifulCLI's two tools — degit and chalk. Understanding these concepts will help you make deliberate choices when scaffolding projects, styling terminal output, and composing both tools into larger workflows. Each concept maps directly to a behavior or design decision you will encounter as soon as you start integrating either tool into your code.
Template Repositories
A template repository is any public git repository — hosted on GitHub, GitLab, BitBucket, or Sourcehut — that you treat as a starting point for a new project. When you run degit against one, it downloads the repository's files without carrying along any of the source repo's commit history. This keeps your new project's git history clean from the first commit and avoids the overhead of transferring refs and blobs you will never use.
Degit also supports subdirectory cloning: you can point it at a folder inside a repository by appending the path directly to the source argument (for example, user/repo/packages/my-template). Only the contents of that folder are downloaded, which is useful when a single repo hosts multiple independent templates.
The Tarball Cache
Every time degit downloads a repository, it stores the result as a compressed snapshot — a .tar.gz file — at ~/.degit/<user>/<repo>/<commithash>.tar.gz. This is the tarball cache.
The cache serves two purposes:
- Speed. If you scaffold the same commit a second time, degit skips the network request and extracts the file it already has.
- Offline use. Once a commit is cached, you can scaffold from it without a network connection.
The cache is keyed by commit hash, not by branch or tag name. That means degit always stores a precise, immutable snapshot rather than a mutable label — so two runs against the same branch name that resolve to different commits produce two separate cache entries.
Download Modes
Degit supports two modes that control how it fetches a repository:
| Mode | How it works | When to use it |
|---|---|---|
tar (default) | Downloads a compressed snapshot over HTTPS | Public repositories; fastest option |
git | Clones via SSH then strips the .git directory | Private repositories that require SSH access |
You select a mode with the --mode flag or the mode option in the programmatic API. For the vast majority of workflows — scaffolding from a public template — the default tar mode is the right choice. Switch to --mode=git only when HTTPS access is unavailable or the repository is private.
Post-Scaffold Actions
Degit's actions system lets you define post-scaffold steps in a degit.json file placed at the root of your working directory. After cloning the primary template, degit reads this file and executes each listed action in order.
Two action types are supported:
clone— Downloads an additional repository (or subdirectory) into the same destination folder, allowing you to compose a project from multiple template sources.remove— Deletes specified files or directories from the scaffolded output, so you can ship a template with placeholder files that are stripped during scaffolding.
This makes it possible to build layered templates: a base project structure from one repo, a framework-specific configuration from another, with a handful of scaffolding-only files removed at the end — all described declaratively in degit.json without any custom scripting.
ANSI Styles and How Chalk Generates Them
ANSI styles are standard escape codes that terminals interpret as instructions to change the visual appearance of text — its foreground color, background color, or modifiers like bold, italic, underline, or strikethrough. Chalk generates these codes for you automatically; you never write raw escape sequences.
Chalk detects whether your terminal supports color and adjusts its output accordingly. This detection result is exposed as chalk.level:
| Level | Meaning |
|---|---|
0 | Colors disabled |
1 | Basic 16-color support |
2 | 256-color support |
3 | Truecolor (16 million colors) |
You can read or override chalk.level globally, or create an isolated instance with a fixed level using new Chalk({ level: n }) to avoid affecting other consumers.
Style Chaining
Chaining is chalk's primary composition mechanism. Because each style accessor returns the same chalk instance, you can join multiple modifiers and colors with dots before calling the result as a function:
chalk.bold.red.bgWhite('text')
Order is flexible — later styles take precedence when there is a conflict. chalk.red.yellow.green is equivalent to chalk.green. This lets you build up style combinations incrementally and define reusable theme variables by storing partially-chained expressions:
const error = chalk.bold.red;
const warning = chalk.hex('#FFA500');
Chalk also supports nested styles: you can embed one styled expression inside another, and chalk correctly re-opens the outer style after the inner one closes.
256-Color and RGB Support
Beyond the standard 16 named colors, chalk provides three extended color models for both foreground and background:
rgb(r, g, b)/bgRgb(r, g, b)— Specify a color as red, green, and blue values (0–255).hex('#RRGGBB')/bgHex('#RRGGBB')— Specify a color as a CSS-style hex string.ansi256(n)/bgAnsi256(n)— Specify a color as an index from 0–255 in the 8-bit ANSI palette.
When the terminal does not support the requested color depth, chalk automatically downsamples the value to the closest color the terminal can render, based on chalk.level. This means you can write your styling code against the full RGB space and trust chalk to degrade gracefully on older terminals.
Scaffolding from a public GitHub template
Download a repository's files into a new directory. No git history is copied.
degit user/my-template my-new-project
After running this command, my-new-project/ contains the template's files, ready for git init.
Scaffolding from a subdirectory
Download only the packages/app folder from a monorepo template.
degit user/monorepo/packages/app my-app
Using git mode for a private repository
degit user/private-template my-project --mode=git
Degit clones via SSH and strips the .git directory from the result.
Composing templates with degit.json
Place a degit.json file in your template repository root to define post-scaffold actions:
[
{
"action": "clone",
"src": "user/shared-config"
},
{
"action": "remove",
"files": ["degit.json", "TEMPLATE_README.md"]
}
]
When a user scaffolds your template, degit first clones the primary repo, then merges in user/shared-config, then removes the listed files.
Basic chalk styling
import chalk from 'chalk';
console.log(chalk.blue('Hello world!'));
console.log(chalk.bold.red('Error: something went wrong'));
console.log(chalk.blue.bgWhite.underline('Highlighted text'));
Expected output (colors rendered by your terminal):
Hello world! ← blue
Error: something went wrong ← bold red
Highlighted text ← blue, white background, underlined
Defining reusable theme variables
import chalk from 'chalk';
const error = chalk.bold.red;
const warning = chalk.hex('#FFA500');
const success = chalk.green;
console.log(error('Build failed'));
console.log(warning('Skipping optional step'));
console.log(success('Done'));
RGB and hex colors with automatic downsampling
import chalk from 'chalk';
// RGB foreground + modifier
console.log(chalk.rgb(123, 45, 67).underline('Underlined reddish color'));
// Hex foreground
console.log(chalk.hex('#DEADED').bold('Bold gray!'));
// 256-color background
console.log(chalk.bgAnsi256(194)('Honeydew, more or less'));
If the terminal only supports 16 colors (chalk.level === 1), chalk downsamples the RGB or hex value to the nearest ANSI color automatically.
Creating an isolated chalk instance with a fixed color level
Use this when you need to control styling in a reusable module without affecting other chalk consumers.
import { Chalk } from 'chalk';
const customChalk = new Chalk({ level: 2 }); // Force 256-color mode
console.log(customChalk.ansi256(201)('Purple text'));
Nesting styles
import chalk from 'chalk';
console.log(
chalk.green(
'I am green ' +
chalk.blue.bold('with a blue bold section') +
' and green again'
)
);
Chalk correctly reopens the outer green style after the inner blue-bold section closes.
- Installation — How to add degit and chalk to your project before using any of the concepts described here.
- Scaffold a new project from a template — A step-by-step workflow that puts template repositories, tarball caching, and download modes into practice.
- Target a specific branch, tag, or commit — How ref resolution works and how the tarball cache stores results by commit hash rather than ref name.
- Compose template actions — A deeper look at building
degit.jsonfiles to merge multiple sources and clean up scaffolding artifacts. - Use degit programmatically — How to drive degit's clone and action system from JavaScript, including listening to
infoandwarnevents. - Style terminal output with chalk — End-to-end guide covering auto-detection, level overrides, and building a complete theme for a CLI tool.