@rcompat/cli
v0.14.0
Published
Standard library CLI
Readme
@rcompat/cli
CLI tools for terminal colors, formatting, and interactive prompts.
What is @rcompat/cli?
A cross-runtime module providing terminal styling, output formatting, and interactive prompts. Build beautiful command-line interfaces that work consistently across Node, Deno, and Bun.
Installation
npm install @rcompat/clipnpm add @rcompat/cliyarn add @rcompat/clibun add @rcompat/cliUsage
Colors
Style terminal output with ANSI colors.
import color from "@rcompat/cli/color";
console.log(color.red("Error: something went wrong"));
console.log(color.green("Success!"));
console.log(color.blue("Info: processing..."));
console.log(color.bold("Important message"));
console.log(color.dim("Less important"));
// combine styles
console.log(color.bold(color.red("Critical error!")));Available colors:
red,green,blue,cyan,magenta,yellowblack,white,graybold,dim,inverse
Write to stdout without a newline.
import print from "@rcompat/cli/print";
print("Loading");
print(".", ".", "."); // Multiple arguments joined with space
print("\n");mark
Format strings with placeholders and dim styling.
import mark from "@rcompat/cli/mark";
console.log(mark("Created {0} in {1}", "config.json", "./src"));
// Output: Created config.json in ./src (values dimmed)
console.log(mark("Found {0} files", 42));
// Output: Found 42 filesPrompts
Interactive CLI prompts for user input.
text
import text from "@rcompat/cli/prompts/text";
import isCancel from "@rcompat/cli/prompts/is-cancel";
const name = await text({
message: "What is your name?",
initial: "Anonymous",
validate: (value) => {
if (value.length < 2) return "Name must be at least 2 characters";
},
});
if (isCancel(name)) {
console.log("Cancelled");
process.exit(0);
}
console.log(`Hello, ${name}!`);confirm
import confirm from "@rcompat/cli/prompts/confirm";
import isCancel from "@rcompat/cli/prompts/is-cancel";
const proceed = await confirm({
message: "Do you want to continue?",
initial: true, // default to yes
});
if (isCancel(proceed)) {
console.log("Cancelled");
process.exit(0);
}
if (proceed) {
console.log("Continuing...");
}select
import select from "@rcompat/cli/prompts/select";
const color = await select({
message: "Pick a color",
options: [
{ label: "Red", value: "#ff0000" },
{ label: "Green", value: "#00ff00" },
{ label: "Blue", value: "#0000ff" },
],
initial: 0, // default to first option
});
console.log(`You picked: ${color}`);multiselect
import multiselect from "@rcompat/cli/prompts/multiselect";
const features = await multiselect({
message: "Select features to install",
options: [
{ label: "TypeScript", value: "typescript" },
{ label: "ESLint", value: "eslint" },
{ label: "Prettier", value: "prettier" },
{ label: "Testing", value: "testing" },
],
initial: [0, 1], // pre-select first two
});
console.log(`Installing: ${features.join(", ")}`);spinner
import spinner from "@rcompat/cli/prompts/spinner";
const s = spinner();
s.start("Installing dependencies");
// Update message while running
s.message("Still installing...");
// Simulate async work
await new Promise(r => setTimeout(r, 2000));
s.stop("Dependencies installed");intro / outro
import intro from "@rcompat/cli/prompts/intro";
import outro from "@rcompat/cli/prompts/outro";
intro("Welcome to the setup wizard");
// ... your prompts here ...
outro("Setup complete!");cancel
Handle user cancellation (Ctrl+C).
import text from "@rcompat/cli/prompts/text";
import isCancel from "@rcompat/cli/prompts/is-cancel";
import cancel from "@rcompat/cli/prompts/cancel";
const name = await text({ message: "Your name?" });
if (isCancel(name)) {
cancel("Operation cancelled");
process.exit(0);
}API Reference
Colors
import color from "@rcompat/cli/color";
declare function color.[NAME](message: string): string;declare function print(...messages: string[]): void;Writes messages to stdout, joined by spaces, without a trailing newline.
mark
declare function mark(format: string, ...params: unknown[]): string;Formats a string by replacing {0}, {1}, etc. with dimmed parameter values.
Prompts
text
declare function text(options: TextOptions): Promise<string | CancelSymbol>;
interface TextOptions {
message: string;
initial?: string;
validate?: (input: string) => string | void | Promise<string | void>;
}confirm
declare function confirm(options: ConfirmOptions): Promise<boolean | CancelSymbol>;
interface ConfirmOptions {
message: string;
initial?: boolean;
}select
declare function select<T>(options: SelectOptions<T>): Promise<T>;
interface SelectOptions<T> {
message: string;
options: Array<{ label: string; value: T }>;
initial?: number;
}multiselect
declare function multiselect<T>(options: MultiselectOptions<T>): Promise<T[]>;
interface MultiselectOptions<T> {
message: string;
options: Array<{ label: string; value: T }>;
initial?: number[];
}spinner
declare function spinner(): {
start(message: string): void;
message(text: string): void;
stop(message?: string): void;
};intro / outro / cancel
declare function intro(message?: string): void;
declare function outro(message?: string): void;
declare function cancel(message?: string): CancelSymbol;isCancel
declare function isCancel(value: unknown): value is CancelSymbol;Examples
Interactive CLI wizard
import intro from "@rcompat/cli/prompts/intro";
import outro from "@rcompat/cli/prompts/outro";
import text from "@rcompat/cli/prompts/text";
import select from "@rcompat/cli/prompts/select";
import confirm from "@rcompat/cli/prompts/confirm";
import spinner from "@rcompat/cli/prompts/spinner";
import isCancel from "@rcompat/cli/prompts/is-cancel";
import cancel from "@rcompat/cli/prompts/cancel";
import green from "@rcompat/cli/color/green";
intro("Project Setup");
const name = await text({
message: "Project name?",
initial: "my-app",
});
if (isCancel(name)) {
cancel("Setup cancelled");
process.exit(0);
}
const template = await select({
message: "Select a template",
options: [
{ label: "Minimal", value: "minimal" },
{ label: "Full", value: "full" },
],
});
const install = await confirm({
message: "Install dependencies?",
initial: true,
});
if (install) {
const s = spinner();
s.start("Installing dependencies");
await new Promise(r => setTimeout(r, 2000));
s.stop("Dependencies installed");
}
outro(green(`Created ${name} with ${template} template`));Colored log levels
import color from "@rcompat/cli/color";
const log = {
error: (msg) => console.log(color.red("ERROR"), msg),
warn: (msg) => console.log(color.yellow("WARN"), msg),
info: (msg) => console.log(color.blue("INFO"), msg),
debug: (msg) => console.log(color.dim("DEBUG"), color.dim(msg)),
};
log.error("Connection failed");
log.warn("Deprecated API");
log.info("Server started");
log.debug("Request received");Cross-Runtime Compatibility
| Runtime | Supported | |---------|-----------| | Node.js | ✓ | | Deno | ✓ | | Bun | ✓ |
No configuration required — just import and use.
License
MIT
Contributing
See CONTRIBUTING.md in the repository root.
