Skip to content

Core

The @clack/core package provides the fundamental building blocks for creating interactive command-line interfaces. It’s designed to be flexible, extensible, and easy to use.

  • Low-level primitives: Base components for building custom prompts
  • Type-safe: Built with TypeScript for better developer experience
  • Flexible rendering: Customizable rendering system for prompts
  • Cancel handling: Built-in support for handling user cancellation
  • Event system: Comprehensive event handling for user interactions
  • Input validation: Built-in support for input validation
  • Abort signal support: Integration with AbortController for cancellation

To start using the core package, first install it:

Terminal window
npm install @clack/core

Then import the components you need:

import {
class TextPrompt
TextPrompt
,
class SelectPrompt<T extends { value: any; }>
SelectPrompt
,
class ConfirmPrompt
ConfirmPrompt
,
class PasswordPrompt
PasswordPrompt
,
class MultiSelectPrompt<T extends { value: any; }>
MultiSelectPrompt
,
class GroupMultiSelectPrompt<T extends { value: any; }>
GroupMultiSelectPrompt
,
class SelectKeyPrompt<T extends { value: any; }>
SelectKeyPrompt
} from '@clack/core';

The core package is organized into two main directories:

  • prompts/: Contains the base prompt implementations
  • utils/: Contains utility functions and helpers

The Prompt class serves as the foundation for all prompt types. It provides:

  • Custom rendering capabilities
  • Input handling
  • State management
  • Event system
  • Validation support
  • Abort signal integration
interface
interface Prompt
Prompt
{
// Event handling
Prompt.on<T extends string>(event: T, cb: (value: any) => void): void
on
<
function (type parameter) T in Prompt.on<T extends string>(event: T, cb: (value: any) => void): void
T
extends string>(
event: T extends string
event
:
function (type parameter) T in Prompt.on<T extends string>(event: T, cb: (value: any) => void): void
T
,
cb: (value: any) => void
cb
: (
value: any
value
: any) => void): void;
Prompt.once<T extends string>(event: T, cb: (value: any) => void): void
once
<
function (type parameter) T in Prompt.once<T extends string>(event: T, cb: (value: any) => void): void
T
extends string>(
event: T extends string
event
:
function (type parameter) T in Prompt.once<T extends string>(event: T, cb: (value: any) => void): void
T
,
cb: (value: any) => void
cb
: (
value: any
value
: any) => void): void;
Prompt.emit<T extends string>(event: T, ...data: any[]): void
emit
<
function (type parameter) T in Prompt.emit<T extends string>(event: T, ...data: any[]): void
T
extends string>(
event: T extends string
event
:
function (type parameter) T in Prompt.emit<T extends string>(event: T, ...data: any[]): void
T
, ...
data: any[]
data
: any[]): void;
// Core functionality
Prompt.prompt(): Promise<string | symbol>
prompt
():
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<string | symbol>;
Prompt.close(): void
close
(): void;
}

The Prompt interface provides several events that can be handled:

import {
class Prompt
Prompt
} from '@clack/core';
// Example usage
const
const p: Prompt
p
= new
new Prompt(options: PromptOptions<Prompt>, trackValue?: boolean): Prompt
Prompt
({
PromptOptions<Prompt>.render(this: Omit<Prompt, "prompt">): string | undefined
render
: () => 'Enter your name:'
});
// Handle value changes
const p: Prompt
p
.
Prompt.on<"value">(event: "value", cb: (value?: string) => void): void

Subscribe to an event

@paramevent - The event name

@paramcb - The callback

on
('value', (
value: string | undefined
value
?: string) => {
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
('Value changed:',
value: string | undefined
value
);
});
// Handle submission
const p: Prompt
p
.
Prompt.on<"submit">(event: "submit", cb: (value?: any) => void): void

Subscribe to an event

@paramevent - The event name

@paramcb - The callback

on
('submit', (
value: string | undefined
value
?: string) => {
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
('Submitted:',
value: string | undefined
value
);
});
// Handle cancellation
const p: Prompt
p
.
Prompt.on<"cancel">(event: "cancel", cb: (value?: any) => void): void

Subscribe to an event

@paramevent - The event name

@paramcb - The callback

on
('cancel', () => {
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
('Operation cancelled');
});
  1. TextPrompt: For text input

    • Supports validation
    • Placeholder text
    • Initial value
  2. SelectPrompt: For selection from options

    • Multiple selection support
    • Custom rendering
    • Option filtering
  3. ConfirmPrompt: For yes/no confirmations

    • Yes/No shortcuts
    • Custom messages
  4. AutocompletePrompt: For searchable selection

    • Type-ahead filtering
    • Custom filtering logic
    • Multiple selection support
  5. PasswordPrompt: For secure input

    • Character masking
    • Validation support
  6. MultiSelectPrompt: For multiple selections

    • Checkbox interface
    • Selection limits
    • Custom rendering
  7. GroupMultiSelectPrompt: For grouped selections

    • Hierarchical options
    • Group selection
    • Custom rendering
  8. SelectKeyPrompt: For key-based selection

    • Custom key bindings
    • Multiple selection support

You can create custom prompts by extending the base Prompt class:

import {
class Prompt
Prompt
} from '@clack/core';
// Example of extending the base Prompt class
class
class CustomPrompt
CustomPrompt
extends
class Prompt
Prompt
{
constructor(
options: {
message: string;
}
options
: {
message: string
message
: string }) {
super({
...
options: {
message: string;
}
options
,
PromptOptions<Prompt>.render(this: Omit<Prompt, "prompt">): string | undefined
render
: () => `${
options: {
message: string;
}
options
.
message: string
message
}\n${this.
Prompt.value: any
value
|| ''}`
});
}
}

For detailed examples and usage patterns, check out our examples guide.