CLI lite parser for Node and Deno
CliteParser generate CLI from a class (or plain object), each method generate a βcommandβ, each field generate an βoptionβ. example-lite.ts example :
#!/usr/bin/env -S deno run
import { cliteRun } from "jsr:@jersou/clite@0.6.0";
// or after "deno add @jersou/clite" : import { cliteRun } from "@jersou/clite";
// or for Node usage, after "npx jsr add @jersou/clite" (same import from "@jersou/clite")
class Tool {
retry = 2;
dryRun = false; // fields are converted to kebab case as global options
webUrl = "none"; // β --web-url
main() {
console.log("main command", this);
}
up() {
console.log("up command", this);
}
down(force: boolean, timeout: number) {
console.log("down command", { force, timeout }, this);
}
}
cliteRun(new Tool());The help is generated automatically:

Run the commands with options and arguments
# βββββββββββββ options ββββββββββββ β command β β cmd args β
$ ./simple.ts --dry-run --web-url=tttt --retry 4 down true 14
down command { force: true, timeout: 14 } Tool { retry: 4, dryRun: true, webUrl: "tttt" }
$ ./simple.ts down true 14 # βββ default options from class init βββ
down command { force: true, timeout: 14 } Tool { retry: 2, webUrl: "none", no_color: undefined }
$ ./simple.ts --dry-run --webUrl=tttt # β same case of the field name works too : --webUrl or --web-url
main command Tool { retry: 2, dryRun: true, webUrl: "tttt" } # β main is the default command
$ deno https://raw.githubusercontent.com/jersou/clite-parser/refs/heads/main/examples/simple.ts --dry-run --web-url tttt --retry 4 down true 14
down command { force: true, timeout: 14 } Tool { retry: 4, dryRun: true, webUrl: "tttt" }Examples
Several examples can be found in examples/ folder.
Full example with decorators (Typescript)
Works with vanilla typescript or with experimentalDecorators = true
import { alias, cliteRun, help } from "jsr:@jersou/clite@0.6.0";
@help("This tool is a little example of CliteParser") // optional description
class Tool {
@alias("r") // optional alias -r for --retry
retry = 2;
@help("no changes mode") // optional description for "--dry-run" field
dryRun = false; // fields are converted to kebab case as global options
webUrl = "none"; // β --web-url
main() {
console.log("main command", this);
}
@help("create and start") // optional description for "up" command
up() {
console.log("up command", this);
}
down(force: boolean, timeout: number) {
console.log("down command", { force, timeout }, this);
}
}
cliteRun(new Tool());The help is generated automatically:

Full example without decorator (Javascript)
import { cliteRun } from "jsr:@jersou/clite@0.6.0";
class Tool {
_help = "This tool is a little example of CliteParser"; // optional description
_retry_alias = "r"; // optional alias -r for --retry
retry = 2;
_dryRun_help = "no changes mode"; // optional description for "--dry-run" field
dryRun = false; // fields are converted to kebab case as global options
webUrl = "none"; // β --web-url
main() {
console.log("main command", this);
}
_up_help = "create and start"; // optional description for "up" command
up() {
console.log("up command", this);
}
down(force, timeout) {
console.log("down command", { force, timeout }, this);
}
}
cliteRun(new Tool());The help is generated automatically (same as the previous):

