As support for Clojure 1.3 becomes widespread, it becomes more
important for projects to think about backwards compatibility. You
can specify a range of versions for Clojure in project.clj
with [org.clojure/clojure "[1.2.0,1.3.0]"], but when
you're developing, it will just find the latest and pull that in,
so it's easy for dependence on 1.3-specific features to sneak
in.

Enter lein-multi, a plugin for running arbitrary tasks against
multiple dependency sets. It's most commonly used with
the test task, but it's a general higher-order task
that can be applied to any other just as well.
Seeing lein-multi in someone's project.clj is a good
indicator that they take backwards-compatibility seriously.

Update: Leiningen 2 supports this out of the box using
profiles, so the lein-multi plugin is deprecated.

The most common complaint I hear about developing in Clojure is
the fact that its error messages often obscure the true cause of
the problem. While practice helps here, it's still true that
there's a lot of irrelevant detail here that can overwhelm the
trained eye. Mark McGranaghan's clj-stacktrace library does a
great job at summarizing stack traces by aligning each frame,
making the namespace distinct from the function name, and even
coloring frames differently based on whether they come from
Clojure, Java, or user code. The next version should let you
filter out frames that are deemed irrelevant on a per-project
basis.

To use it in your project's repl as well as
in clojure.test error reporting, place this code
in ~/.lein/init.clj after running $ lein plugin
install clj-stacktrace 0.2.4:

Another common question you hear is "How do I generate custom
exception classes?". It's awkward and somewhat un-idiomatic to do
this, so people generally try to get by with the Exception
classes that ship with the JDK. But why shouldn't exceptions get
the same level of dynamicity and flexibility that Clojure affords
other data types?

This is basically the question Slingshot addresses. It provides
enhanced try+ and throw+ counterparts to
the built-in error mechanisms that let you throw arbitrary data
types like maps. Then rather than dispatching in your catch blocks
based on class, you can use arbitrary predicates. You can even
perform destructuring on maps that are thrown. It's a big step up
in expressiveness:

Update: The equivalent of the exception-throwing side of
Slingshot has been included in Clojure 1.4 using
the ex-info and ex-data functions, so
unless you are targeting old versions of Clojure you should use
those instead. Nothing has been added on the exception handling
side though, so Slingshot's try+ macro is still very
useful.

If you've ever written a test where you expect two lengthy data
structures to be equal, you'll remember how annoying it is to try
to compare the failure message where "expected" and "actual" are
each spat out on a single line and you're supposed to try to hunt
down the difference. Using lein difftest makes it easy:

It also uses clj-stacktrace to report errors. This one
is better off installed as a user-level plugin since you're
likely to want to be able to use the difftest task
across all your projects:

$ lein plugin install lein-difftest 1.3.7

Update: Use version 2.0.0 of lein-difftest for
compatibility with Leiningen 2.x.

From the do-one-thing-and-do-it-well department, we have Robert
Bruce, which concerns itself only with determinedly retrying a
given function. It provides all the options you could imagine for
how to perform the retries, including pausing between them (with
exponential decay on backoffs), retry limits, callbacks on
failure, and so on.

[robert/bruce "0.7.1"]

Happy hacking!

Do you have a favourite that I've missed here? Leave a comment
about it. Remember that the version numbers provided here are
current as of the time of this writing but may be outdated when
you read this.