For Squarespace's most recent Hack Week, I tried out three different documentation tools, with an eye to replacing our current internal documentation system.
Since Squarespace's internal engineering documentation team was established a year ago, we've made progress towards standardizing on a documentation system and establishing best practices. As a small team of writers, a major part of our job is making it easy for developers to write and publish their own docs. We've migrated most teams to writing in Markdown and storing the source in Git repositories.
But one piece of the puzzle is still in progress: a static site generator to turn those source files into self-contained, attractive HTML sites.
For Hack Week, I chose to evaluate two of the newer options on the scene (Antora and Docusaurus), as well as one of the most established (Sphinx). This post will compare Antora and Docusaurus. Stay tuned for a follow-up post about Sphinx.
I will admit upfront: I wanted to love Antora. It purports to be "The Static Site Generator for Tech Writers," and How Antora Can Help did promise lots of features I wanted.
However, it took me two and a half days to get a functioning project, and I'm still not convinced I did it right. Additionally, the killer feature I wanted (the ability to pull content from multiple different repositories) didn't pan out.
I’ll walk through my experience trying to get a working Antora site, but if all the terminology makes your eyes glaze over, just skip it — the takeaway is that the process is as confusing to go through as it is to read about it.
First, you should know that Antora has you divide functionality into three repositories:
a repository with the actual content, which must adhere to a specific directory structure and contain an
antora.ymlfile with metadata about that content
a repository for your "playbook," which defines where to pull content from, which UI to apply, and where to publish your site (essentially, configuration)
a repository that defines the UI for your docs site (essentially, theme)
Antora doesn’t provide a quickstart generator, but they do have a demo playbook repository that you can download. After wading through the lengthy system requirements and installation docs, I downloaded the demo repo. I decided to ignore the part about putting content and configuration in two different repos, and used the demo repo for both my playbook and content.
The issues I ran into were partly conceptual and partly technical.
Conceptually, I struggled to understand how I should define a component versus a module. An
antora.yml file denotes a component and has metadata like title and version, plus a reference to a default navigation file. But the navigation file itself is nested within a particular module. I never got as far as determining whether and how you could combine nav files for a complete table of contents.
I eventually decided that a component is intended to correspond with a repository, and then modules are essentially just subdirectories with a stricter structure.
For example, if you had organized your
docs repository into
installation, etc., each of those directories would become a module (each of which has subdirectories for
docs/ |- antora.yml |- modules/ |- ROOT/ |- assets/ |- examples/ |- pages/ |- nav.adoc |- getting-started/ |- assets/ |- examples/ |- pages/ |- nav.adoc |- installation/ |- …
On the technical side, once I’d put my content into a module, I spent a long time trying to get my docs to build.
Antora really wants you to use multiple Git repositories. Because I had put everything (both configuration and content) in a single repo, I had to figure out how to build from local source files instead of from a remote repository. I read the content sources documentation thoroughly, and tried different combinations of paths, branches, and the
start_path option, before I came across this issue with a relevant example for what I wanted.
My verdict? Antora’s initial configuration is too difficult.
I understand that Antora's level of specificity is by design, and as a tech writer I appreciate standardization. For example, I've often been annoyed when some people put image files in
images, some in
_static, some in
/images. But Antora asks a lot of overhead knowledge from contributors, and I worry that will scare away developers from contributing, let alone starting a new docs project. We need a docs solution that lets teams be as self-sufficient as possible.
Antora has you write documentation in AsciiDoc. Since all of the documentation I’ve written at Squarespace is in Markdown, I had to rewrite it in AsciiDoc.
Here we encounter the next thing preventing me from liking Antora: oh my god I hate AsciiDoc syntax so much. Yes, I know that this is not the fault of Antora itself — but its creators did choose that as the markup language.
In no particular order, some things I don't like:
. First item in the list. . Second item. + Here is some follow-on text to the second item. . Third item.
I love when a markup language automatically increments numbers in a list, but using a single dot doesn't make semantic sense to me, unlike repeating
1. (like in Markdown) or
#. (in reStructuredText, another markup language). I also hate having to "attach" follow-on paragraphs with the + character. It makes the whole thing look cluttered, and visually I don't associate the follow-on with the list item it belongs to.
Compare this to the same list in reStructuredText (RST):
#. First item in the list. #. Second item. Here is some follow-on text to the second item. #. Third item.
Yes, you have to be more careful with whitespace, but the whole thing looks much more like what it will render to.
Having the URL followed by the link text is harder to read and looks messier. There is also no option to do reference-style links, where you defer defining the link URL to later in the document. Reference-style links make paragraph text easier to read and let you collect all link definitions in a single place, making them easier to find and update if needed.
**JSON Schema** describes how some piece of JSON should be structured. For a good explanation, see https://spacetelescope.github.io/understanding-json-schema/about.html[What is a schema?] (from the https://spacetelescope.github.io/understanding-json-schema/index.html[Understanding JSON Schema] book).
**JSON Schema** describes how some piece of JSON should be structured. For a good explanation, see [What is a schema?][what-is-a-schema] (from the [Understanding JSON Schema][json-schema-book] book). [what-is-a-schema]: https://spacetelescope.github.io/understanding-json-schema/about.html [json-schema-book]: https://spacetelescope.github.io/understanding-json-schema/index.html
**JSON Schema** describes how some piece of JSON should be structured. For a good explanation, see `What is a schema?`_ (from the `Understanding JSON Schema`_ book). .. _What is a schema?: https://spacetelescope.github.io/understanding-json-schema/about.html .. _Understanding JSON Schema: https://spacetelescope.github.io/understanding-json-schema/index.html
Both the Markdown and RST versions use reference-style links, making them easier to read.
For reasons that I don't understand, the syntax for bold/italics/etc. is different based on whether you're applying it to the whole word or just part of the word, and different still if it's followed by punctuation. From Antora's documentation:
A word or phrase is marked as bold when it’s enclosed in a single set of asterisks (e.g., *word*) (constrained formatting). Bounded characters are marked as bold when they’re enclosed in a set of double asterisks (e.g., char**act**ers) (unconstrained formatting). You don’t need to use double asterisks when an entire word or phrase marked as bold is directly followed by a common punctuation mark, such as ;, ", and !.
Compare the above to how the Sphinx docs talk about how to apply bold in RST:
Use two asterisks: **text** for strong emphasis (boldface).
The AsciiDoc syntax seems unnecessarily complicated, and it probably doesn't even matter, because I can't imagine someone needing to use styles like this… but it still bothers me.
After nearly three days of working on my Antora site, I turned to Facebook's Docusaurus. Two hours later, I had a functioning, attractive site running.
Docusaurus is only slightly older than Antora. It was released in December 2017 after being developed as the documentation solution for Facebook's open source projects.
Docusaurus was a pleasure to use from the start. Their docs are brief, but include everything you need. The installation process looks like this:
1. Install NPM.
2. Run a quickstart script to generate a site.
3. Run the site with
I'm simplifying things — but not by very much. It was incredibly easy to set up a minimal site. After installation, I followed the Creating your site guide to learn where to put my source files, make the small changes needed to my existing Markdown (adding a page ID and title), list the files in a
sidebars.json file to form a table of contents, and change some things like site name and theme colors. And just like that, I had a branded site with some content in it.
Almost everything about Docusaurus is configurable in a single file:
siteConfig.js. The file itself is well commented, making it easy to follow even without documentation. Compare to Antora, where the documentation on the equivalent configuration file,
antora.yml, spans 11 pages (at time of writing). And you can't change the look-and-feel of your site with this file.
Features I like
Besides ease of use, what I like most about Docusaurus is that it adds documentation-specific features that were always lacking in Markdown (but present in Sphinx/RST).
You can link directly to a page ID rather than filename, which allows you to move or rename a file without risking breaking all your existing links to that file.
At the top of each file, you define the page ID:
--- id: getting-started Title: Getting Started with My Product --- Body text here...
Then in another file, you can link to that file like so:
... for instructions, see the [getting started guide](getting-started)...
Table of contents
Markdown doesn't have a native way to construct a page hierarchy and order. You can manually write a list of links and serve that as your landing page, but that doesn't provide any real navigation, and you have to manually update page titles in your link list if they change. Docusaurus lets you add files by filename to a
sidebars.json file, and builds your site navigation from that. You can even add categories within the sidebar. For example, Getting Started, Guides, and API here:
Admonitions are pre-styled callouts for "warning," "tip," "note," etc. Docusaurus only has a single option that uses Markdown's block quote syntax, but it's better than nothing.
Antora's creators might argue that there is a learning curve, and if I'd just spent more time and read through the (extensive) documentation more thoroughly, I'd find Antora to be a good tool. That may be true. The documentation was comprehensive, sure, but wordy in places, and there was too much of it — and that's probably because the tool is too complicated. This is a trap I've seen before — using documentation to work around an unintuitive product. When users struggle with a new feature, rather than changing the feature, you write several pages of docs explaining how to use it.
In our particular case, this is especially problematic. As a small internal documentation team, we don't have scores of tech writers who are only too eager to learn the nuances of the Antora directory structure and meticulously maintain navigation files. We need our documentation system to be as easy as possible for developers to contribute to. If they get frustrated with the Antora build or AsciiDoc syntax, they are likely to leave the system entirely and go back to writing documentation on the wiki or in Google Docs.
For ease of use and ramp-up time, Docusaurus was the clear winner. Markdown’s syntax is also more beginner-friendly than AsciiDoc’s, and while Markdown has fewer documentation-specific features, Docusaurus compensates for that by adding functionality like sidebar navigation and dynamic links.
To learn how Sphinx stacked up against both Antora and Docusaurus, see my next post.
(Bonus: I have more to say about Antora. If you’re interested, see my follow-up post.)