Running scripts written in Clojure as an executable using Inlein

Do you sometimes wish you could create a smart, yet still simple utility? My usual dilemma is choosing whether to create a shell script to suit my needs, or to create a standard Java application. Now I have another handy alternative. I was just shown an interesting program called Inlein.

Inlein lets you to run Clojure written scripts without the need to care about its dependencies. This way you have all the libraries you could wish for at your disposal and yet the utility you are writing is an easily modifiable and readable text file.


The installation process for Inlein is best described on The only  real prerequisite is having JDK 7 or newer installed.

During the first run or when trying to upgrade there was a possibility of getting exception java.nio.file.AtomicMoveNotSupportedException. The workaround was to do the intended move by yourself (move the downloaded jar from /tmp to ~/.inlein/clients/inlein). This has been fixed with this commit.


The best way to lean about how to write a script for Inlein is to read the documentation.

In order to demonstrate some of its possibilities I created a script that exports list of all files in a given directory along with file's size as a JSON file. Which would be quite a challenge to do using a shell script as far as I know.

#!/usr/bin/env inlein

'{:dependencies [[org.clojure/clojure "1.8.0"]
                 [org.clojure/data.json "0.2.6"]]}

(require '[ :as json])

(when-not (and (first *command-line-args*) (second *command-line-args*))
  (println "Usage:" (System/getProperty "$0") "root-dir output-file")
  (System/exit 1))

(def rootFile ( (first *command-line-args*)))

(def files (map #(into {} [[:name (.getName %)] [:size (.length %)]]) (.listFiles rootFile)))

(with-open [wrtr ( (second *command-line-args*))]
  (.write wrtr (json/write-str files)))
The script itself is my first work so it is far from perfect. Though it does show the most important parts.

The first line contains shebang letting the system know what to use to run the script. It is necessary for direct script invocation. You do not need it if you want to invoke the script by Inlein call. Or when you are on Windows where the shebanging does not work.

The most important part of the script is the dependencies part. The rest of the script contains a regular Clojure code.

You can run the script by invoking a standard-looking command.
~ ./fileList.clj . test.json
The output file has a content of following structure.


Creating the script is quite easy because you can develop it using REPL. You can run the script on any machine with JDK and Inlein installed. The script easy to read and modify because it is a text file. Unless you run into trouble, the same script should run on any Java supported platform producing a similar results. With access to any Java library trough dependencies, you can easily work with JSON, XML and do almost anything.


The startup time is much worse in comparison with shell script. The JVM startup itself takes nearly one second which might be a deal-breaker for some usages. Memory footprint is significantly higher than for shell script.


Inlein powered scripts seem to me as an interesting way to create a handy utilities. Its limitation will probably make it impossible to replace every shell  script you are using, but it does offer much broader variety of things to do by letting you to use any Clojure or Java library available. Interoperability and extensibility are the strongest sides of Inlein scripts.

I do not plan migrating my backup script into Clojure any time soon, but I will most likely keep this option in mind next time I need some small import/export utility.

I do recommend giving it a try.


Popular posts from this blog

Ldap security for Jenkins CI

Automatic jsp recompile on Jboss AS 7

Simple EJB Arquillian test based on JUnit running on managed JBoss AS 7