Mark McGranaghan

My Clojure Development Setup

March 2 2010

In this post I describe my local Clojure development setup. You might find this useful if you are setting up a Clojure environment on your own machine.

I have tried to keep the setup very simple. This makes the environment easier to use, maintain, and debug.

For an editor, I use TextMate with a TextMate Clojure bundle. TextMate is an unusual choice among Clojure hackers but has worked well for me. As you will see, I’ve designed my setup so that the editor is independent of the rest of the environment. So if you prefer another editor things will work fine.

I don’t run any Clojure code from within the editor: both the REPL and scripts are run from the command line using the following clj script:

JAVA="java -Xmx"`freembytes`"m"

if [ -z "$1" ]; then
  rlwrap $JAVA -cp `cljcp` clojure.contrib.repl_ln
  $JAVA -cp `cljcp` clojure.main $USER_CLJ_DIR/run.clj $@

Running clj with no arguments boots into a Clojure REPL. Running clj <path> invokes the Clojure script at the given path.

clj relies on two other scripts. The first is freembytes, which determines how much free RAM my machine has to offer the JVM:

FREEPAGES=`vm_stat | head -2 | tail -1 | awk '{print $3}'`
echo "(4096*$FREEPAGES)/1048576" | bc

The second is cljcp, which builds a Java classpath:



for file in lib/*.jar; do


echo $CP

When clj starts a REPL, it looks for a user.clj on the classpath. I have the following in ~/Clojure/user.clj:

(use 'clojure.contrib.repl-utils 'clj-stacktrace.repl)

(defn quit []
  (System/exit 0))

This provides access to the clj-stacktrace REPL utilities and defines a handy quit function.

When the clj runs script files, it uses ~/Clojure/run.clj, which is as follows:

(use 'clj-stacktrace.repl)
(import 'clojure.lang.Compiler)

(let [script-path (first *command-line-args*)
      script-args (rest  *command-line-args*)]
  (binding [*command-line-args*  script-args
            *warn-on-reflection* true]
      (Compiler/loadFile script-path)
      (catch Exception e
        (pst-on *err* true e)
        (System/exit 1)))))

This script print warnings when the Clojure compiler is using Java reflection and pretty-prints any exception stacktraces with clj-stacktrace.

Finally, I manage dependencies using Leiningen. You can find good instructions for installing and useing Leiningen on the linked site. The Leiningen command lein deps pulls all dependencies required by a project into the local lib director, which is then picked up by the cljcp script and therefore available for use at the REPL and for running scripts.