Skip to content
GitHub Twitter

Building Command-Line Interfaces Made Easy with Clack

Command-line interfaces (CLI) are a fundamental part of the developer's toolkit, offering powerful ways to interact with software and systems. However, crafting a CLI that is intuitive, robust, and user-friendly can be a challenging task. In this post, we'll discuss some essential considerations when building a CLI and introduce Clack, a tool that eases this process by leveraging familiar languages like JavaScript and TypeScript.

Why is a Good CLI Important?

A well-designed CLI can significantly enhance the user experience by providing clear error messages, easy-to-discover commands, and straightforward interactions. It's essential that users are not burdened with installing external dependencies and can quickly find documentation when needed. Let's consider some key points that help achieve these goals.

Error Messages and Documentation

Error messages should be:

  • Clear and easy to read
  • Indicative of potential solutions
  • Linked to additional documentation

Command Discoverability

Your CLI should:

  • Present commands that are easy to discover
  • Provide help flags or commands to list available options
  • Incorporate auto-suggestions or tab-completions where possible

Interaction Simplicity

A great CLI allows users to:

  • Execute commands with minimal fuss
  • Use flags and parameters in a predictable manner
  • Access well-structured help menus for guidance

Clack GH page

Introducing Clack: A Clever Way to Build CLIs

When it comes to building your CLI, Clack comes to the rescue. But what exactly is Clack? It's comprised of two packages: @clack/core and @clack/prompts.

@clack/core

At its heart, @clack/core provides the unstyled but essential building blocks of your CLI, which can be customized as needed.

@clack/prompts

On the other hand, @clack/prompts offers a suite of "component-style," pre-styled elements that you can easily import and use within your project. This is perfect for those looking to create something appealing without reinventing the wheel.

Created by Nate, a member of the Astro core team, Clack's approach allows developers to focus on their business logic rather than the complex underlying CLI infrastructure.

Dive into Clack Prompts with a Demo

To appreciate the powers of Clack, let's roll up our sleeves and see it in action with a simple demonstrative application: create-my-app.

Here's how a typical interaction might go using Clack prompts:

Code example

Clack's functionality doesn't just stop at the basics. You get access to a variety of interactive prompts, like:

  • text: Captures input text.
  • confirm: Returns a boolean, useful for yes/no questions.
  • select: Allows the user to choose from a list.
  • multiSelect: Enables selection of multiple items from a list.
  • spinner: Provides visual feedback of a process in action.

Let's look at an example implementation:

import { text, confirm, select, spinner, isCanceled } from "@clack/prompts";

async function main() {
  const name = await text("What is your name?", "anonymous");
  if (isCanceled(name)) return process.exit();
  const continuation = await confirm("Do you want to continue?");
  if (!continuation) return process.exit();
  const projectType = await select("Choose a project type", [
    "Web",
    "Mobile",
    "API",
    "Library",
  ]);
  await spinner("Installing selected features...", () => {
    // Simulate an asynchronous task, such as installing packages
    return new Promise((resolve) => setTimeout(resolve, 3000));
  });
  console.log(
    "Setup complete! Ready to start building your ",
    projectType,
    " project.",
  );
}
main();

Code example Using promises and async-await patterns, this example showcases how straightforward it is to construct a CLI with Clack. It's also worth noting that Clack is 80% smaller in size compared to other CLI-building options out there.

Streamlining CLI Development

To tie this all together, Clack emphasizes three critical components for a complete CLI experience:

  1. Intro: A warm introduction as the session starts.
  2. Outro: A friendly farewell message as the session concludes.
  3. Guard Clause: isCanceled ensures the ability to exit or cancel operations at any stage.

"Utilize Clack's simplicity to focus on what really matters in your CLI—your core logic and user interaction."

The Additional Charm of Multiselect

In our exploration, we've touched upon the power of multinselect. It enhances user interaction by enabling the simultaneous selection of multiple items, which is as easy as hitting the spacebar.

Real-world Use Case: unkey's CLI

To wrap things up, I'd like to share how I've been using Clack at my own company, unkey, to simplify the creation of our CLI. This tool is designed to make it easier for contributors to quickly set up and start working on our application.

Final Thoughts

Clack undoubtedly simplifies the process of creating a CLI, making it more accessible and enjoyable for developers. If you found this tour illuminating, remember to show some love by leaving a thumbs up, subscribing to the channel, and keeping an eye out for more tutorials like this throughout the year.

Thank you for joining me on this deep dive into Clack, and here's to building better CLIs! See you in the next one.