Declarative command-line parsing for OCaml
  • OCaml 72.7%
  • Text 23.8%
  • Shell 1.7%
  • Dune 1%
  • Awk 0.6%
  • Other 0.2%
Find a file
2026-09-08 12:44:05 +02:00
.github Upgrade CI 2026-09-08 12:44:05 +02:00
.vscode Add spell entry 2026-04-29 16:55:00 +02:00
doc Remove some unused ppx 2026-04-29 16:49:44 +02:00
script/ci-packages Prepare configuration of 5.5 CI packages 2026-04-29 21:00:53 +02:00
src Avoid ppxlib direct deps here (simplify) 2026-05-08 14:02:00 +02:00
test Remove unused ppx 2026-04-29 16:55:07 +02:00
.gitattributes Initialize project 2024-08-08 06:59:24 +02:00
.gitignore Ignore local coverage script 2025-09-12 10:30:27 +02:00
.headache.config Add headache config 2025-09-12 10:29:49 +02:00
.headache.exclude Add header exclusion config 2026-03-17 12:26:53 +01:00
.ocamlformat Upgrade ocamlformat to 0.29.0 2026-03-24 09:52:20 +01:00
CHANGES.md Edit changelog 2026-05-08 14:18:07 +02:00
cmdlang-dev.opam Remove some unused ppx 2026-04-29 16:49:44 +02:00
cmdlang-stdlib-runner.opam Require dune.3.17 2024-12-16 10:34:15 +01:00
cmdlang-stdlib-runner.opam.template Add opam template file and configure more fields 2024-12-02 13:20:52 +01:00
cmdlang-tests.opam Remove some unused ppx 2026-04-29 16:49:44 +02:00
cmdlang-tests.opam.template Add opam template file and configure more fields 2024-12-02 13:20:52 +01:00
cmdlang-to-base.opam Avoid ppxlib direct deps here (simplify) 2026-05-08 14:02:00 +02:00
cmdlang-to-base.opam.template Add opam template file and configure more fields 2024-12-02 13:20:52 +01:00
cmdlang-to-climate.opam Upgrade deps to latest climate 2025-08-13 23:25:19 +02:00
cmdlang-to-climate.opam.template Add opam template file and configure more fields 2024-12-02 13:20:52 +01:00
cmdlang-to-cmdliner.opam Require dune.3.17 2024-12-16 10:34:15 +01:00
cmdlang-to-cmdliner.opam.template Add opam template file and configure more fields 2024-12-02 13:20:52 +01:00
cmdlang.opam Require dune.3.17 2024-12-16 10:34:15 +01:00
cmdlang.opam.template Add opam template file and configure more fields 2024-12-02 13:20:52 +01:00
CODE_OF_CONDUCT.md Adopt OCaml code of conduct 2024-08-12 16:53:49 +02:00
CODEOWNERS Initiate code owners file for GH 2026-02-01 08:04:51 +01:00
COPYING.HEADER Add headache config 2025-09-12 10:29:49 +02:00
dune Initialize project 2024-08-08 06:59:24 +02:00
dune-project Avoid ppxlib direct deps here (simplify) 2026-05-08 14:02:00 +02:00
dune-workspace.4.14 Upgrade CI 2026-09-08 12:44:05 +02:00
dune-workspace.5.2 Upgrade CIs 2026-04-12 13:37:29 +02:00
dune-workspace.5.3 Upgrade CIs 2026-04-12 13:37:29 +02:00
dune-workspace.5.4 Enable 5.4 in CI 2026-04-29 16:20:03 +02:00
dune-workspace.5.5 Upgrade CI 2026-09-08 12:44:05 +02:00
dunolint Add test package invariant 2026-01-01 19:59:30 +01:00
headache.sh Remove left-over unused var (shellcheck) 2026-03-17 12:26:54 +01:00
LICENSE Add headache config 2025-09-12 10:29:49 +02:00
Makefile Refactor err & err-cli 2024-09-03 22:16:01 +02:00
README.md Revise rationale for cmdlang development 2025-10-07 14:51:50 +02:00

cmdlang

CI Status Coverage Status Deploy Doc Status

