Build beautiful CLIs with TypeScript
Build production-ready CLIs in minutes, not hours.
Building a CLI tool in Node.js typically means:
EasyCLI provides a complete, type-safe toolkit for building beautiful command-line applications.
import { defineCLI } from "easycli-core";
const cli = defineCLI({
name: "myapp",
version: "1.0.0",
commands: {
deploy: {
description: "Deploy to production",
args: { env: ["staging", "production"] },
async run({ env }, ctx) {
const t = ctx.task("Deploying");
await t.step("Build", build);
await t.step("Upload", upload);
t.success("Done!");
}
}
}
});
cli.run();
| Feature | Commander.js | EasyCLI |
|---|---|---|
| Type Safety | Manual | Built-in |
| Argument Validation | Manual | Automatic |
| Subcommands | Verbose setup | Nested objects |
| Interactive Prompts | Separate package | Integrated |
| Spinners/Progress | Separate package | Integrated |
| Rich Errors | Manual | Built-in |
| Task Runners | Not available | Built-in |
| Colors | Separate package | Integrated |
Commander.js
const { program } = require('commander');
const inquirer = require('inquirer');
const ora = require('ora');
const chalk = require('chalk');
program
.command('deploy <env>')
.description('Deploy to production')
.action(async (env) => {
const { confirm } = await inquirer.prompt([
{ type: 'confirm', name: 'confirm', message: 'Continue?' }
]);
if (!confirm) return;
const spinner = ora('Building...').start();
await build();
spinner.succeed('Built!');
});
program.parse();
EasyCLI
const cli = defineCLI({
name: "myapp",
commands: {
deploy: {
args: { env: ["staging", "production"] },
async run({ env }, ctx) {
const confirmed = await ctx.ask.confirm("Continue?");
if (!confirmed) return;
const t = ctx.task("Deploying");
await t.step("Building", build);
t.success("Built!");
}
}
}
});
| Feature | Yargs | EasyCLI |
|---|---|---|
| TypeScript Support | Partial | Full |
| Learning Curve | Steep | Minimal |
| Bundle Size | ~150KB | ~40KB |
| UI Components | None | Spinner, Progress, Table, Box |
| Prompts | Separate | Integrated |
| Configuration | Complex | Simple Objects |
| Feature | Oclif | EasyCLI |
|---|---|---|
| Setup Time | Hours | Minutes |
| Boilerplate | Heavy | Minimal |
| Class-based | Required | Optional |
| Plugin System | Complex | Simple |
| Learning Curve | Steep | Gentle |
Full TypeScript inference from schema to handler:
commands: {
create: {
args: { name: "string" },
flags: {
template: { type: "string", default: "default" },
force: { type: "boolean", alias: "f" }
},
run({ name, template, force }) {
// name: string, template: string, force: boolean
// All inferred automatically!
}
}
}
Beautiful, actionable error messages:
throw ctx.error("Invalid token", {
hint: "Run: myapp auth login",
docs: "https://docs.myapp.dev/auth"
});
Output:
X Invalid token
Hint: Run: myapp auth login
Docs: https://docs.myapp.dev/auth
Progress tracking for multi-step workflows:
const t = ctx.task("Deploying");
await t.step("Build", build);
await t.step("Upload", upload);
await t.step("Verify", verify);
t.success("Deployment complete!");
Output:
Deploying
> Build
> Upload
> Verify
> Deployment complete!
Built-in prompts with zero config:
const name = await ctx.ask.text("Project name:", "my-app");
const port = await ctx.ask.select("Port:", ["3000", "8080"]);
const features = await ctx.ask.multiselect("Features:", ["auth", "api", "db"]);
const confirmed = await ctx.ask.confirm("Continue?");
Everything you need, included:
import { spinner, progress, table, box, colors } from "easycli-ui";
// Spinner
const s = spinner("Loading...");
s.start();
await load();
s.success("Done!");
// Progress bar
const bar = progress(100);
bar.update(50);
bar.complete();
// Table
console.log(table([
{ Name: "Alice", Role: "Admin" },
{ Name: "Bob", Role: "User" }
]));
// Box
console.log(box("Important message", {
title: "Notice",
borderStyle: "rounded"
}));
// Colors
console.log(colors.green("Success!"));
console.log(colors.bold(colors.cyan("Title")));
npm install easycli-core easycli-ui
import { defineCLI } from "easycli-core";
const cli = defineCLI({
name: "hello",
version: "1.0.0",
commands: {
greet: {
description: "Say hello",
args: { name: "string" },
run({ name }) {
console.log(`Hello, ${name}!`);
}
}
}
});
cli.run();
Perfect for:
npx create-easycli my-cli
cd my-cli
npm run dev