Marginalia: literate programming for Clojure that produces a side-by-side source view
Ultra-lightweight literate programming for clojure inspired by docco
At a glance
- What is it?
- Marginalia is a documentation generator for Clojure and ClojureScript that parses your source and outputs it side by side with its comments and docstrings aligned. It runs through Leiningen, deps.edn or a Maven plugin, and the whole configuration surface is a dozen flags, from the output directory to the option that lifts inline comments to the top of their enclosing form.
- Who is it for?
- Adopt Marginalia when you want browsable documentation that shows the code itself rather than a rendered API reference, particularly for a library where reading the source is the point. Do not expect classical literate programming, because the README is explicit that Marginalia is a linear generator allowing no out-of-order reassembly of source.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 85 days ago.
- What is it written in?
- Mainly Clojure, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the tool produces and what it refuses to be
Marginalia describes itself as ultra-lightweight literate programming for Clojure and ClojureScript, inspired by docco. It is a source code documentation tool that parses Clojure and ClojureScript code and outputs a side-by-side source view with appropriate comments and docstrings aligned.
That is the whole description, and it is a narrower thing than the phrase literate programming usually suggests. The README has a footnote that is worth reading before anything else. While the phrase ultra-lightweight literate programming is used to describe Marginalia, it is in no way a tool for classical literate programming. Marginalia is a linear documentation generator allowing no out-of-order reassembly of source.
In other words, it does not reorder your code to match the order of the prose. There is no weaving step where you write a narrative and the tool assembles the source around it. The output is your source in its original order with the documentation beside it.
For Clojure that is a reasonable trade, and the reason is not hard to see. Clojure code is not a sequence of top-level definitions in a narrative order. It is a namespace of interlocking definitions, and the reader of Clojure expects to encounter them in the order they are written, with the docstrings visible. Classical literate programming would scramble that.
The project history is in the README as well. There is a link announcing that Marginalia has a new home, a blog post from 2013, and a contributor list sorted by first commit that starts with Fogus, then Zachary Kim, Justin Balthrop, Brenton Ashworth and others through to around twenty names. The author thanks Zachary Kim specifically for taking a pile of incoherent code and making it something worth using, and says Marginalia would be nothing without his work and vision. Justin Balthrop and Brenton Ashworth are thanked for support and code contributions, and Marginalia is currently maintained by Tim Macdonald.
The project is published to Clojars, the site is clj-commons.org/marginalia, and the repository carries a CHANGELOG.md, an ORIGINATOR file, a project.clj, a bin/ directory, a vendor/ directory and a test_projects/ directory.
Running it through Leiningen, deps.edn and Maven
The tool can be driven three ways, and the README documents each with the exact configuration.
With Leiningen, the plugin is lein-marginalia. On Leiningen 1.x you add [lein-marginalia "0.9.2"] to the :dev-dependencies argument of the defproject function and run lein deps. On Leiningen 2.x you add [[lein-marginalia "0.9.2]] to the :plugins entry in either your project.clj or your :user profile. Then you generate the documentation with:
lein marg <options> <files>With deps.edn, you add the dependency and define an alias:
{:aliases
{:marginalia
{:extra-deps {marginalia/marginalia {:mvn/version "0.9.2"}}
:main-opts ["-m" "marginalia.main" "-n" "YourProjectName"
"src" "test"]}}}And you invoke it with clojure -M:marginalia, or without the alias, clojure -M -m marginalia.main. The alias form is the better one to standardise on, because it means the version of the tool and the arguments travel together.
With Maven, the zi plugin supports Marginalia. The README gives the pom.xml configuration with the marginaliaTargetDirectory set to autodoc/marginalia, and the corresponding settings.xml with the plugin group, the plugin repository and an active profile.
The three-way support is itself the interesting engineering fact. Leiningen was the dominant Clojure build tool when Marginalia was written, and deps.edn arrived later with tools.deps. Supporting both, and a Maven plugin for the JVM-toolchain world, means Marginalia can be dropped into an existing build without a migration.
The README also notes that options can be added to .marginalia/config.edn as a map with keys taken from the flag names.
The flags, and the one that changes the output
The option table is compact and mostly follows a familiar shape: the output directory defaults to ./docs and the output file to uberdoc.html, while the project name, version, description and dependencies default to values taken from project.clj.
The interesting flags are the ones that change what the generated document contains rather than where it goes.
--multi, disabled by default, generates each namespace's documentation as a separate file rather than one document. For a large project, one file per namespace is the difference between a documentation page you can scroll and one you cannot.
--exclude takes a list of source files to leave out of generation, and --leiningen generates the documentation for a Leiningen project file, so the project definition itself gets documented.
The last two are the most interesting. --lift-in-line-comments, disabled by default, lifts inline comments to the top of the enclosing form. Clojure code puts ; comments at the end of a line, and in a side-by-side view that trailing comment can end up in a narrow column, so moving it above the form gives it room to breathe. --exclude-lifted-comments then controls whether the lifted comment also stays out of the source display, so the comment appears once, in its new position, rather than twice.
The remaining options are for adding resources: --css and --js take lists of extra files to include, and --deps takes the project dependencies in the form group1:artifact1:version1;group2:... so the generated page can show what the project depends on.
Taken together, the option set says something about the tool's intent. It assumes you want one self-contained HTML file with your assets, and the flags are about what goes into it rather than about presentation.
Limits: a linear generator, an old release line and an unfilled licence field
The limits are visible in the README and in the metadata.
The first is the one the README states most plainly. Marginalia is a linear documentation generator allowing no out-of-order reassembly of source. If you wanted literate programming in the sense of writing a document and having the code woven into it, this is not that tool, and no configuration flag changes it.
The second is the release history. The tags are v0.9.2 from 2024-02-01, v0.9.1 from 2017-11-09 and v0.9.0 from 2016-03-16. The release title for 0.9.1 is Keeping up with Cognitects, which tells you what that release was about: the tool tracks the Clojure and ClojureScript releases it depends on, and a seven-year gap between 0.9.1 and 0.9.2 means the intervening changes were to the platform rather than to the tool's features.
The third is that it produces one HTML page rather than a documentation site. The -f flag defaults to uberdoc.html and the -d flag to ./docs, and --multi splits by namespace, but there is no index, no search and no cross-referencing between pages. If your project needs browsable API documentation with a search box, this is the wrong shape and you want a different tool.
The fourth is the licence position. The repository records the licence as unknown and there is no LICENSE file in the top-level listing, though the project.clj and the Clojars publication are there. For a documentation tool that reads source and writes HTML, that is a gap worth closing before you run it across a codebase you care about, since you will be publishing that HTML.
The fifth is the dependency surface. The project leans on Leiningen, deps.edn or a Maven plugin, and on the tools those pull in. The pom configuration in the README adds a plugin repository for Clojure snapshots, which is a hint that a snapshot of the platform can appear in the documentation you generate.
Marginalia against generated API documentation and against a literate Clojure workflow
Two comparisons make the choice clearer.
The first is against an API documentation generator for Clojure, the kind that reads your namespaces and emits a browsable reference of every public var with its docstring and arglists. The difference in approach is what the reader gets. An API reference tells you what a function accepts and returns. A side-by-side source view shows you what the function does, because the body is right there next to the explanation. For a language whose functions are often a few lines of destructuring and threading, the body is the documentation.
The cost is size and search. The output is one HTML file per namespace by default, with no index, and the reader scrolls. That is fine for a small library and awkward for a large codebase, and it is why --multi exists.
The second comparison is against a literate workflow in the original sense, where the document is the source and the code is extracted from it. Marginalia is the other way round, and the README's footnote is explicit that it is not that tool. For Clojure the argument is straightforward: a namespace is a web of definitions where the order matters to the reader, and reordering it to follow a narrative would produce something nobody could use. The accepted practice in the Clojure community is that the docstring is the documentation and the source is the reference, and Marginalia puts the two side by side rather than replacing either.
So the choice is between a document that reads like a blog and a document that reads like the code with comments in the margin. For Clojure, most people who have used Marginalia would argue the second is the one you actually want, and that is why a tool with this little feature surface has been in continuous use since 2013.
Editorial conclusion
Adopt Marginalia when you want browsable documentation that shows the code itself rather than a rendered API reference, particularly for a library where reading the source is the point. Do not expect classical literate programming, because the README is explicit that Marginalia is a linear generator allowing no out-of-order reassembly of source. Verify first that your build tool is one of the three it supports, and read the version difference between 0.9.1 and 0.9.2 before upgrading, since the jump from 0.9.1 was about keeping up with the tools the project builds on.
Frequently asked questions
What does Marginalia produce from Clojure source?
It parses Clojure and ClojureScript code and outputs a side-by-side source view with the comments and docstrings aligned. The output is a single HTML file by default, written to uberdoc.html in a ./docs directory, and the --multi flag generates each namespace's documentation as a separate file instead.
How do I run Marginalia with deps.edn?
Add marginalia/marginalia with the version to your deps and define an alias whose extra-deps include the library and whose main-opts run -m marginalia.main with the project name and the source paths. Then invoke it with clojure -M:marginalia, or use clojure -M -m marginalia.main without the alias.
Is Marginalia a literate programming tool?
Not in the classical sense. The README has a footnote stating that while the phrase ultra-lightweight literate programming is used to describe it, it is in no way a tool for classical literate programming, because Marginalia is a linear documentation generator allowing no out-of-order reassembly of source. The source order is preserved and the documentation is placed alongside it.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/clj-commons-marginalia)Was this useful?