The Clojure Library Ecosystem

Clojure’s library ecosystem can be a source of confusion for new users. This quick overview will help to orient new Clojure programmers to the current state of the library system, with pointers to resources for further information.

Leiningen

Most Clojure projects use Leiningen as their build and dependency management system. Project dependencies and their required versions are placed in a file called project.clj, and Leiningen takes care of downloading them. Leiningen also creates JARs of the release versions of your project, and can bridge to Emacs’ SLIME mode, run a REPL at the command line, and so on. Many plugins exist to extend Leiningen’s functionality for other things like testing and deployment.

Under the covers, Leiningen uses Maven for dependency management. Maven is one of those ridiculously over-engineered Java projects that we all love to hate where you have to write 100 lines of XML boilerplate around 2 lines of actual project-specific configuration data. Fortunately, Leiningen insulates us from all of that.

Users should be aware that, as of this writing (May, 2012), Leiningen is about to release version 2.0, which uses a slightly different project.clj format. Some Leiningen plugins have not been updated for the new format. This is easy enough to work around if you know that there has been a specification change. In particular, many :dev-dependencies that affect Leiningen itself have to be moved to the new :plugins key.

Clojars and GitHub

Most Clojure libraries are provided in binary JAR format on Clojars, and have their source code hosted on GitHub.

Clojure developers frequently face the situation where some critical bugfix or new feature exists only on somebody’s GitHub fork, but not in the mainline repository. The best option in this case is to get the maintainer to push a new official release with the required changes, but this is not always possible. If the project has a slow release cycle, or if the original developer is not very into the project, it can be months between the creation of patches in a fork and their release from the mainline repository to a new version on Clojars. We have a few options in that case.

For development, it can be convenient to use the lein-git-deps plugin. This extends Leiningen to allow it to download dependencies from GitHub into a hidden directory in your project. This is something of a fragile hack, though. If the subproject has any dependencies, they will not be checked out by Leiningen — you have to manually install them in the parent project. Worse, the code on GitHub can change at any time (unless you specify a particular release). If you redeploy your code in the future, you might wind up with a broken project. If it’s impractical to get the maintainer of a library to produce a new official release, it’s best to fork the library and make your own stable release.

If you just want to use it locally, check out your fork to your local machine, bump the version number, and do lein install. Within your organization, you can easily host a private Maven repository. If you want to deploy publicly, you can push a forked release to Clojars with a different group-id. Detailled instructions on how to do these things can be found in the Leiningen documentation.

4 Responses to The Clojure Library Ecosystem