Liking cljdoc? Tell your friends :D


CircleCI Clojars Project cljdoc badge

A minimal and opinionated linter for Clojure code that sparks joy.


You don't mind the occasional inline def for debugging, but you would like to get rid of them before making your code public. Also, unnecessary do and let nestings don't really add any value to your life. Let clj-kondo help you tidy your code.


  • inline def warnings
  • obsolete do warnings
  • obsolete let warnings
  • arity errors across namespaces
  • private function call errors

This linter is:

  • compatible with .clj, .cljs and .cljc files
  • build tool and editor agnostic


Under active development, but already useful. None of the code is meant to be exposed as a public API, except the command line interface.

For new features I'd like to focus on things that joker doesn't support yet, so I recommend enabling that one as well.



brew install borkdude/brew/clj-kondo


Install Linuxbrew. Then run:

brew install borkdude/brew/clj-kondo

Manual install

Pre-built binaries are available for linux and MacOS on the releases page.

Building from source

To build a binary from source, download GraalVM and set the GRAALVM_HOME variable. E.g.:

export GRAALVM_HOME=$HOME/Downloads/graalvm-ce-1.0.0-rc14/Contents/Home

Then clone this repo, cd clj-kondo and build the native binary:

clojure -A:native-image

Place the binary somewhere on your path.


Command line

Lint from stdin:

$ echo '(def x (def x 1))' | clj-kondo --lint -
<stdin>:1:8: warning: inline def

Lint a file:

$ echo '(def x (def x 1))' > /tmp/foo.clj
$ clj-kondo --lint /tmp/foo.clj
/tmp/foo.clj:1:8: warning: inline def

Lint a directory:

$ clj-kondo --lint src
src/clj_kondo/test.cljs:7:1: warning: obsolete do
src/clj_kondo/vars.clj:291:3: error: Wrong number of args (1) passed to clj-kondo.vars/analyze-arities

Lint a project classpath:

$ clj-kondo --lint $(lein classpath)

Project setup

Make a .clj-kondo directory in the root of your project. This directory will be automatically detected by clj-kondo and a cache will be created inside of it.

To initialize the cache, lint the entire classpath generated by e.g. lein:

$ clj-kondo --lint $(lein classpath) --cache

For boot you can use boot with-cp -w -f -. For tools.deps you can use clj -Spath.

Now you are ready to lint single files using editor integration. A simulation of what happens when you edit a file in your editor:

$ echo '(select-keys)' | clj-kondo --lang cljs --cache --lint -
<stdin>:1:1: error: Wrong number of args (0) passed to cljs.core/select-keys

Since the cache knows about your version of ClojureScript, it detects that the number of arguments you pass to select-keys is invalid. This works for all libraries and your own namespaces, not just Clojure. While editing files, the cache is incrementally updated.

Running with the JVM

Using the binary is recommended for better startup time, but you can run this linter with as a regular Clojure program on the JVM as well.


You can add clj-kondo to ~/.lein/profiles.clj to make it available as a lein command:

{:user {:dependencies [[clj-kondo "RELEASE"]]
        :aliases {"clj-kondo" ["run" "-m" "clj-kondo.main"]}
$ lein clj-kondo --lint src


Run clj-kondo as an ad-hoc command line dependency:

$ clj -Sdeps '{:deps {clj-kondo {:mvn/version "RELEASE"}}}' -m clj-kondo.main --lint src

Or add it as an alias to ~/.clojure/deps.edn:

  {:extra-deps {clj-kondo {:mvn/version "RELEASE"}}
   :main-opts ["-m" "clj-kondo.main"]}}}
$ clj -A:clj-kondo --lint src

Editor integration

For integrating with Emacs, see flycheck-clj-kondo.


clj -A:test


This project is inspired by joker. It uses clj.native-image for compiling the project. The parsing of Clojure code relies on rewrite-clj.


Copyright © 2019 Michiel Borkent

Distributed under the EPL License, same as Clojure. See LICENSE.

Can you improve this documentation?Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close