Skip to main content

CLI Application Example

Build a professional CLI tool with beautiful, informative output using Logluxe.

Complete CLI Example

Here's a full CLI application that demonstrates all major features:

#!/usr/bin/env node

import { log } from 'logluxe';
import { program } from 'commander';
import fs from 'fs/promises';
import path from 'path';

// ASCII Logo
function showLogo() {
log.gradient(`
╔══════════════════════════════════════╗
║ 🚀 PROJECT GENERATOR ║
║ v1.0.0 ║
╚══════════════════════════════════════╝
`, ['#667eea', '#764ba2']);
}

// Main CLI setup
program
.name('project-gen')
.description('Generate project scaffolding')
.version('1.0.0');

// Init command
program
.command('init <name>')
.description('Create a new project')
.option('-t, --template <type>', 'Template type', 'default')
.option('--no-git', 'Skip git initialization')
.option('--no-install', 'Skip dependency installation')
.action(async (name, options) => {
showLogo();
console.log('');

await initProject(name, options);
});
$ project-gen init my-app
╔══════════════════════════════════════╗
║ 🚀 PROJECT GENERATOR ║
║ v1.0.0 ║
╚══════════════════════════════════════╝
ℹ Creating project: my-app

Project Structure Creation

// Main init function
async function initProject(name: string, options: any) {
log.info(`Creating project: ${log.paint(name).cyan().bold().toString()}`);
console.log('');

// Step 1: Create directory
log.group('Creating project structure');
log.perf('create-structure');

try {
await createDirectory(name);
await createFiles(name, options.template);

log.perfEnd('create-structure');
log.success('Project structure created');
} catch (error) {
log.perfEnd('create-structure');
log.error('Failed to create structure');
log.stack(error);
process.exit(1);
}

log.end();
}
Creating Project Structure
ℹ Creating project: my-app
┌ Creating project structure
│ ⏱ Started: create-structure
│ Created: my-app/
│ Created: my-app/src/
│ Created: my-app/src/components/
│ Created: my-app/src/utils/
│ Created: my-app/tests/
│ Created: my-app/public/
│ Created: package.json
│ Created: tsconfig.json
│ Created: src/index.ts
│ Created: README.md
│ Created: .gitignore
│ ⏱ create-structure: 127ms
│ ✔ Project structure created
🎮 Try Project Logging

Git Initialization

// Step 2: Git init
if (options.git !== false) {
log.group('Initializing git');
log.perf('git-init');

try {
await initGit(name);
log.perfEnd('git-init');
log.success('Git repository initialized');
} catch (error) {
log.perfEnd('git-init');
log.warn('Git initialization failed (non-fatal)');
}

log.end();
}
Git Initialization Output
┌ Initializing git
│ ⏱ Started: git-init
│ ⏱ git-init: 45ms
│ ✔ Git repository initialized

Installing Dependencies

// Step 3: Install dependencies
if (options.install !== false) {
log.group('Installing dependencies');
log.perf('npm-install');

try {
await installDeps(name);
log.perfEnd('npm-install');
log.success('Dependencies installed');
} catch (error) {
log.perfEnd('npm-install');
log.error('Failed to install dependencies');
log.stack(error);
}

log.end();
}
Dependency Installation
┌ Installing dependencies
│ ⏱ Started: npm-install
│ ℹ Running npm install...
│ added 156 packages in 12s
│ ⏱ npm-install: 12.3s
│ ✔ Dependencies installed

Summary Display

