Skip to content
AgileLogics
7 min read

Projects with deps.edn and the Clojure CLI

Prerequisites: Namespaces

The official Clojure CLI (clj / clojure) builds a classpath from a deps.edn file and runs Clojure programs. It isn't a build tool — compiling jars is done by the tools.build library, called from the CLI.

A project

inventory/
├── deps.edn
├── build.clj
├── src/inventory/core.clj
├── src/inventory/db.clj
├── resources/config.edn
└── test/inventory/core_test.clj
;; illustrative — deps.edn
{:paths ["src" "resources"]

 :deps {org.clojure/clojure {:mvn/version "1.12.6"}
        org.clojure/data.json {:mvn/version "2.5.2"}
        com.github.seancorfield/next.jdbc {:mvn/version "1.3.1118"}}

 :aliases
 {:run   {:main-opts ["-m" "inventory.core"]}
  :dev   {:extra-paths ["dev"]
          :extra-deps {org.clojure/test.check {:mvn/version "1.1.3"}}}
  :test  {:extra-paths ["test"]
          :extra-deps {io.github.cognitect-labs/test-runner
                       {:git/tag "v0.5.1" :git/sha "dfb30dd"}}
          :main-opts ["-m" "cognitect.test-runner"]
          :exec-fn cognitect.test-runner.api/test}
  :build {:deps {io.github.clojure/tools.build {:mvn/version "0.10.14"}}
          :ns-default build}}}
  • :paths — source and resource folders on the classpath.
  • :deps — libraries from Maven Central or Clojars (:mvn/version), Git repositories (:git/tag + :git/sha), or local folders (:local/root).
  • :aliases — named variations: extra paths, extra deps, and what to run. The versions above are examples; check each project's README for the current coordinates.

Running things

clj                         # REPL with the project's classpath
clj -M:dev                  # REPL with the :dev alias added
clj -M:run 8080             # run inventory.core/-main with args
clj -M -m inventory.core    # the same, without an alias
clj -X:test                 # run tests (exec-fn style)
clj -T:build uber           # run the build.clj function "uber"
clj -Spath                  # print the classpath
clj -X:deps tree            # print the dependency tree
  • -M runs clojure.main (a -main function or a script).
  • -X calls a function that takes a map of arguments (clj -X:run :port 8080).
  • -T runs a tool with only the tool's own classpath.

Adding a library at the REPL

;; illustrative — Clojure 1.12 REPL started with clj
(add-lib 'hiccup/hiccup {:mvn/version "2.0.0"})
(require '[hiccup2.core :as h])
(str (h/html [:p "added without restarting"]))

Clojure 1.12's add-lib loads a new dependency into a running REPL — in keeping with the "never restart" workflow. Add it to deps.edn afterwards so the project remembers it.

Where libraries come from

  • Maven Central — Java libraries and official Clojure libraries (org.clojure/...).
  • Clojars (clojars.org) — the community repository for Clojure libraries. The CLI searches both automatically.
  • Find libraries on clojure-toolbox.com and the Clojurians Slack.