Declarative Command-line Parsing for OCaml.

Synopsis

Cmdlang is a library for creating command-line parsers in OCaml. Implemented as an OCaml EDSL, its declarative specification language lives at the intersection of other well-established similar libraries.

Cmdlang doesn't include an execution engine. Instead, Cmdlang parsers are automatically translated to cmdliner, core.command, or climate commands for execution.

Our goal is to provide an approachable, flexible, and user-friendly interface while allowing users to choose the backend runtime that best suits their needs.

Documentation

Cmdlang's documentation is published here.

Rationale

⚠️ The following section was written when the development of cmdlang first started - a time when in particular cmdliner.2.0 didn't exist yet. The version 2.0 of cmdliner implements support for auto-completion, making part of our analysis no longer up-to-date (See also #33).


The OCaml community currently has two popular libraries for declarative command-line argument parsing:

  1. cmdliner
  2. core.command, base's Command module.

There is also a third library under development:

  1. climate, aiming to support autocompletion scripts and other conventions.

The following table reflects our understanding and preferences (ranked 1-3, most preferred first) as of the early days of cmdlang (your mileage may vary):

Library Runtime (eval) Ergonomic (mli) CLI conventions Man pages Auto-complete
cmdliner Battled-tested 2 1 Yes No
core.command Battled-tested 2 3 No Yes
climate (Under Construction) 1 1 No Yes

Programming Interface: We find the type separation between the Arg & Param types proposed by climate to be the easiest to understand among the three models.

CLI syntax support: Both cmdliner and climate support established conventions. We find that these conventions are harder to achieve with core.command, especially regarding its handling of long flag name arguments beginning with a single -.

The cmdlang developers are enthusiastic to the prospect of compatible ways of working with these libraries.

As developers of CLI tools written in OCaml, we aim to avoid a strong commitment to any single library if possible, especially concerning the runtime aspects. This is particularly relevant for new commands written today.

In this spirit, we created cmdlang, a new library that offers a unique twist: it doesn't implement its own runtime. Instead, it translates its parsers into cmdliner, core.command, or climate parsers, making it compatible with all their execution engines.

Our current preferred target is depicted below, but other combinations are possible:

Library Runtime (eval) Ergonomic (mli) CLI conventions Man pages Auto-complete
cmdlang Battled-tested 1 1 Yes Yes*
via cmdliner inspired by climate cmdliner cmdliner Hybrid*

* Auto-completion: we plan to say more about it in the doc in the near future.

Due to its architecture, cmdlang can be a helpful tool for implementing effective migration paths to transition from one of the existing libraries to another.

We initiated the library as part of another project where we are migrating some commands from core.command to cmdliner, with the desire to make it easy to experiment with climate in the future.

Architecture

cmdlang is composed of several parts:

  1. Core Specification Language:

    • A kernel command-line parsing specification language written as an OCaml EDSL.
    • Covers the intersection of what is expressible in cmdliner, core.command, and climate.
  2. OCaml Library:

    • Exposes a single module, Cmdlang.Command, with no dependencies, to build command-line parsers in total abstraction using ergonomic helpers.
    • Supports various styles for writing command-lines, including ( let+ ) and ppx_let's let%map or let%map_open.
    • Designed with ocaml-lsp in mind for user-friendly in-context completion.
  3. Translation Libraries:

    • Convert cmdlang parsers at runtime into cmdliner, core.command, or climate parsers
    • Packaged as separate helper libraries to keep dependencies isolated.
  4. Basic execution runner based on stdlib.arg:

    • A proof-of-concept execution engine implemented on top of stdlib.arg.

Experimental Status

cmdlang is currently under construction and considered experimental. We are actively seeking feedback to validate our design and engage with other declarative command-line enthusiasts.

Acknowledgements

  • We are grateful for the years of accumulated work and experience that have resulted in high-quality CLI libraries like cmdliner and core.command.
  • climate's early programming interface was a great source of inspiration. We are very thankful for their work on auto-completion and excited to see where the climate project goes next.
  • We are inspired by the diataxis approach to technical documentation, which we use to structure our documentation.