Decortator @* or inline field _<field name>_*
Fields can be extended with description, type or aliases using decorators or
_<field name>_* field.
Help description with the @help decorator or inline help
import { cliteRun, help } from "jsr:@jersou/clite@0.6.0";
@help("This tool is a little example of CliteParser")
class Tool {
retry = 2;
webUrl = "none"; // fields are converted to kebab case as global options
@help("skip colorize") // optional description for "no_color" field
no_color?: string | boolean; // β --no-color
main() {
console.log("main command", this);
}
@help("create and start") // optional description for "up" command
up() {
console.log("up command", this);
}
down(force: boolean, timeout: number) {
console.log("down command", { force, timeout }, this);
}
}
cliteRun(new Tool());Without decorator : optional fields _<filed or method name>_help or
_<filed or method name>_desc are displayed as description in the help (_desc
is deprecated) :
#!/usr/bin/env -S deno run -A
import { cliteRun } from "jsr:@jersou/clite@0.6.0";
class Tool {
_help = "This tool is a little example of CliteParser"; // optional description
retry = 2;
webUrl = "none"; // fields are converted to kebab case as global options
no_color?: string | boolean; // β --no-color
_no_color_help = "skip colorize"; // optional description for "no_color" field
_up_help = "create and start"; // optional description for "up" command
main() {
console.log("main command", this);
}
up() {
console.log("up command", this);
}
down(force: boolean, timeout: number) {
console.log("down command", { force, timeout }, this);
}
}
if (import.meta.main) { // if the file is imported, do not execute this block
cliteRun(new Tool());
}Alias
Alias of option can be created, with the @alias decorator or with
_<field name>_alias :
#!/usr/bin/env -S deno run -A
import { cliteRun } from "../clite_parser.ts";
import { alias, help, type } from "../src/decorators.ts";
class Tool {
@alias("a")
all?: boolean;
@alias("r")
retry = 2;
@alias("w")
webUrl = "none";
@alias("nb")
@alias("n")
@help("n & b")
@type("boolean")
no_color?: string | boolean;
main() {
console.log("main command", this);
}
}Produce the help :
...
Options:
-h, --help Show this help [default: false]
-a, --all
-r, --retry [default: 2]
-w, --web-url [default: "none"]
-n, --nb, --no-color n & b [boolean]Short parameters can be aggregated, -an here :
$ ./alias-with-decorator.ts -an -r 8
main command Tool { all: true, retry: 8, webUrl: "none", no_color: true }-an = -a -n
Example without the @alias decorator :
class Tool {
_all_alias = "a";
all?: boolean;
_retry_alias = "r";
retry = 2;
_webUrl_alias = "w";
webUrl = "none";
_no_color_alias = ["nb", "n"];
_no_color_help = "n & b";
_no_color_type = "boolean";
no_color?: string | boolean;
main() {
console.log("main command", this);
}
}@types
@defaultHelp
@negatable
Argument parsing
Clite use @std/cli, based on minimist.
Kebab case or the same name
Example : webUrl field can be set by --webUrl or --web-url:
$ ./simple.ts --web-url test
main command Tool { retry: 2, dryRun: false, webUrl: "test" }
$ ./simple.ts --webUrl test
main command Tool { retry: 2, dryRun: false, webUrl: "test" }Passing objects :
--ac.bb aaa --ac.dd.ee v --ac.dd.ff w
β { ac: { bb: "aaa", dd: { ee: "v", ff: "w" } } }Warning: boolean parameter without value preceding the command
If a boolean param without value is used before the command, you must:
- separate the boolean and the command by a double hyphen
-- - or use a value :
--dry-run=trueor--dry-run true
Otherwise, the command will be interpreted as the value of boolean parameter.
Default command
- If there is only one method/command => this method is the default
- If the main method exist => main is the default
- else => no default method
$ ./example-lite.ts
main command Tool { retry: 2, webUrl: "none", no_color: undefined }Boolean options
$ ./example-lite.ts
main command Tool { retry: 2, webUrl: "none", no_color: undefined }
$ ./example-lite.ts --no-color
main command Tool { retry: 2, webUrl: "none", no_color: true }
$ ./example-lite.ts --no-color=false
main command Tool { retry: 2, webUrl: "none", no_color: "false" }
$ ./example-lite.ts --no-color=true
main command Tool { retry: 2, webUrl: "none", no_color: "true" }Ignore _* and #* methods and fields (in the help)
Fields and methods that start with β_β are ignored.
_privateData = 12;
_privmethod() {
console.log("this method is not visible in the help (starts with '_')");
}Note: this βprivateβ method can be run by the CLI, itβs useful during the development.
Note2: js private fields #* are also ignored :
#privateData = 12;
#privmethod() {
console.log("this method is not visible in the help (starts with '#')");
}Plain Object
A plain JS Object can be used :
import { cliteRun } from "jsr:@jersou/clite@0.6.0";
cliteRun({
retry: 2,
main() {
console.log("main command", this);
},
_up_help: "create and start the services",
up(svc: string, timeout = 10) {
console.log("up command", { svc, timeout, retry: this.retry });
},
down(svc: string) {
console.log("down command", { svc, retry: this.retry });
},
});$ ./plain_object_lite.ts --retry=77 up foo 123
up command { svc: "foo", timeout: "123", retry: "77" }
$ /plain_object_lite.ts --help
Usage: <Object file> [Options] [--] [command [command args]]
Commands:
main (default)
up <svc> <timeout> create and start the services
down <svc>
Options:
--retry=<RETRY> (default "2")
--help Show this helpPrint the help on error
If printHelpOnError is enable, the help is print if any error is thrown while
the command execution. Else, the help is print only for errors that have
{ cause: { clite: true } }.
Itβs useful if a required option is missing, for example.
CliteRunConfig
cliteRun(new Tool(), < optional CliteRunConfig > )
type CliteRunConfig = {
args?: string[]; // default : Deno.args or process.argv.slice(2)
dontPrintResult?: boolean; // default false : false, print the command return
noCommand?: boolean; // no default command : do not run "main" methode if no arg
printHelpOnError?: boolean; // print the help if an error is thrown and then re-throw the error
mainFile?: string; // allows to change the name of the file in the help, instead of the default <{Class name} file>
meta?: ImportMeta; // import.meta to use : don't run if the file is imported, and use import.meta.url in the help
configCli?: boolean; // enable "--config <path>" to load json config before processing the args, Show in the help if it's a string
dontConvertCmdArgs?: boolean; // don't convert "true"/"false" to true/false in command arguments, and not to number after --
};Return value
If the method run by cliteRun return a value != undefined, it will be print in
stdout.
This behavior can be disabled with the config :
cliteRun(new Tool(), { dontPrintResult: true })
noCommand
cliteRun(new Tool(), { noCommand: true }); β ./example-no-command.ts ---help
give :
This tool is a "no-command" example of CliteParser usage
Usage: <Tool file> [Options] [--] [args]
Options:
--retry=<RETRY> (default "2")
--web-url=<WEB_URL> web URL ... (default "none")
--no-color=<NO_COLOR> skip colorize
--help Show this helpprintHelpOnError
Print the help if an error is thrown and then re-throw the error:
import { cliteRun } from "jsr:@jersou/clite@0.6.0";
export class Tool {
throw = "true";
main() {
if (this.throw === "true") {
throw new Error("add --throw=false option !");
}
console.log("OK !");
}
}
cliteRun(new Tool(), { printHelpOnError: true });To print help on specific error without printHelpOnError=true, use
{ cause: { clite: true } } :
import { cliteRun } from "jsr:@jersou/clite@0.6.0";
export class Tool {
noThrow = false;
main() {
if (!this.noThrow) {
throw new Error("add --no-throw option !", { cause: { clite: true } });
}
console.log("OK !");
}
}
cliteRun(new Tool());configCli : load config with --config <path
TODO for Node
If configCli === true in CliteRunConfig
$ cat ./load-config.ts
...
cliteRun(new Tool(), { configCli: true });
$ ./load-config.ts --help
...
--config Use this file to read option before processing the args [string]
...
$ ./load-config.ts down
down command { force: undefined, timeout: undefined } Tool { retry: 2, dryRun: false, webUrl: "none" }
$ cat load-config.json
{ "retry": 44, "dryRun": true, "webUrl": "yyy" }
$ ./load-config.ts --retry 88 --config ./load-config.json down
down command { force: undefined, timeout: undefined } Tool {
retry: 88,
dryRun: false,
webUrl: "yyy",
config: "./load-config.json"
}mainFile
Allows to change the name of the file in the help, instead of the default for
example <Tool file>.
cliteRun(new Tool(), { mainFile: "my-tool" });β¦will change the usage line in the help :
Usage: my-tool [Options] [--] [command [command args]]meta
Use meta to avoid the import.meta.main check :
if (import.meta.main) { // if the file is imported, do not execute this block
cliteRun(new Tool());
}is equivalent to :
cliteRun(new Tool(), { meta: import.meta });The basename of import.meta.url will be used in the generated help, as βmainFileβ.
This feature does not work with NodeJS (no import.meta.main).
dontConvertCmdArgs
If -- is used and dontConvertCmdArgs=true, all command arguments will be
strings.
Node support : npx jsr add @jersou/clite
Run npx jsr add @jersou/clite and then, import with
import { cliteRun } from "@jersou/clite"; :
import { cliteRun } from "@jersou/clite"; // after "npx jsr add @jersou/clite"
class Tool { ... }
cliteRun(new Tool());See node usage examples :