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 simpleargumentsparser
cargo 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 npm
const parseCLI = require("simpleargumentsparser"); (async () => { const cli = await parseCLI(); 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!`); } })();
import parseCLI from "simpleargumentsparser"; (async () => { const cli = await parseCLI(); if (cli.noArgs) { console.log(cli.color.yellow("No arguments provided")); } })();
use simpleargumentsparser::parse_cli; use std::process; fn main() { let cli = parse_cli(); if cli.s.contains_key("h") || cli.c.contains_key("help") { exit("Help Menu:\n\nThis is just an example"); } } fn exit(msg: &str) { println!("{}", msg); process::exit(0); }
#include "simpleargumentsparser.hpp" #include <iostream> int main(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; return 0; } return 0; }
#!/bin/bash source ./parseCLI parse_cli "$@" if cli s h || cli c help; then cli color bold cyan "My Script v1.0.0" fi
The 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 tracking p: false, // Piped input (string or false) e: [], // Separator positions (--) noArgs: false,// True if no arguments provided argc: 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 // true cli.s.h // true
# With values
$ myapp -n John -p 3000cli.s.n // "John" cli.s.p // "3000"
# Combined flags
$ myapp -lvkcli.s.l // true cli.s.v // true cli.s.k // true
Double-dash options that support hyphenated names.
# Boolean options
$ myapp --verbose --debugcli.c.verbose // true cli.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 backend
cli.o // [["init", 1], ["project", 2], ["backend", 3]]
Automatically captured when data is piped into your CLI.
$ echo "Hello World" | myapp
cli.p // "Hello World"
# Combine with arguments $ cat data.txt | myapp --process
cli.p // "Contents of data.txt" cli.c.process // true
Track positions of -- separators for command chaining.
$ myapp cmd1 -v -- cmd2 -d -- cmd3
cli.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 application console.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 messages console.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 output const name = "Manolo"; console.log(`Hello ${cli.color.bold.yellow(name)}, welcome!`); // Status badges console.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 simulation console.log(`${cli.color.magenta("const")} ${cli.color.cyan("name")} = ${cli.color.green('"value"')};`);
const parseCLI = require("simpleargumentsparser"); (async () => { const cli = await parseCLI(); // Help menu if (cli.s.h || cli.c.help) { showHelp(cli); process.exit(0); } // Version if (cli.c.version) { console.log(cli.color.bold("v1.0.0")); process.exit(0); } // Validation if (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 input if (cli.p) { console.log(cli.color.blue("Processing piped input...")); processInput(cli.p); } // Verbose mode const verbose = cli.s.v || cli.c.verbose; if (verbose) { console.log(cli.color.dim("Verbose mode enabled")); } // Debug mode if (cli.c["debug-args"]) { console.log(cli.color.magenta("Debug: Arguments")); console.log(JSON.stringify(cli, null, 2)); } })(); function showHelp(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 `); } function processInput(input) { console.log(cli.color.green("β") + " Processed:", input); }
import parseCLI from "simpleargumentsparser"; import * as fs from "fs"; interface Config { input: string; output: string; verbose: boolean; } const loadFile = (filename: string): string | null => { try { return fs.readFileSync(filename, { encoding: "utf-8" }); } catch (e) { return null; } }; (async () => { const cli = await parseCLI(); const config: Config = { input: cli.c.input as string || "input.txt", output: cli.c.output as string || "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}`)); } const content = 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 script source ./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/bash source ./parseCLI parse_cli "$@" # Validation if cli noArgs; then cli color red "Error: Arguments required" exit 1 fi # Help if 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 input if 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/bash source ./parseCLI parse_cli "$@" # Helper functions info() { 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 logic if cli noArgs; then error "No arguments provided" show_help exit 1 fi if cli s h || cli c help; then show_help exit 0 fi if 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 commands if 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 mode if cli c debug; then warning "Debug mode active" cli print fi
Run 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; fn main() { let cli = parse_cli(); let mut 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!"); } if let Some(p) = &cli.p { println!("Hello {}", p); } if cli.c.contains_key("debug-arguments") { println!("{:#?}", cli); } } fn exit(msg: &str) { println!("{}", msg); process::exit(0); }
The Rust version features a fluent builder pattern for color styling:
use simpleargumentsparser::parse_cli; fn main() { let cli = parse_cli(); // Basic colors with direct application println!("{}", cli.color.red("Error message")); println!("{}", cli.color.green("Success!")); println!("{}", cli.color.blue("Information")); // Chaining styles println!("{}", cli.color.bold().red("Bold red text")); println!("{}", cli.color.underline().yellow("Underlined yellow")); println!("{}", cli.color.bold().italic().cyan("Bold italic cyan")); // Bright colors println!("{}", cli.color.bright_red("Bright red")); println!("{}", cli.color.bright_green("Bright green")); // Background colors with chaining println!("{}", 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 styling println!("{}", cli.color.bold().underline().paint("Explicitly painted text")); }
For more concise color combinations, use the color! macro:
use simpleargumentsparser::color; fn main() { // Combine multiple styles in one line println!("{}", 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")); }
pub struct CLI { pub s: HashMap<String, String>, // Single-dash arguments (-v, -h) pub c: HashMap<String, String>, // Double-dash arguments (--verbose, --help) pub o: Vec<(String, usize)>, // Positional arguments with indices pub p: Option<String>, // Piped input (None if no pipe) pub e: Vec<usize>, // Error indices pub no_args: bool, // True if no arguments provided pub argc: usize, // Argument count pub color: 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 echo echo "Hello from pipe" | cargo run --example basic # Using cat with a file cat Cargo.toml | cargo run --example basic -- --debug-arguments # Combined with arguments printf "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> int main(int argc, char* argv[]) { CLI cli = parseCLI(argc, argv); // Check for help flag using JSValue's implicit bool conversion if (cli.s["h"] || cli.c["help"]) { std::cout << cli.color["bold"]["cyan"]("My C++ Tool") << " v1.0.0" << std::endl; return 0; } // Verbose mode if (cli.s["v"] || cli.c["verbose"]) { std::cout << cli.color["dim"]("Verbose mode enabled") << std::endl; } // Piped input if (!cli.p.empty()) { std::cout << "Hello " << cli.color["blue"](cli.p) << std::endl; } return 0; }
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> void exit(const std::string& msg) { std::cout << msg << std::endl; std::exit(0); } int main(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=true if (!json.empty()) { std::cout << json << std::endl; } } return 0; }
#include "simpleargumentsparser.hpp" #include <iostream> #include <sstream> using namespace std; void showColorShowcase(const CLI& 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"; } int main(int argc, char* argv[]) { CLI cli = parseCLI(argc, argv); if (cli.c["showcase"]) { showColorShowcase(cli); } return 0; }
- 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 input echo "Hello from pipe" | ./example
Contributions 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