Clojure implementation of the docopt language.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Clojure implementation of the docopt language, version 0.6, under a MIT license.


Add [docopt "0.6.1"] to your dependencies in project.clj, and import docopt.core in your clojure code. This namespace contains the public API:

  • A macro docopt wich takes up to two arguments, a docstring and an args sequence.
    The docstring is optional; if omitted, the macro will try to use the docstring of #'-main. The docstring is parsed at compile-time, and the args are matched at run-time. The args should be a sequence of command-line arguments like those passed to -main or public static void main(String[] args);.

  • A function -docopt which is the run-time equivalent of the docopt macro provided for Java interoperability.

  • A function parse which takes a docstring as argument and returns all the information extracted from it. This function is called by both docopt and -docopt.

Example - Clojure

(ns example.core
  (:use [docopt.core :only [docopt]]) ; import the docopt macro from docopt.core
(defn #^{:doc "Naval Fate.

  naval_fate ship new <name>...
  naval_fate ship <name> move <x> <y> [--speed=<kn>]
  naval_fate ship shoot <x> <y>
  naval_fate mine (set|remove) <x> <y> [--moored|--drifting]
  naval_fate -h | --help
  naval_fate --version

  -h --help     Show this screen.
  --version     Show version.
  --speed=<kn>  Speed in knots [default: 10].
  --moored      Moored (anchored) mine.
  --drifting    Drifting mine."
:version "Naval Fate, version 1.2.3." }
  -main [& args]
  (let [arg-map (docopt args)] ; with only one argument, docopt parses -main's docstring.
      (or (nil? arg-map)
          (arg-map "--help")) (println (:doc     (meta #'-main)))
      (arg-map "--version")   (println (:version (meta #'-main)))
      (arg-map "mine")        (println (if (arg-map "set") "Set" "Remove") 
                                         (arg-map "--moored")   "moored" 
                                         (arg-map "--drifting") "drifting")
                                       "mine at (" (arg-map "<x>") ", " (arg-map "<y>") ").")
      (arg-map "new")         (println "Create new" 
                                       (let [[name & more-names :as names] (arg-map "<name>")]
                                         (if (seq more-names) 
                                           (str "ships " (clojure.string/join ", " names))
                                           (str "ship " name)))
      (arg-map "shoot")       (println "Shoot at (" (arg-map "<x>") "," (arg-map "<y>") ").")
      (arg-map "move")        (println "Move" (first (arg-map "<name>")) 
                                       "to (" (arg-map "<x>") "," (arg-map "<y>")
                                       (if-let [speed (arg-map "--speed")]
                                         (str " ) at " speed " knots.")
                                         " )."))
      true                    (throw (Exception. "This ought to never happen.\n")))))

Example - Java interoperability

Assuming you're using Maven, update your pom.xml by adding a child to its repositories node


and to its dependencies node.


Import org.docopt.clj in your code and call the static method clj.docopt(String, String[]); which returns a AbstractMap<String, Object>.

import java.util.AbstractMap;
import org.docopt.clj;

public class Main {
  public static void main(String[] args) {
    String docstring = "Usage: prog [options]\n\nOptions:\n-h, --help  Print help.";
    AbstractMap<String, Object> result = clj.docopt(docstring, args);
    if (result.get("--help").toString() == "true") {
    else {
      System.out.println("You don't need help.");


Run lein test to validate all tests. The tests are automatically downloaded from the language-agnostic testcases.docopt file in the reference implementation, master branch commit 511d1c57b5. Please feel free to (re)open an issue in case this implementation falls behind.