{"skill":{"slug":"clack-prompts","displayName":"Build beautiful interactive Node.js command-line apps with @clack/prompts.","summary":"Build beautiful interactive Node.js command-line apps with @clack/prompts. Use when building CLI apps, wizards, setup scripts, or any interactive terminal pr...","description":"---\nname: clack-prompts\ndescription: Build beautiful interactive Node.js command-line apps with @clack/prompts. Use when building CLI apps, wizards, setup scripts, or any interactive terminal prompt flow in Node.js. Covers text input, password, confirm, select, autocomplete, multiselect, spinner, progress bars, grouped prompts, task runners, and styled logging.\n---\n\n# @clack/prompts\n\nBuild beautiful, minimal interactive CLI apps. Pre-styled, tree-shakeable, 80% smaller than alternatives.\n\n## Quick Start\n\n```\nnpm install @clack/prompts\n```\n\n```js\nimport { intro, outro, text, isCancel, cancel } from '@clack/prompts';\n\nintro('create-my-app');\n\nconst name = await text({ message: 'Project name?' });\nif (isCancel(name)) { cancel('Cancelled.'); process.exit(0); }\n\noutro(`Done! Created ${name}.`);\n```\n\n## Core Pattern — Always Guard Cancellation\n\nEvery prompt can return a cancel symbol (user pressed `Ctrl+C`). Always use `isCancel()`:\n\n```js\nconst result = await text({ message: 'Name?' });\nif (isCancel(result)) {\n  cancel('Cancelled.');\n  process.exit(0);\n}\n```\n\n## Choosing the Right Component\n\n| Need | Component | Returns |\n|------|-----------|---------|\n| Single-line text | `text` | string |\n| Masked secret | `password` | string |\n| Yes / No | `confirm` | boolean |\n| Pick one from list | `select` | string (value) |\n| Searchable pick one | `autocomplete` | string (value) |\n| Single-key selection | `selectKey` | string (value) |\n| Pick many from list | `multiselect` | string[] |\n| Pick many, grouped | `groupMultiselect` | string[] |\n| Multi-line text area | `multiline` | string |\n| Filesystem path | `path` | string |\n| Calendar date | `date` | Date |\n\n## Common Patterns\n\n### Sequential Prompts with group()\n\nChain prompts where later ones depend on earlier answers:\n\n```js\nimport * as p from '@clack/prompts';\n\nconst result = await p.group(\n  {\n    name: () => p.text({ message: 'What is your name?' }),\n    age: () => p.text({ message: 'What is your age?' }),\n    color: ({ results }) =>\n      p.multiselect({\n        message: `What is your favorite color ${results.name}?`,\n        options: [\n          { value: 'red', label: 'Red' },\n          { value: 'blue', label: 'Blue' },\n        ],\n      }),\n  },\n  {\n    onCancel: ({ results }) => {\n      p.cancel('Operation cancelled.');\n      process.exit(0);\n    },\n  },\n);\n```\n\n### Task Runner with Spinners\n\nRun sequential tasks, each with its own spinner:\n\n```js\nimport { tasks } from '@clack/prompts';\n\nawait tasks([\n  {\n    title: 'Installing via npm',\n    task: async () => {\n      // Return a string = success with checkmark\n      return 'Installed via npm';\n    },\n  },\n  {\n    title: 'Running tests',\n    task: async () => {\n      throw new Error('Tests failed!');  // Error = red X\n    },\n  },\n]);\n```\n\n### Standalone Spinner\n\n```js\nimport { spinner } from '@clack/prompts';\n\nconst s = spinner();\ns.start('Uploading...');\ntry { await upload(); s.stop('Uploaded!'); }\ncatch { s.stop('Upload failed'); }\n```\n\n### Progress Bar\n\n```js\nconst p = progress({ max: 100 });\np.start('Downloading');\nfor (const chunk of chunks) { p.advance(1); }\np.stop('Done');\n```\n\n### Live Sub-Process Output with taskLog\n\n```js\nimport { taskLog } from '@clack/prompts';\n\nconst log = taskLog({ title: 'npm install' });\nfor await (const line of npmInstall()) { log.message(line); }\nlog.success('Done!');   // Clears output on success\n// log.error('Failed!'); // Keeps output visible on failure\n```\n\n## Styled Logging (no user input)\n\n```js\nimport { log } from '@clack/prompts';\nimport color from 'picocolors';\n\nlog.info('Starting setup...');\nlog.success('Config written!');\nlog.step('Checking dependencies...');\nlog.warn('Optional peer dep missing');\nlog.error('Build failed');\nlog.message('Custom', { symbol: color.cyan('~') });\n```\n\n## Streaming Logs\n\nFor LLM output or dynamic streams:\n\n```js\nimport { stream } from '@clack/prompts';\n\nstream.info((function* () { yield 'Info!'; })());\nstream.success((async function* () { yield 'Done!'; })());\nstream.message(\n  (function* () { yield 'Hello'; yield ', World'; })(),\n  { symbol: color.cyan('~') }\n);\n```\n\n## Selection Options Shape\n\nUsed by `select`, `autocomplete`, `selectKey`, `multiselect`, `groupMultiselect`:\n\n```js\n{ value: 'ts', label: 'TypeScript' }           // Basic\n{ value: 'js', label: 'JavaScript', disabled: true }  // Disabled\n{ value: 'coffee', label: 'CoffeeScript', hint: 'oh no' } // With hint\n```\n\n## Validation\n\nMost components accept a `validate(value)` that returns `string` (error message) or `undefined` (valid):\n\n```js\nconst name = await text({\n  message: 'Username?',\n  validate(value) {\n    if (!value.length) return 'Username is required!';\n    if (value.length < 3) return 'At least 3 characters.';\n  },\n});\n```\n\n## Full API Reference\n\nSee [references/api.md](references/api.md) for every component's complete signature, options table, and examples.\n","tags":{"latest":"1.0.0"},"stats":{"comments":0,"downloads":330,"installsAllTime":0,"installsCurrent":0,"stars":0,"versions":1},"createdAt":1778040326264,"updatedAt":1778492854429},"latestVersion":{"version":"1.0.0","createdAt":1778040326264,"changelog":"Initial release of clack-prompts.\n\n- Build beautiful interactive Node.js command-line apps using @clack/prompts.\n- Supports various prompt types: text, password, confirm, select, autocomplete, multiselect, grouped prompts, and more.\n- Includes utilities for spinners, progress bars, task runners, styled logging, and streaming logs.\n- Comprehensive documentation provided with usage examples and API reference.","license":"MIT-0"},"metadata":null,"owner":{"handle":"openlark","userId":"s1727wv2g20pc729snzcm4nf8183hy72","displayName":"OpenLark","image":"https://avatars.githubusercontent.com/u/260858787?v=4"},"moderation":null}