Optique Documentation

website·Indexed 33 days ago

https://optique.dev/

A type-safe CLI parser and framework featuring a comprehensive patterns cookbook for subcommands, mutually exclusive options, and dependent values. It includes support for config file loading via Standard Schema (Zod, Valibot, ArkType), Bash completion generation, command discovery from the file system, and interactive prompt integration via @optique/clack.

Tokens
133.9K
Snippets
555
Records
660
Agent score
58%

What's inside Optique

  1. Overview of Optique runtime context systems

    Optique provides two systems for handling runtime data that is not part of command-line arguments (e.g., config files, environment variables, or shared locale settings):

    1. Annotations: A low-level primitive for injecting runtime data directly into parsers. Use this for direct control or when implementing a source context.
    2. Source Context: A high-level system for composing multiple data sources with automatic priority handling and two-phase parsing. Use this when building new data sources (e.g., a secrets manager).

    Annotations are non-invasive, symbol-keyed for type safety and conflict avoidance, and are accessed via low-level APIs like parse(), parseSync(), and parseAsync().

  2. Overview of Optique parser combinators

    Optique is a type-safe combinatorial CLI parser that uses composable functions instead of configuration objects to infer TypeScript types automatically. The core building blocks include:

    • option() and argument(): For individual CLI elements.
    • object(): To group parsers into structured results.
    • or(): For mutually exclusive alternatives.
    • optional(), multiple(), and merge(): For flexible composition.
  3. Implement inter-option dependencies in Optique

    Inter-option dependencies allow one option's valid values to depend on another option's value, enabling dynamic validation and context-aware shell completion. This is achieved by creating a 'dependency source' and a 'derived parser'. Optique defers final validation of dependent options until all options are parsed, then replays the dependent parsers with the resolved dependency values. This system is independent of the order in which options appear on the command line.
  4. Understand Optique's architectural advantages for CLI development

    Optique distinguishes itself from other JS/TS CLI libraries (like Commander.js, Yargs, and oclif) through several key structural features:

    • Zero Runtime Dependencies: The core of Optique has no runtime dependencies. Integration packages (e.g., @optique/clack, @optique/config, @optique/standard-schema) only add dependencies when explicitly used.
    • Unified Parser for Multiple Outputs: A single parser definition drives argument parsing, --help generation, shell completion for five different shells (including async and context-aware suggestions), and Unix man page generation via @optique/man.
    • Standard Schema Integration: Optique is the only library in its class to integrate the Standard Schema spec via @optique/standard-schema, allowing any compatible validator to act as a value parser. It also provides specialized adapters for Zod and Valibot.
    • Combinator Model: Unlike the builder or declarative APIs found in most CLI libraries, Optique uses a combinator model based on composable parsers to achieve superior type inference and composition.
  5. Use automatic 'Did you mean?' suggestions for CLI typos

    Optique automatically provides 'Did you mean?' suggestions when users make typos in option or command names. This feature uses Levenshtein distance to find matches within an edit distance of 3 characters and a distance ratio of at most 50% of the input length. It suggests up to 3 closest matches using case-insensitive comparison. If a custom unexpectedInput error is provided, suggestions are not added automatically; you must use the suggestions formatter to include them.
    import { object } from "@optique/core/constructs";
    import { option } from "@optique/core/primitives";
    import { run } from "@optique/run";
    
    const parser = object({
      verbose: option("--verbose"),
      version: option("--version"),
      verify: option("--verify"),
    });
    
    // User types '--verbos' instead of '--verbose'
    run(parser, { args: ["--verbos"] });
    // Output: Error: No matched option for `--verbos`. Did you mean `--verbose`?
  6. Optique Integration Packages Overview

    Optique provides several optional integration packages to extend parsing capabilities:

    • @optique/env: Binds values to environment variables.
    • @optique/keyring: Async fallback to OS credential store for secrets.
    • @optique/config: Loads values from config files with schema validation (Zod, Valibot, ArkType).
    • @optique/standard-schema: Uses Standard Schema-compatible validators as value parsers.
    • @optique/clack / @optique/inquirer: Fallback to interactive prompts.
    • @optique/zod / @optique/valibot: Direct use of Zod/Valibot schemas as parsers.
    • @optique/git: Async parsers for Git references.
    • @optique/temporal: Parsers for Temporal date/time types.
    • @optique/man: Generates Unix man pages.
    • @optique/logtape: Parsers for LogTape sink configuration.
  7. Compare Optique with other JavaScript/TypeScript CLI libraries

    Optique uses a type-first parser combinator approach, which differs from the fluent builders, declarative configs, or class-based styles found in other libraries. It is designed to excel in three specific scenarios: mutually exclusive option groups (using typed unions), shared option groups across subcommands (via parser merging), and complex value resolution (CLI args → env vars → config file → interactive prompt).
  8. Compare Optique and oclif for CLI development

    Choose between Optique and oclif based on whether you need a full framework or a lightweight library.

    oclif is a comprehensive framework that provides project scaffolding, file-based command discovery, a production-grade plugin system, and automatic README generation. It is ideal for large, extensible enterprise CLI products (e.g., Salesforce, Heroku, Shopify CLIs).

    Optique is a zero-dependency parsing-and-resolution library. It focuses on composition and type-safe parsing. It is better suited for focused tools where a full framework would be overkill, or when you want to bring your own command loader and project structure.

  9. Optique Feature Overview

    Optique is a type-first, composable argument parser. Key features and advantages include:

    • Zero Runtime Dependencies: @optique/core has no dependencies.
    • Advanced Generation: Generates man pages and shell completions for five different shells (including async suggestions).
    • Validation: Uses Standard Schema-compatible validators as value parsers and provides rich adapters for Zod and Valibot.
    • Structural Composition: Uses combinators like or() for discriminated unions and merge() for shared options.
  10. Compare Optique and Cleye for CLI development

    Cleye is a small, focused command-line argument parser for Node.js that excels at turning process.argv into a typed object with automatic --help generation. It is ideal for flat CLIs and minimal footprints. Optique is a more comprehensive tool that supports composition, fallback chains (CLI > Env > Config > Prompt), and structural constraints encoded in the type system. Optique is zero-dependency and compatible with Node.js, Deno, and Bun.
  11. Group CLI options and arguments using the `object()` parser

    The object() parser combines multiple named parsers (such as arguments and options) into a single parser that produces a structured object. This is the primary method for grouping related CLI inputs into logical units. You can use InferValue to automatically derive the TypeScript type of the resulting object.
    import { object } from "@optique/core/constructs";
    import type { InferValue } from "@optique/core/parser";
    import { argument, option } from "@optique/core/primitives";
    import { string, integer } from "@optique/core/valueparser";
    
    const serverConfig = object({
      name: argument(string({ metavar: "NAME" })),
      port: option("-p", "--port", integer({ min: 1, max: 0xffff })),
      host: option("-h", "--host", string()),
      verbose: option("-v", "--verbose")
    });
    
    type ServerConfig = InferValue<typeof serverConfig>;
  12. Create type-safe enumerations using the choice() parser

    The choice() parser restricts input to a predefined set of string or number values. It produces exact string or number literal types in TypeScript rather than generic types, ensuring type safety for options like log levels, output formats, or port numbers.
    import { choice } from "@optique/core/valueparser";
    
    // String choices (type: "debug" | "info" | "warn" | "error")
    const logLevel = choice(["debug", "info", "warn", "error"]);
    
    // Number choices (type: 8 | 10 | 12)
    const bitDepth = choice([8, 10, 12]);