A lightweight, powerful CLI argument parser for Node.js, Bash, Rust, and C++ with built-in ANSI color support
- Overview
- Features
- Installation
- Quick Start
- API Reference
- Examples
- Bash Version
- Rust Version
- C++ Version
- License
simpleArgumentsParser is a zero-dependency CLI argument parser designed for simplicity and speed. Unlike heavyweight alternatives, it provides exactly what you need: fast argument parsing, pipe support, and a beautiful color system—all in a compact package.
- 🚀 Fast & Lightweight - Zero dependencies, minimal overhead
- 🎨 Built-in Colors - ANSI color system with chainable styles
- 🔄 Pipe Support - Handle piped input seamlessly
- 📦 Multi-Language - Available for Node.js (JS/TS), Rust, C++, and Bash
- 🎯 Simple API - Intuitive syntax, minimal learning curve
- ⚡ TypeScript Ready - Full TypeScript support with type definitions
✨ Argument Parsing
- Single-dash flags (
-v,-h) - Double-dash options (
--verbose,--help) - Multi-flag support (
-lvk→-l -v -k) - Hyphenated options (
--add-new-item) - Position tracking for positional arguments
- Piped input detection and handling
🎨 Color System
- Text styles (bold, italic, underline, dim, blink, invert)
- 8 standard colors + 8 bright variants
- Background colors
- Chainable style combinations
- Works in Node.js, Rust, C++, and Bash
npm install simpleargumentsparsercargo add simpleargumentsparser# Copy the single header file
cp other_languages/cpp/simpleargumentsparser.hpp /your/project/include/git clone https://github.com/stringmanolo/simpleargumentsparser
cd simpleargumentsparser/other_languages/bash
# You can also use npmconstparseCLI=require("simpleargumentsparser");(async()=>{constcli=awaitparseCLI();if(cli.s.h||cli.c.help){console.log(`${cli.color.bold.cyan("My CLI Tool")} - v1.0.0`);console.log(`${cli.color.green("✓")} Ready to use!`);}})();importparseCLIfrom"simpleargumentsparser";(async()=>{constcli=awaitparseCLI();if(cli.noArgs){console.log(cli.color.yellow("No arguments provided"));}})();use simpleargumentsparser::parse_cli;use std::process;fnmain(){let cli = parse_cli();if cli.s.contains_key("h") || cli.c.contains_key("help"){exit("Help Menu:\n\nThis is just an example");}}fnexit(msg:&str){println!("{}", msg);
process::exit(0);}#include"simpleargumentsparser.hpp"
#include<iostream>intmain(int argc, char* argv[]) {
CLI cli = parseCLI(argc, argv);
if (cli.s["h"] || cli.c["help"]) {
std::cout << cli.color["bold"]["cyan"]("My C++ Tool") << " v1.0.0" << std::endl;
return0;
}
return0;
}#!/bin/bashsource ./parseCLI
parse_cli "$@"if cli s h || cli c help;then
cli color bold cyan "My Script v1.0.0"fiThe parser returns an object with the following properties:
{s: {},// Single-dash arguments (-v, -h)c: {},// Double-dash arguments (--verbose, --help)o: [],// Positional arguments with position trackingp: false,// Piped input (string or false)e: [],// Separator positions (--)noArgs: false,// True if no arguments providedargc: 0,// Argument count (excludes piped input)color: {}// Color system API}Single-dash flags that can be combined or have values.
# Boolean flags
$ myapp -v -hcli.s.v// truecli.s.h// true# With values
$ myapp -n John -p 3000cli.s.n// "John"cli.s.p// "3000"# Combined flags
$ myapp -lvkcli.s.l// truecli.s.v// truecli.s.k// trueDouble-dash options that support hyphenated names.
# Boolean options
$ myapp --verbose --debugcli.c.verbose// truecli.c.debug// true# With values
$ myapp --name John --output-dir ./buildcli.c.name// "John"cli.c["output-dir"]// "./build"Non-flag arguments tracked by position.
$ myapp init project backendcli.o// [["init", 1], ["project", 2], ["backend", 3]]Automatically captured when data is piped into your CLI.
$ echo"Hello World"| myappcli.p// "Hello World"# Combine with arguments
$ cat data.txt | myapp --processcli.p// "Contents of data.txt"cli.c.process// trueTrack positions of -- separators for command chaining.
$ myapp cmd1 -v -- cmd2 -d -- cmd3cli.e// [3, 6]Helper properties for quick validation.
if(cli.noArgs){console.log("Please provide arguments");process.exit(1);}console.log(`Received ${cli.argc} argument(s)`);// Direct color applicationconsole.log(cli.color.red("Error message"));console.log(cli.color.green("Success!"));console.log(cli.color.blue("Information"));cli.color.bold("Bold text")cli.color.dim("Dimmed text")cli.color.italic("Italic text")cli.color.underline("Underlined text")cli.color.blink("Blinking text")cli.color.invert("Inverted colors")cli.color.black("Black")cli.color.red("Red")cli.color.green("Green")cli.color.yellow("Yellow")cli.color.blue("Blue")cli.color.magenta("Magenta")cli.color.cyan("Cyan")cli.color.white("White")cli.color.brightBlack("Bright Black")cli.color.brightRed("Bright Red")cli.color.brightGreen("Bright Green")cli.color.brightYellow("Bright Yellow")cli.color.brightBlue("Bright Blue")cli.color.brightMagenta("Bright Magenta")cli.color.brightCyan("Bright Cyan")cli.color.brightWhite("Bright White")cli.color.bgBlack("Black background")cli.color.bgRed("Red background")cli.color.bgGreen("Green background")cli.color.bgYellow("Yellow background")cli.color.bgBlue("Blue background")cli.color.bgMagenta("Magenta background")cli.color.bgCyan("Cyan background")cli.color.bgWhite("White background")Combine multiple styles for complex formatting:
cli.color.bold.red("Bold red")cli.color.underline.yellow("Underlined yellow")cli.color.bold.italic.cyan("Bold italic cyan")cli.color.bgRed.white.bold("Bold white on red")cli.color.dim.underline.brightGreen("Complex styling")// Status messagesconsole.log(`${cli.color.green("✓")}${cli.color.bold("Success:")} File saved`);console.log(`${cli.color.red("✗")}${cli.color.bold("Error:")} File not found`);console.log(`${cli.color.yellow("⚠")}${cli.color.bold("Warning:")} Deprecated API`);console.log(`${cli.color.blue("ℹ")}${cli.color.bold("Info:")} Loading...`);// Formatted outputconstname="Manolo";console.log(`Hello ${cli.color.bold.yellow(name)}, welcome!`);// Status badgesconsole.log(`${cli.color.bgGreen.black.bold(" SUCCESS ")} Operation completed`);console.log(`${cli.color.bgRed.white.bold(" ERROR ")} Connection failed`);console.log(`${cli.color.bgYellow.black.bold(" WARNING ")} Low memory`);// Code highlighting simulationconsole.log(`${cli.color.magenta("const")}${cli.color.cyan("name")} = ${cli.color.green('"value"')};`);constparseCLI=require("simpleargumentsparser");(async()=>{constcli=awaitparseCLI();// Help menuif(cli.s.h||cli.c.help){showHelp(cli);process.exit(0);}// Versionif(cli.c.version){console.log(cli.color.bold("v1.0.0"));process.exit(0);}// Validationif(cli.noArgs&&!cli.p){console.log(cli.color.red("Error: No input provided"));console.log(`Use ${cli.color.cyan("--help")} for usage information`);process.exit(1);}// Process piped inputif(cli.p){console.log(cli.color.blue("Processing piped input..."));processInput(cli.p);}// Verbose modeconstverbose=cli.s.v||cli.c.verbose;if(verbose){console.log(cli.color.dim("Verbose mode enabled"));}// Debug modeif(cli.c["debug-args"]){console.log(cli.color.magenta("Debug: Arguments"));console.log(JSON.stringify(cli,null,2));}})();functionshowHelp(cli){console.log(`${cli.color.bold.cyan("My CLI Tool")}${cli.color.dim("- v1.0.0")}${cli.color.dim("=")}${"=".repeat(50)}${cli.color.bold("USAGE")} mycli [command] [options]${cli.color.bold("COMMANDS")}${cli.color.green("init")} Initialize a new project${cli.color.green("build")} Build the project${cli.color.green("deploy")} Deploy to production${cli.color.bold("OPTIONS")}${cli.color.yellow("-h, --help")} Show this help message${cli.color.yellow("-v, --verbose")} Enable verbose output${cli.color.yellow("--version")} Show version number${cli.color.yellow("--debug-args")} Show parsed arguments${cli.color.bold("EXAMPLES")}${cli.color.dim("$")} mycli init --verbose${cli.color.dim("$")} mycli build -v${cli.color.dim("$")} echo "data" | mycli process `);}functionprocessInput(input){console.log(cli.color.green("✓")+" Processed:",input);}importparseCLIfrom"simpleargumentsparser";import*asfsfrom"fs";interfaceConfig{input: string;output: string;verbose: boolean;}constloadFile=(filename: string): string|null=>{try{returnfs.readFileSync(filename,{encoding: "utf-8"});}catch(e){returnnull;}};(async()=>{constcli=awaitparseCLI();constconfig: Config={input: cli.c.inputasstring||"input.txt",output: cli.c.outputasstring||"output.txt",verbose: !!(cli.s.v||cli.c.verbose)};if(config.verbose){console.log(cli.color.dim(`Input: ${config.input}`));console.log(cli.color.dim(`Output: ${config.output}`));}constcontent=loadFile(config.input);if(!content){console.log(cli.color.red(`Error: Cannot read ${config.input}`));process.exit(1);}// Process content...console.log(cli.color.green("✓ Success"));})();# Clone or download the repository
git clone https://github.com/stringmanolo/simpleargumentsparser
cd simpleargumentsparser/other_languages/bash
# Source in your scriptsource ./parseCLI
# Send the commands you want the lib to parse. "$@" for all the cli commands
parse_cli "$@"| Feature | JavaScript | Bash |
|---|---|---|
| No arguments | cli.noArgs | cli noArgs |
| Single flag | cli.s.h | cli s h |
| Double flag | cli.c.help | cli c help |
| Piped input | cli.p | $(cli p) |
| Positional args | cli.o | cli o |
| Color output | cli.color.red("text") | cli color red "text" |
#!/bin/bashsource ./parseCLI
parse_cli "$@"# Validationif cli noArgs;then
cli color red "Error: Arguments required"exit 1
fi# Helpif cli s h || cli c help;then
cli color bold cyan "My Bash Script v1.0.0"echo""
cli color green "Usage: $0 [options]"exit 0
fi# Process arguments
verbose=false
if cli s v || cli c verbose;then
verbose=true
cli color dim yellow "Verbose mode enabled"fi# Handle piped inputif cli p found;then
cli color blue "Processing piped input..."
input=$(cli p)echo"Received: $input"fi# Basic colors
cli color red "Error message"
cli color green "Success message"
cli color yellow "Warning"# Text styles
cli color bold "Bold text"
cli color italic "Italic text"
cli color underline "Underlined"# Chained styles
cli color bold red "Bold red"
cli color underline yellow "Underlined yellow"
cli color bold white bg_red "White on red background"# Bright colors
cli color bright_red "Bright red"
cli color bright_green "Bright green"
cli color bright_cyan "Bright cyan"# Background colors
cli color bg_black white "White on black"
cli color bg_red white "White on red"
cli color bg_green black "Black on green"#!/bin/bashsource ./parseCLI
parse_cli "$@"# Helper functionsinfo() {
cli color cyan "[INFO] $1"
}
success() {
cli color green "[✓] $1"
}
error() {
cli color bold red "[✗] $1"
}
warning() {
cli color yellow "[⚠] $1"
}
show_help() {
cli color bold cyan "My Bash Tool"echo""
cli color white "Usage: $0 [command] [options]"echo""
cli color bold "Commands:"echo" start Start the service"echo" stop Stop the service"echo" status Check status"echo""
cli color bold "Options:"echo" -h, --help Show this help"echo" -v, --verbose Verbose output"echo" --version Show version"
}
# Main logicif cli noArgs;then
error "No arguments provided"
show_help
exit 1
fiif cli s h || cli c help;then
show_help
exit 0
fiif cli c version;then
cli color bold "Version 1.0.0"exit 0
fi# Verbose mode
verbose=false
if cli s v || cli c verbose;then
verbose=true
info "Verbose mode enabled"fi# Process commandsif cli o 1 | grep -q "start";then
info "Starting service..."
success "Service started"elif cli o 1 | grep -q "stop";then
info "Stopping service..."
success "Service stopped"elif cli o 1 | grep -q "status";then
info "Checking status..."
cli color blue "Service is running"else
error "Unknown command"
show_help
exit 1
fi# Debug modeif cli c debug;then
warning "Debug mode active"
cli print
fiRun the included color showcase example:
cd other_languages/bash
./colorsExample.shCheck freednsBashClient for a real app using parseCLI
The Rust version of simpleArgumentsParser provides a type-safe, zero-dependency argument parser with a fluent API for colors.
Add to your Cargo.toml:
[dependencies]
simpleargumentsparser = "2.1.0"use simpleargumentsparser::parse_cli;use std::process;fnmain(){let cli = parse_cli();letmut verbose = false;if cli.no_args{exit("Arguments needed");}if cli.s.contains_key("h") || cli.c.contains_key("help"){exit("Help Menu:\n\nThis is just an example");}if cli.s.contains_key("v") || cli.c.contains_key("verbose"){
verbose = true;}if cli.c.contains_key("version"){exit("V0.0.1");}if cli.s.contains_key("s"){println!("Hello!");}ifletSome(p) = &cli.p{println!("Hello {}", p);}if cli.c.contains_key("debug-arguments"){println!("{:#?}", cli);}}fnexit(msg:&str){println!("{}", msg);
process::exit(0);}The Rust version features a fluent builder pattern for color styling:
use simpleargumentsparser::parse_cli;fnmain(){let cli = parse_cli();// Basic colors with direct applicationprintln!("{}", cli.color.red("Error message"));println!("{}", cli.color.green("Success!"));println!("{}", cli.color.blue("Information"));// Chaining stylesprintln!("{}", cli.color.bold().red("Bold red text"));println!("{}", cli.color.underline().yellow("Underlined yellow"));println!("{}", cli.color.bold().italic().cyan("Bold italic cyan"));// Bright colorsprintln!("{}", cli.color.bright_red("Bright red"));println!("{}", cli.color.bright_green("Bright green"));// Background colors with chainingprintln!("{}", cli.color.bg_red().white("White text on red background"));println!("{}", cli.color.bg_blue().bright_white("Bright white on blue"));// Using paint() for explicit stylingprintln!("{}", cli.color.bold().underline().paint("Explicitly painted text"));}For more concise color combinations, use the color! macro:
use simpleargumentsparser::color;fnmain(){// Combine multiple styles in one lineprintln!("{}", color!(bold red "Bold red text"));println!("{}", color!(underline yellow "Underlined yellow"));println!("{}", color!(bg_blue bright_white "White on blue background"));println!("{}", color!(bold italic cyan "Bold italic cyan"));println!("{}", color!(bg_red white blink "Blinking white on red"));}pubstructCLI{pubs:HashMap<String,String>,// Single-dash arguments (-v, -h)pubc:HashMap<String,String>,// Double-dash arguments (--verbose, --help)pubo:Vec<(String,usize)>,// Positional arguments with indicespubp:Option<String>,// Piped input (None if no pipe)pube:Vec<usize>,// Error indicespubno_args:bool,// True if no arguments providedpubargc:usize,// Argument countpubcolor:Color,// ANSI color system with builder pattern}# Basic example with arguments
cargo run --example basic -- -v --debug-arguments
# Colored example showcase
cargo run --example colored -- --showcase
# Specific color demonstrations
cargo run --example colored -- --colors
cargo run --example colored -- --bright
cargo run --example colored -- --backgrounds
# The example binary
cargo run --bin cli-example -- -h
cargo run --bin cli-example -- --version# Using echoecho"Hello from pipe"| cargo run --example basic
# Using cat with a file
cat Cargo.toml | cargo run --example basic -- --debug-arguments
# Combined with argumentsprintf"Line 1\nLine 2"| cargo run --bin cli-example -- -v- Zero Dependencies - Pure Rust implementation
- Builder Pattern - Fluent API for color styling
- Memory Safe - Rust's ownership model ensures safety
- Macro Support -
color!macro for concise styling - Cross-Platform - Works on Windows, macOS, Linux
- Complete Color System - 8 standard colors, 8 bright variants, backgrounds, and styles
- Piped Input Support - Automatic detection of stdin input
The C++ version of simpleArgumentsParser is a single-header library providing a lightweight, zero-dependency CLI argument parser with full ANSI color support. Designed for C++17 and above, it offers a similar API to the JavaScript and Rust versions with C++ idioms.
Simply copy the header file to your project:
# Copy the single header file
cp other_languages/cpp/simpleargumentsparser.hpp /your/project/include/Or include it directly:
#include"simpleargumentsparser.hpp"No build system configuration required - it's header-only!
#include"simpleargumentsparser.hpp"
#include<iostream>intmain(int argc, char* argv[]) {
CLI cli = parseCLI(argc, argv);
// Check for help flag using JSValue's implicit bool conversionif (cli.s["h"] || cli.c["help"]) {
std::cout << cli.color["bold"]["cyan"]("My C++ Tool") << " v1.0.0" << std::endl;
return0;
}
// Verbose modeif (cli.s["v"] || cli.c["verbose"]) {
std::cout << cli.color["dim"]("Verbose mode enabled") << std::endl;
}
// Piped inputif (!cli.p.empty()) {
std::cout << "Hello " << cli.color["blue"](cli.p) << std::endl;
}
return0;
}The C++ version uses bracket notation for color access:
// Basic colors
std::cout << cli.color["red"]("Error message") << std::endl;
std::cout << cli.color["green"]("Success!") << std::endl;
// Text styles
std::cout << cli.color["bold"]("Bold text") << std::endl;
std::cout << cli.color["underline"]("Underlined text") << std::endl;
// Chained styles with bracket notation
std::cout << cli.color["bold"]["red"]("Bold red text") << std::endl;
std::cout << cli.color["underline"]["yellow"]("Underlined yellow") << std::endl;
// Bright colors
std::cout << cli.color["brightRed"]("Bright red") << std::endl;
std::cout << cli.color["brightGreen"]("Bright green") << std::endl;
// Background colors
std::cout << cli.color["bgRed"]["white"]("White on red") << std::endl;
std::cout << cli.color["bgBlue"]["white"]("White on blue") << std::endl;#include"simpleargumentsparser.hpp"
#include<iostream>
#include<cstdlib>voidexit(const std::string& msg) {
std::cout << msg << std::endl;
std::exit(0);
}
intmain(int argc, char* argv[]) {
CLI cli = parseCLI(argc, argv);
bool verbose = false;
if (cli.noArgs) exit("Arguments needed");
if (cli.s["h"] || cli.c["help"]) exit("Help Menu:\n\nThis is just an example");
if (cli.s["v"] || cli.c["verbose"]) verbose = true;
if (cli.c["version"]) exit("V0.0.1");
if (cli.s["s"]) std::cout << "Hello!" << std::endl;
if (!cli.p.empty()) std::cout << "Hello " << cli.p << std::endl;
if (cli.c["debug-arguments"]) {
std::string json = cli.toJSON(4, true); // indent=4, tryUseJQ=trueif (!json.empty()) {
std::cout << json << std::endl;
}
}
return0;
}#include"simpleargumentsparser.hpp"
#include<iostream>
#include<sstream>usingnamespacestd;voidshowColorShowcase(constCLI& cli) {
cout << "\n" << cli.color["bold"]["brightCyan"]("CLI COLOR SYSTEM SHOWCASE") << "\n\n";
// Text styles
cout << cli.color["bold"]("Bold text") << "\n";
cout << cli.color["italic"]("Italic text") << "\n";
cout << cli.color["underline"]("Underlined text") << "\n\n";
// Standard colors
cout << cli.color["red"]("Red") << "";
cout << cli.color["green"]("Green") << "";
cout << cli.color["yellow"]("Yellow") << "";
cout << cli.color["blue"]("Blue") << "\n\n";
// Chained combinations
cout << cli.color["bold"]["red"]("Bold Red") << "\n";
cout << cli.color["underline"]["green"]("Underlined Green") << "\n";
cout << cli.color["italic"]["blue"]("Italic Blue") << "\n";
// Background combinations
cout << cli.color["bgRed"]["white"]("White on Red") << "\n";
cout << cli.color["bgGreen"]["black"]("Black on Green") << "\n";
}
intmain(int argc, char* argv[]) {
CLI cli = parseCLI(argc, argv);
if (cli.c["showcase"]) {
showColorShowcase(cli);
}
return0;
}- Single-header library - Just include
simpleargumentsparser.hpp - Zero dependencies - Only uses standard C++17 library
- Type-safe API - Uses
std::variantandJSValuewrapper - Full ANSI color system - Bracket notation for colors (
["color"]["style"]) - Cross-platform - Works on Windows, macOS, and Linux
- Automatic pipe detection - Captures piped input automatically
- JSON output - Built-in JSON serialization with jq support
- Debug utilities - Built-in debugging and visualization
Compile with C++17 or later:
# Basic compilation
g++ -std=c++17 -o myapp myapp.cpp
# With optimizations
g++ -std=c++17 -O2 -o myapp myapp.cpp# Build the examples
g++ -std=c++17 -o example example.cpp
g++ -std=c++17 -o coloredExample coloredExample.cpp
# Run basic example
./example -h
./example -v --debug-arguments
# Run color showcase
./coloredExample --showcase
./coloredExample --colors --bright
# With piped inputecho"Hello from pipe"| ./exampleContributions are welcome! This library is actively maintained and improved based on real-world usage.
Found a bug or have a feature request? Please open an issue on GitHub with:
- Clear description of the problem/feature
- Steps to reproduce (for bugs)
- Expected vs actual behavior
- Your environment (Node.js version, OS, etc.)
- 📖 Documentation: See examples above
- 🐛 Issues: GitHub Issues
- 📦 npm Package: simpleargumentsparser on npm
- 📦 Crate: simpleargumentsparser on crates.io