Inquirer.js prompts look dated. Prompts.js is minimal. Clack gives you stunning interactive CLI prompts with spinners, confirmations, and multi-selects — in a fraction of the code.
What Is Clack?
Clack is a set of beautiful CLI prompt components. It's used by the Astro CLI, SvelteKit, and other popular tools. Think of it as "shadcn/ui for the terminal."
Quick Start
npm install @clack/prompts
import { intro, outro, text, select, confirm, spinner, isCancel, cancel } from '@clack/prompts';
async function main() {
intro('Create a new project');
const name = await text({
message: 'What is your project name?',
placeholder: 'my-awesome-app',
validate: (value) => {
if (!value) return 'Name is required';
if (value.includes(' ')) return 'No spaces allowed';
},
});
if (isCancel(name)) {
cancel('Operation cancelled');
process.exit(0);
}
const framework = await select({
message: 'Pick a framework',
options: [
{ value: 'react', label: 'React', hint: 'recommended' },
{ value: 'vue', label: 'Vue' },
{ value: 'svelte', label: 'Svelte' },
{ value: 'astro', label: 'Astro' },
],
});
const typescript = await confirm({
message: 'Use TypeScript?',
});
const s = spinner();
s.start('Creating project...');
await createProject(name, framework, typescript);
s.stop('Project created!');
outro('Done! Run `cd ${name} && npm run dev` to start.');
}
Available Prompts
Text Input
const name = await text({
message: 'Enter your name',
placeholder: 'John Doe',
defaultValue: 'Anonymous',
validate: (v) => v.length < 2 ? 'Too short' : undefined,
});
Password
const password = await password({
message: 'Enter password',
validate: (v) => v.length < 8 ? 'Min 8 characters' : undefined,
});
Select
const color = await select({
message: 'Choose a color',
options: [
{ value: 'red', label: 'Red' },
{ value: 'blue', label: 'Blue', hint: 'calming' },
{ value: 'green', label: 'Green' },
],
});
Multi-Select
const features = await multiselect({
message: 'Select features',
options: [
{ value: 'auth', label: 'Authentication' },
{ value: 'db', label: 'Database' },
{ value: 'api', label: 'API routes' },
],
required: true,
});
Group (Sequential)
const project = await group({
name: () => text({ message: 'Name?' }),
framework: () => select({ message: 'Framework?', options: [...] }),
typescript: () => confirm({ message: 'TypeScript?' }),
}, {
onCancel: () => { cancel('Cancelled'); process.exit(0); },
});
// project = { name: '...', framework: '...', typescript: true }
Why Clack Over Alternatives
| Feature | Clack | Inquirer | Prompts |
|---|---|---|---|
| Visual quality | Beautiful | Dated | Clean |
| Bundle size | 15KB | 50KB+ | 10KB |
| Spinner | Built-in | Separate | No |
| TypeScript | First-class | Good | Basic |
| Cancel handling | Built-in | Manual | Manual |
| Used by | Astro, SvelteKit | Legacy | Misc |
Get Started
- Documentation
- GitHub — 6K+ stars
Building CLI tools? My Apify scrapers have CLI interfaces too. Custom solutions: spinov001@gmail.com
Top comments (0)