Skip to content
Branch: master
Find file Copy path
239 lines (162 sloc) 9.38 KB

cljdoc for Library Authors

Why cljdoc?

cljdoc aims to automate as much as possible of the process of publishing documentation. This means you get to spend time on crafting great documentation while cljdoc takes care of publishing and serving them to your users.

Basic Setup

For basic docs to be available you don’t have to do anything at all. cljdoc will pick up new releases as they are published to Clojars.

Building docs for older releases: If you would like to build docs for a version that existed before cljdoc started building docs automatically just head to the homepage, search for your project and pick it from the list. If we haven’t built docs for it yet you’ll be able to do so with the press of a button.

Point users to your projects documentation: You can link to cljdoc from your projects README using a plain Markdown link or the cljdoc badge:

# This will redirect to the latest released version$group-id/$artifact-id/CURRENT
# This will show a badge with the latest released version$group-id/$artifact-id

In full it may look like this:

[![cljdoc badge](](

cljdoc badge

In the cljdoc URLs above $group-id and $artifact-id always refer to the Clojars/Maven group/artifact ID, not e.g. GitHub’s owner/repo names.

That’s pretty much it. Read on for some more advanced stuff that will make your docs extra awesome!


Docstrings are rendered as Markdown in the CommonMark dialect.


Some libraries may want to publish additional guides, tutorials or, as they are called in cljdoc: articles. They can be written in Markdown (in the CommonMark dialect, file extension .md) or AsciiDoc (in the Asciidoctor dialect, file extension .adoc) and you can mix and match the two formats as you please.

In order to do so the following prerequisites must be met:

This allows cljdoc to retrieve files at the revision/commit the respective release was made. Those docs always being in sync will save your users a lot of trouble.

Articles are always read at the revision linked to the version docs are being built for. This means you cannot update docs for previous releases but are instead encouraged to cut a new release. For testing purposes you can build any -SNAPSHOT release which will cause cljdoc to use master as revision.
Referencing files in submodules is not currently supported, please open an issue if you need it.

If an article refers to another article’s source file via a link cljdoc will automatically rewrite that link if one of the known articles has the same source file. All links that work on GitHub should also work on cljdoc.

Auto-inferred Articles

If your repository does not contain a doc/cljdoc.edn file cljdoc will try to include articles from your doc/ or docs/ folder automatically.

The title is read from the file’s first heading. There will be no nesting and articles will be ordered alphabetically by filename. If you don’t need nesting this may be sufficient.

Use filenames prefixed with digits like to easily define the order of articles.

Configuring Articles

If you need more control you may provide a file doc/cljdoc.edn to specify a tree of articles.

Assuming you have a directory doc/ in your repository as follows:


You can integrate those files into your cljdoc build by adding a file doc/cljdoc.edn with the following contents:

{:cljdoc.doc/tree [["Readme" {:file ""}]
                   ["Getting Started" {:file "doc/"}
                    ["Installation" {:file "doc/"}]]
                   ["Configuration" {:file "doc/"}]]}

Which will result in the following hierarchy being shown in your docs:

├── Readme
├── Getting Started
│   └── Installation
└── Configuration
Since sometimes people forget to update the paths after moving files around we recommend you add the following to your CI setup:
curl -fsSL | bash -s doc/cljdoc.edn

Module Support

Some libraries consist of smaller submodules and cljdoc provides some facilities for library authors to make their documentaiton available in one location:

Module specific settings

If you want to provide a different doc tree for one module, simply nest it in the projects name, e.g.:

  ;; used for metosin/reitit
  ;; when building docs for metosin/reitit this will be used as if
  ;; the doc/cljdoc.edn file contained just the value of this key
  metosin/reitit {:cljdoc.doc/tree [["Introduction" {:file ""}]]}

  ;; used for any project except metosin/reitit
  ;; could contain an overview about all modules and a pointer
  ;; to the overarching documentation for metosin/reitit
  :cljdoc.doc/tree [["Overview" {:file "modules/"}]]


If you want a project to include API documentation for some of it’s dependencies provide an additional key :cljdoc/include-namespaces-from-dependencies:

This can be specified on a per artifact basis as described in the previous section.
This only works if the artifact specifies a dependency on the projects listed. The projects POM file will be used to load API information for the correct version.

WARN: If analysis for some of the specified dependencies failed or just hasn’t been ran they will be silently ignored for now.

More Features

You can refer to other namespaces and functions inside your docstrings using [[wikilink]] syntax. Note that if you want to link to vars outside the current namespace you need to either fully qualify those vars or specify them relative to the current namespace. An example: if you want to link to compojure.core/GET from compojure.route you’ll need to provide the wiki in one of the two forms below:


Intelligent Version Resolving

If you want to refer to namespaces, vars or similar in an article you can use CURRENT instead of a specific version.

  • If that link is clicked while viewing the project’s docs on cljdoc the version will be resolved based on the referring URL.

  • If that link is clicked outside of cljdoc the version will be resolved to the latest release version.

An example linking to reagent.core:

Hiding Namespaces & Vars in Documentation

To hide namespaces or vars from documentation, annotate them with :no-doc metadata as in the examples below:

(defn ^:no-doc hidden [x])
(ns ^:no-doc namespace.hidden
  "This ns shouldn't show in the docs.")
(ns namespace.hidden
  "This ns shouldn't show in the docs."
  {:no-doc true})

Getting Dependencies Right

cljdoc will try to load all namespaces that are part of the jar for your artifact. If you include namespaces that require additional/optional dependencies, make sure you declare them in your pom.xml (commonly done via Leiningen/Boot). If you don’t want these dependencies to be included by default, mark them with :scope "provided". This will cause dependency resolution to skip those dependencies but allow cljdoc to inspect your pom.xml and load them.

Offline Docs

Building Docs Locally

This may be useful to test your changes without pushing new releases to Clojars or commits to Github. See Running cljdoc locally for details.

Asciidoc Environment

Similar to GitHub, cljdoc will set an env-cljdoc attribute when rendering your Asciidoc file. This allows you to hide or show sections of your document or set configuration parameters.


Supported rich text formats

Our rich text render supports two formats:

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.