// Show completion summary
function showSummary(name: string, options: any) {
console.log('');
log.rainbow('═'.repeat(50));
console.log('');

log.success('Project created successfully!');
console.log('');

log.tagged(`
[bold]Next steps:[/bold]

[dim]1.[/dim] cd ${name}
[dim]2.[/dim] npm run dev

[bold]Available commands:[/bold]

[cyan]npm run dev[/cyan] Start development server
[cyan]npm run build[/cyan] Build for production
[cyan]npm run test[/cyan] Run tests
`);

console.log('');
log.rainbow('═'.repeat(50));
console.log('');

log.neon('Happy coding! 🎉', 'cyan');
console.log('');
}
Project Summary
══════════════════════════════════════════════════
✔ Project created successfully!
Next steps:
1. cd my-app
2. npm run dev
Available commands:
npm run dev Start development server
npm run build Build for production
npm run test Run tests
══════════════════════════════════════════════════
Happy coding! 🎉
🎮 Try Summary Logging

Interactive Prompts

Add interactive prompts with beautiful styling:

import { log } from 'logluxe';
import readline from 'readline';

async function prompt(question: string): Promise<string> {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});

// Styled prompt
const styledQuestion = log.paint('? ').cyan().bold().toString() +
log.paint(question).white().bold().toString() + ' ';

return new Promise((resolve) => {
rl.question(styledQuestion, (answer) => {
rl.close();
resolve(answer);
});
});
}

async function selectOption(question: string, options: string[]): Promise<number> {
console.log('');
log.paint('? ').cyan().bold().print();
log.paint(question).white().bold().print();
console.log('');

options.forEach((opt, i) => {
log.tagged(` [dim]${i + 1}.[/dim] ${opt}`);
});

console.log('');

const answer = await prompt('Enter number');
return parseInt(answer) - 1;
}
Interactive Prompts
? Project name: my-awesome-app
? Choose a template:
1. React + TypeScript
2. Vue + TypeScript
3. Node.js API
4. CLI Application
? Enter number: 1
? Initialize git? (y/n) y
? Install dependencies? (y/n) y

Progress Indicators

Show progress for long-running operations:

import { log } from 'logluxe';

async function downloadWithProgress(url: string) {
const total = 100;
let current = 0;

log.info(`Downloading ${url}`);

while (current < total) {
current += Math.random() * 10;
current = Math.min(current, total);

// Progress bar
const percentage = Math.round(current);
const filled = Math.round(percentage / 2);
const empty = 50 - filled;

const bar = log.gradient('█'.repeat(filled), ['#00d2ff', '#3a7bd5']).toString();
const remaining = log.paint('░'.repeat(empty)).gray().toString();
const pct = log.paint(`${percentage}%`).cyan().bold().toString();

process.stdout.write(`\r${bar}${remaining} ${pct}`);

await sleep(100);
}

process.stdout.write('\n');
log.success('Download complete');
}
Progress Bar
ℹ Downloading https://example.com/file.zip
██████████████████████████████████████████████████ 100%
✔ Download complete

Spinner Animation

Add loading spinners:

class Spinner {
private frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
private current = 0;
private interval: NodeJS.Timeout | null = null;
private message: string;

constructor(message: string) {
this.message = message;
}

start() {
this.interval = setInterval(() => {
const frame = log.paint(this.frames[this.current]).cyan().toString();
process.stdout.write(`\r${frame} ${this.message}`);
this.current = (this.current + 1) % this.frames.length;
}, 80);
}

stop(success = true) {
if (this.interval) {
clearInterval(this.interval);
}

const icon = success
? log.paint('✓').green().toString()
: log.paint('✗').red().toString();

process.stdout.write(`\r${icon} ${this.message}\n`);
}
}

// Usage
async function performTask() {
const spinner = new Spinner('Processing files...');
spinner.start();

try {
await doLongTask();
spinner.stop(true);
} catch (error) {
spinner.stop(false);
throw error;
}
}
Spinner Animation
Processing files...
Processing files...
Processing files...
Processing files...

Help Menu Styling

Create beautiful help menus:

