DEV Community

Alex Spinov
Alex Spinov

Posted on

Clack Has Free Beautiful CLI Prompts — Here's How to Use It

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
Enter fullscreen mode Exit fullscreen mode
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.');
}
Enter fullscreen mode Exit fullscreen mode

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,
});
Enter fullscreen mode Exit fullscreen mode

Password

const password = await password({
  message: 'Enter password',
  validate: (v) => v.length < 8 ? 'Min 8 characters' : undefined,
});
Enter fullscreen mode Exit fullscreen mode

Select

const color = await select({
  message: 'Choose a color',
  options: [
    { value: 'red', label: 'Red' },
    { value: 'blue', label: 'Blue', hint: 'calming' },
    { value: 'green', label: 'Green' },
  ],
});
Enter fullscreen mode Exit fullscreen mode

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,
});
Enter fullscreen mode Exit fullscreen mode

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 }
Enter fullscreen mode Exit fullscreen mode

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


Building CLI tools? My Apify scrapers have CLI interfaces too. Custom solutions: spinov001@gmail.com

Top comments (0)