Yea, agreed. I think a nice future for lein is as a build tool over clj, as I feel having an official package/dependency manager now, that part of lein is the most redundant and likely to just slowly be deprecared or see itself being used less and less. So the use of lein with the lein-tools-deps
plugin I think is pretty great, and I’ve used that in some projects before.
You’re also correct in that it is much more nuanced. The nuance comes partly with trying to even define what a build
is, and thus what a build tool
looks like.
A build
is really whatever you want. Back in the day, it meant to build the binary for your application. But nowadays, what does it mean to build Clojure? Clojure doesn’t need building
like in the old days. You can run a .clj
file as is, your source code is also a program that you can run directly without any additional steps. But there are possibly many steps
you’d want to perform prior to giving your app to others, such as generating documentation, linting, running tests, auto-formatting the source, possibly running AOT, etc.
None of these per-say are required to run your program, thus what you’re going to be doing exactly as part of building
your Clojure program is kind of up to you. You might want to send yourself an email, or play a victory jingle for example. There is no strict set.
Still, you eventually realize that many of the possible tasks you’d want performed as part of your build
from project to project starts to always be the same set of tasks, with only minor modifications to them. And that’s when a build tool
seems like a good idea. A single program/script where you’ll implement the logic for the most common build tasks and expose a certain level of configuration to each so they can adapt to the minor changes between projects.
And with that definition in place, you’ll realize that clj/deps is not such a tool. It does not come with a set of common build tasks that you can use with some configuration to adapt them to your project, but lein does!
And yet, clj/deps can look like a build tool, because it is a package manager for Clojure programs. And so let me explain.
As you realize that for each of your Clojure project, you always want to generate documentation, run tests and perform linting. You have two follow up:
- Create a single tool that can do all of these, and has a unified configuration.
- Create a separate tool for each of these, which can be configured.
Lein is the #1 option. A monolithic build tool with a unified configuration, and some support for addition plugins that can be used to add even more tasks to its existing set which all follow its conventions and configuration format.
#2 are some of the new build tools which have been more recently developed to be used with clj/deps, such as clj-new, cljfmt-runner, clj-check, test-runner, kaocha, depstar, etc. A bunch of separate tools each targeting a subset or even a single of the possible tasks you’d want performed at build, using their own configuration and conventions.
Most of these don’t need clj/deps, though some of them
I believe do depend on having a deps.edn file. They’re all build tools
, like lein, just with a smaller scope.
Previously, getting all these tools installed on your machine and running would have been painful, or you’d have used lein for it (lein is also a package manager), but if you’d have used lein for it, and since lein already comes with most build tasks built in, you’d have probably not tried to get any of those other tool and just used lein or a lein plugin to perform the same task. But now that clj/deps is here, it is super easy to get all these tools downloaded and running in your project. That’s where some people are thus saying that clj/deps
can be used as a “build tool”.
Now I’m not here to fight on word definitions, the fact is indirectly, you can use clj/deps to kick-start build tasks on your project, and that alone could mean we label it a build tool, I don’t care. My goal is only to provide a deeper understanding of the differences between lein
and clj/deps
at a fundamental level, for those interested.
Hope I helped.
Regards!