Skip to content

dahlia/optique

Repository files navigation

Optique: Type-safe combinatorial CLI parser for TypeScript

JSR npm GitHub Actions

Warning

The API is stabilizing, but may change before the 1.0 release.

Type-safe combinatorial CLI parser for TypeScript inspired by Haskell's optparse-applicative and TypeScript's Zod. Build composable parsers for command-line interfaces with full type safety, automatic type inference, and built-in shell completion support for Bash, zsh, fish, PowerShell, and Nushell.

Note

Optique is a parsing library that focuses on extracting and validating command-line arguments. It doesn't dictate your application's structure, handle command execution, or provide scaffolding—it simply transforms command-line input into well-typed data structures.

Features

  • Parser combinators: object(), or(), merge(), optional(), multiple(), map(), and more for composable CLI parsing
  • Full type safety: Automatic TypeScript type inference for all parser compositions with compile-time validation
  • Rich value parsers: Built-in parsers for strings, numbers, URLs, locales, UUIDs, temporal types (via @optique/temporal), Zod schemas (via @optique/zod), and Valibot schemas (via @optique/valibot)
  • Shell completion: Automatic completion script generation for Bash, zsh, fish, PowerShell, and Nushell
  • Smart error messages: “Did you mean?” suggestions for typos with context-aware error formatting
  • Automatic help generation: Beautiful help text with usage formatting, labeled sections, and colored output
  • Multi-runtime support: Works seamlessly with Deno, Node.js, and Bun
  • CLI integration: Complete CLI setup with run() function including help, version, and completion support

Quick example

import { object, option, optional, or, merge, constant } from "@optique/core/parser";
import { string, integer } from "@optique/core/valueparser";
import { run, print } from "@optique/run";

// Reusable parser components
const commonOptions = object({
  verbose: option("-v", "--verbose"),
  config: optional(option("-c", "--config", string())),
});

// Mutually exclusive deployment strategies
const localDeploy = object({
  mode: constant("local" as const),
  path: option("--path", string()),
  port: option("--port", integer({ min: 1000 })),
});

const cloudDeploy = object({
  mode: constant("cloud" as const),
  provider: option("--provider", string()),
  region: option("--region", string()),
  apiKey: option("--api-key", string()),
});

// Compose parsers with type-safe constraints
const parser = merge(
  commonOptions,
  or(localDeploy, cloudDeploy)
);

const config = run(parser, { help: "both" });
// config: {
//   readonly verbose: boolean;
//   readonly config: string | undefined;
// } & (
//   | {
//       readonly mode: "local";
//       readonly path: string;
//       readonly port: number;
//   }
//   | {
//       readonly mode: "cloud";
//       readonly provider: string;
//       readonly region: string;
//       readonly apiKey: string;
//   }
// )

// TypeScript knows exactly what's available based on the mode
if (config.mode === "local") {
  print(`Deploying to ${config.path} on port ${config.port}.`);
} else {
  print(`Deploying to ${config.provider} in ${config.region}.`);
}

Docs

Optique provides comprehensive documentation to help you get started quickly: https://optique.dev/.

API reference documentation for each package is available on JSR (see below).

Packages

Optique is a monorepo which contains multiple packages. The main package is @optique/core, which provides the shared types and parser combinators. The following is a list of the available packages:

Package JSR npm Description
@optique/core JSR npm Shared types and parser combinators
@optique/run JSR npm Runner for Node.js/Deno/Bun
@optique/temporal JSR npm Temporal value parsers (date and time)
@optique/valibot JSR npm Valibot schema integration for validation
@optique/zod JSR npm Zod schema integration for validation