clj exec update

A new prerelease version of clj is now available ( and it includes some important restructuring of how you use clj.

This version has not yet been promoted to “stable” release. You can either install it explicitly with that version though:

  • On Linux, use the instructions here but with
  • On Mac, use a versioned release:
    • brew uninstall clojure
    • brew install clojure/tools/clojure@
  • The Windows scripts have not yet been updated for this release but I will get those out next week.

Execution options

The big picture for the changes is that we are focusing on three main execution options:

  • clj (no args) to start a REPL
  • clj -X - execute a function that takes a map, with support for command-line overrides
  • clj -M - execute clojure.main

We have expanded the capabilities of -X in several ways since the last release. First, -X can now take multiple aliases and those alias can refer to argmaps that include any of the argmap keys (:extra-deps, :override-deps, etc) so you can supply the deps and the function to execute together. Second, you can optionally pass the function on the command line after the alias (basically replacing the former -F option). And third, there are some new argmap keys, :ns-default and :ns-aliases, that can be used to set up either a default namespace or namespace aliases to make it easier to supply those functions.

-M was an existing option (only) for supplying :main-opts to clojure.main. We are moving towards making this a required option to execute clojure.main programs. As such, -M can now be used without an alias to pass args to clojure.main like clj -M -m my.namespace. Or you can now use -M to pass one or more aliases that can include any of the prior argmap keys (:extra-deps etc) in addition to :main-opts. Previously, this was often done with -A for tools.

To ease this transition a bit, you can still use -A to specify :main-opts, and you can still invoke clojure.main without -M for now but you will get a warning suggesting the use of -M for this instead.

Other argmap key changes:

  • :fn and :args were renamed to :exec-fn and :exec-args for -X
  • :deps and :paths (previously used with -T or -A) have been renamed to :replace-deps and :replace-paths. The old names still work for now but will print a warning.

The alias options taking smaller argmaps -T, -R, -C, and -O have all been removed and will suggest using -X, -M, or -A instead. Note that -A still exists and can continue to be used to supply argmap args. The ad hoc function execution option -F has been removed as -X now covers that.


A new option -P has been added to “prepare” an execution. This option will download deps, cache the classpath, but not actually perform an execution. You can use it with any of the other execution options (or none), so works kind of like –dry-run in other tools. You might find this helpful when preparing a container to ensure you don’t need to later download jars, etc.

We would be happy to hear feedback about this and how well it works for you!

Deps programs

The expanded capabilities of -X described above have been used to offload some of the special “-S” programs in clj into provided programs accessible via -X. Since the beginning, clj has shipped with a built-in :deps alias that adds the latest version of org.clojure/tools.deps.alpha to your deps. That alias has been extended to also set a :ns-default namespace to and you can now use that in lieu of -Stree, -Spom, and -Sresolve-tags:

  • clj -X:deps tree
  • clj -X:deps mvn-pom
  • clj -X:deps git-resolve-tags

Additionally, the mvn local jar installer program that was detailed in the last prerelease can similarly be used with:

  • clj -X:deps mvn-install

The old options have been removed and will suggest these alternatives instead if you try to use them. These options are also doc’ed in the clj -h help.

Docs and feedback

As the prerelease version has continued to diverge pretty far from stable, I’ve updated and moved the docs into a prerelease-specific version of the reference.

If you have feedback, would be happy to see it, probably at the #tools-deps channel in Clojurians Slack is the best place right now. We are hoping to switch this over to the new stable release relatively soon, but would be great for tool-makers and users to try this out prior to the switch.

Written on September 4, 2020