function showHelp() {
console.clear();

log.gradient(`
╭──────────────────────────────────────────────╮
│ MY CLI TOOL v1.0.0 │
╰──────────────────────────────────────────────╯
`, ['#667eea', '#764ba2']);

log.tagged(`
[bold]USAGE[/bold]
$ my-cli [green]<command>[/green] [dim][options][/dim]

[bold]COMMANDS[/bold]
[green]init[/green] <name> Create a new project
[green]build[/green] Build the project
[green]dev[/green] Start development server
[green]test[/green] Run tests
[green]deploy[/green] Deploy to production

[bold]OPTIONS[/bold]
[cyan]-h, --help[/cyan] Show this help message
[cyan]-v, --version[/cyan] Show version number
[cyan]-c, --config[/cyan] Path to config file
[cyan]-q, --quiet[/cyan] Suppress output
[cyan]--verbose[/cyan] Show detailed output
`);
}
$ my-cli --help
╭──────────────────────────────────────────────╮
│ MY CLI TOOL v1.0.0 │
╰──────────────────────────────────────────────╯
USAGE
$ my-cli <command> [options]
COMMANDS
init <name> Create a new project
build Build the project
dev Start development server
test Run tests
deploy Deploy to production
OPTIONS
-h, --help Show this help message
-v, --version Show version number
-c, --config Path to config file
-q, --quiet Suppress output
--verbose Show detailed output
🎮 Try Help Menu

Error Handling in CLI

Handle errors gracefully:

async function main() {
try {
await runCLI();
} catch (error) {
console.log('');
log.errorBox(error);

log.tagged(`
[dim]If this issue persists, please report it at:[/dim]
[cyan][underline]https://github.com/my/cli/issues[/underline][/cyan]
`);

process.exit(1);
}
}

// Unhandled errors
process.on('uncaughtException', (error) => {
console.log('');
log.paint(' FATAL ERROR ').white().bgRed().bold().print();
console.log('');
log.error(error.message);
log.dev(error.stack);
process.exit(1);
});
Error Output
FATAL ERROR
✖ Configuration file not found
at loadConfig (config.ts:45:11)
at main (cli.ts:23:5)
If this issue persists, please report it at:
🎮 Try Error Handling

Complete CLI Template

Here's a template you can use as a starting point:

#!/usr/bin/env node

import { log } from 'logluxe';

const VERSION = '1.0.0';
const NAME = 'my-cli';

// Parse arguments
const args = process.argv.slice(2);
const command = args[0];

// Main
async function main() {
// Show banner
if (!args.includes('--quiet')) {
showBanner();
}

// Handle commands
switch (command) {
case 'help':
case '-h':
case '--help':
showHelp();
break;

case 'version':
case '-v':
case '--version':
log.info(`${NAME} v${VERSION}`);
break;

case 'init':
await handleInit(args.slice(1));
break;

case 'build':
await handleBuild(args.slice(1));
break;

default:
if (command) {
log.error(`Unknown command: ${command}`);
log.info('Run "my-cli --help" for usage');
} else {
showHelp();
}
}
}

function showBanner() {
log.gradient(`
╔═══════════════════════════════╗
${NAME.toUpperCase()} v${VERSION}
╚═══════════════════════════════╝
`, ['#00d2ff', '#3a7bd5']);
}

async function handleInit(args: string[]) {
const name = args[0] || 'my-project';

log.info(`Initializing ${name}...`);
log.perf('init');

// Your init logic here

log.perfEnd('init');
log.success('Project initialized!');
}

async function handleBuild(args: string[]) {
log.info('Building project...');
log.perf('build');

// Your build logic here

log.perfEnd('build');
log.success('Build complete!');
}

// Run
main().catch((error) => {
log.error(error.message);
process.exit(1);
});
$ my-cli init awesome-project
╔═══════════════════════════════╗
║ MY-CLI v1.0.0 ║
╚═══════════════════════════════╝
ℹ Initializing awesome-project...
⏱ Started: init
⏱ init: 234ms
✔ Project initialized!
🎮 Try CLI Commands

Next: Express Server Example