Designing effective command-line interfaces requires balancing functionality with usability. Well-designed CLI tools follow established patterns that enhance user experience while maintaining efficiency and scriptability.
๐ฏ Core Design Principles
Simplicity and Clarity
CLI tools should have intuitive command structures and clear help systems.
| # Good: Clear, predictable naming
git commit -m "Message"
git push origin main
# Avoid: Cryptic abbreviations
tool -xzf file.tgz # What does xzf mean?
# Better: Self-documenting flags
tar --extract --gzip --file=file.tgz
|
Follow established conventions within the ecosystem.
| # Standard flag patterns
--help, -h # Help information
--version, -V # Version information
--verbose, -v # Verbose output
--quiet, -q # Quiet mode
--output, -o # Output destination
--input, -i # Input source
|
๐ Help and Documentation Patterns
Comprehensive Help Systems
Effective help should be contextual and progressive.
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | # Basic help
command --help
# Detailed man page
man command
# Example usage in help
command --help
# Examples:
# command process input.txt
# command --format json --output result.json
# Web documentation link
command --docs
|
Self-Documenting Interfaces
Commands should be understandable from their structure.
| # Clear subcommand structure
kubectl get pods
kubectl describe pod my-pod
kubectl delete pod my-pod
# Intuitive flag grouping
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a aac output.mp4
|
Standard Streams Usage
Proper handling of stdin, stdout, and stderr.
1
2
3
4
5
6
7
8
9
10
11
12 | # Read from stdin when no args
cat file.txt | process
process < file.txt
# Write to stdout by default
process file.txt > output.txt
# Error messages to stderr
echo "Error: Invalid input" >&2
# Progress to stderr, results to stdout
process large-file.txt 2>progress.log >results.txt
|
Support multiple input/output formats gracefully.
1
2
3
4
5
6
7
8
9
10
11
12 | # Format specification
tool --format json input.txt
tool --format yaml input.txt
tool --format csv input.txt
# Auto-detection based on extension
tool data.json # JSON input
tool data.yaml # YAML input
tool data.csv # CSV input
# Explicit format override
tool --input-format xml --output-format json data.xml
|
โ๏ธ Configuration Patterns
Layered Configuration
Multiple configuration sources with clear precedence.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | # Precedence order (highest to lowest):
# 1. Command-line flags
# 2. Environment variables
# 3. Local config file (.toolrc)
# 4. User config (~/.config/tool/config)
# 5. System config (/etc/tool/config)
# Environment variable example
export TOOL_TIMEOUT=30
export TOOL_FORMAT=json
# Config file example (~/.toolrc)
timeout = 30
format = json
verbose = false
|
Progressive Disclosure
Show basic options by default, advanced options on demand.
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | # Basic usage shows common flags
command --help
# Usage: command [OPTIONS] INPUT
# Options:
# -h, --help Show help
# -v, --version Show version
# -o, --output Output file
# Advanced help shows all options
command --help-all
# Advanced Options:
# --debug Enable debug logging
# --threads N Number of worker threads
# --buffer-size Internal buffer size
|
๐จ User Experience Enhancements
Interactive Features
Smart defaults and helpful prompts when appropriate.
| # Interactive mode for ambiguous situations
tool deploy
# Multiple environments found: dev, staging, prod
# Which environment? [dev]:
# Confirmation for destructive operations
tool delete important-data
# Are you sure you want to delete important-data? [y/N]:
# Tab completion support
# Install with: tool completion bash > /etc/bash_completion.d/tool
|
Visual Feedback
Appropriate progress indication and status reporting.
| # Progress bar for long operations
Processing files [####################] 100% | 50/50 files
# Spinner for indeterminate progress
โ Analyzing data...
# Color-coded output
echo -e "\033[32mSUCCESS\033[0m Operation completed"
echo -e "\033[31mERROR\033[0m Operation failed"
|
๐ ๏ธ Scripting and Automation Patterns
Exit Codes and Signals
Clear, documented exit status codes.
1
2
3
4
5
6
7
8
9
10
11
12 | # Standard exit codes
exit 0 # Success
exit 1 # General error
exit 2 # Misuse of shell builtins
exit 126 # Command cannot execute
exit 127 # Command not found
exit 128+N # Fatal error signal N
# Custom exit codes for specific conditions
exit 10 # Configuration error
exit 11 # Network error
exit 12 # Permission denied
|
Machine-Readable Output
Options for automation-friendly output.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | # Default human-readable output
tool status
# Service: running
# Uptime: 2 hours
# Memory: 128MB
# JSON output for scripts
tool status --json
# {
# "service": "running",
# "uptime": "2h",
# "memory": "128MB"
# }
# Quiet mode for scripts
if tool check --quiet; then
echo "Check passed"
fi
|
๐ Discovery and Exploration
Intuitive Subcommand Structure
Hierarchical organization that reveals functionality.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | # Root help shows main commands
git --help
# Available commands:
# add Add file contents to index
# commit Record changes to repository
# push Update remote refs
# config Get/set repository options
# Nested help for complex tools
kubectl --help
# Basic Commands:
# create Create a resource
# delete Delete a resource
# get Display resources
#
# Advanced Commands:
# apply Apply configuration
# rollout Manage deployments
|
Smart Defaults and Sensible Behavior
Tools should work well out-of-the-box.
| # Sensible defaults
mkdir -p project/{src,tests,docs}
# Creates directory structure without errors if exists
# Context-aware behavior
git status
# Automatically detects git repository root
# Reasonable timeouts
curl --max-time 30 https://example.com
# Prevents hanging on slow/unresponsive sites
|
๐งพ Summary Guidelines
Do:
โ
Follow established conventions
โ
Provide clear, contextual help
โ
Handle standard streams properly
โ
Use progressive disclosure
โ
Return appropriate exit codes
โ
Support machine-readable output
โ
Implement smart defaults
โ
Offer configuration flexibility
Don't:
โ Use cryptic abbreviations
โ Ignore standard input/output conventions
โ Mix concerns in single commands
โ Require excessive configuration
โ Produce inconsistent output formats
โ Forget about error handling
โ Neglect accessibility considerations
๐ง Best Practices
- Start Simple: Begin with core functionality and add features gradually
- Test Extensively: Verify behavior across different environments and edge cases
- Document Everything: Clear examples are worth a thousand words
- Consider Your Audience: Balance power user needs with newcomer accessibility
- Maintain Compatibility: Avoid breaking changes; use deprecation cycles
- Embrace Standards: Follow POSIX guidelines and community conventions
- Plan for Growth: Design extensible interfaces from the start
๐งพ See Also