On this page
@std/cli
Overview Jump to heading
Tools for creating interactive command line tools.
import { parseArgs } from "@std/cli/parse-args";
import { assertEquals } from "@std/assert";
// Same as running `deno run example.ts --foo --bar=baz ./quux.txt`
const args = parseArgs(["--foo", "--bar=baz", "./quux.txt"]);
assertEquals(args, { foo: true, bar: "baz", _: ["./quux.txt"] });
Add to your project Jump to heading
deno add jsr:@std/cli
See all symbols in @std/cli on
Why use @std/cli? Jump to heading
This package helps you build command‑line tools with great developer experience. It focuses on the essentials:
- Parsing flags and arguments (
parseArgs
) without heavy frameworks - Prompting for sensitive input (
promptSecret
) - Measuring display width reliably (
unicodeWidth
) for clean TTY output - Unstable extras to enhance UX: spinners, progress bars, ANSI cursor control, and interactive selects
Use it when you want a lightweight, composable toolkit for CLI utilities. For
more complex CLIs with subcommands, rich help, and config systems, you can still
start with parseArgs
and layer in your own structure.
Examples Jump to heading
import { parseArgs } from "@std/cli/parse-args";
import { promptSecret } from "@std/cli/prompt-secret";
const args = parseArgs(Deno.args, {
alias: { v: "verbose" },
boolean: ["verbose"],
string: ["out"],
});
if (args.verbose) console.log("Verbose mode on");
const token = await promptSecret("Enter API token: ");
console.log(`Writing to: ${args.out ?? "stdout"}`);
parseArgs
is lightweight and unopinionated—great for simple tools; for complex CLIs consider subcommands and help text patterns.- Booleans default to false unless present; use
--no-flag
support if needed viabooleanNegation
options. - Use
stopEarly
to treat--
as end of options and pass-through remaining args.
parseArgs: aliases, defaults, collect, negatable, unknown, and -- Jump to heading
import { parseArgs } from "@std/cli/parse-args";
const argv = [
"-v",
"--out=dist/file.txt",
"--tag",
"alpha",
"--tag",
"beta",
"--no-cache",
"--",
"--literally-a-file-flag",
];
const args = parseArgs(argv, {
alias: { v: "verbose" },
boolean: ["verbose", "cache"],
string: ["out"],
default: { out: "stdout" },
collect: ["tag"],
negatable: ["cache"],
unknown: (flag) => {
if (flag.startsWith("--") && flag !== "--") {
console.warn(`Unknown flag: ${flag}`);
return false; // drop it from parsed output
}
return true;
},
"--": true,
});
// args.tag -> ["alpha", "beta"]
// args.cache -> false (because of --no-cache)
// args.verbose -> true (because of -v)
// args.out -> "dist/file.txt"
// args["--"] -> ["--literally-a-file-flag"] (pass-through)
promptSecret: masking and clearing Jump to heading
import { promptSecret } from "@std/cli/prompt-secret";
const token = await promptSecret("Enter token: ", { mask: "*" });
// Optionally clear the prompt line after entry
await promptSecret("Press Enter to continue", { mask: "", clear: true });
unicodeWidth: simple column alignment Jump to heading
import { unicodeWidth } from "@std/cli/unicode-width";
const rows = [
["Name", "Width"],
["hello", String(unicodeWidth("hello"))],
["你好", String(unicodeWidth("你好"))],
["🐙octo", String(unicodeWidth("🐙octo"))],
];
const col1Width = Math.max(...rows.map((r) => unicodeWidth(r[0])));
for (const [a, b] of rows) {
const pad = " ".repeat(col1Width - unicodeWidth(a));
console.log(`${a}${pad} ${b}`);
}
Unstable UI helpers: spinner and progress bar Jump to heading
These APIs are marked unstable and may change.
// Spinner
import { Spinner } from "@std/cli/unstable-spinner";
const spinner = new Spinner({ message: "Fetching data..." });
spinner.start();
await new Promise((r) => setTimeout(r, 800));
spinner.stop();
// ProgressBar
import { ProgressBar } from "@std/cli/unstable-progress-bar";
const bar = new ProgressBar({ max: 5 });
for (let i = 0; i < 5; i++) {
await new Promise((r) => setTimeout(r, 300));
bar.value = i + 1;
}
bar.stop();