This month in Pavex, #8: docs, docs, docs

👋 Hi!
It's Luca here, the author of "Zero to production in Rust".
This is a progress report about Pavex, a new Rust web framework that I have been working on.

It's time for another progress report on Pavex, covering what has been done in December!

At the end of November, I announced that Pavex was entering a closed beta period.
From a functionality perspective, the framework was ready for a test drive. Documentation, however, was lacking.

That's where most of December went: docs, docs, docs.
A month later, we're in a good place1. Good enough to kick off the closed beta2: the first batch of invites went out on January 3rd!

I took a different approach to Pavex's documentation compared to my previous OSS projects and the work I did in "Zero to Production in Rust". I'll use the rest of this post to dive into it!

You can discuss this update on r/rust.

Table of Contents

Documentation is hard

No docs, no users

Documentation is one of the most important parts of a project.
There's plenty of great projects out there that aren't realising their full potential because people don't know how to use them.

I've always admired the Rust community's emphasis on documentation. Compared to other ecosystems, the average crate has better docs. That's definitely been a factor in Rust's success and a testament to the excellent work done by the rustdoc team: more maintainers are willing to write docs if it's easy and they don't have to worry about hosting.

What docs do you need?

What makes documentation good? It's a tough question to answer!
You hear people praising this or that project's documentation, but it's often hard to articulate why it's good.

While working at AWS, I was introduced to Diátaxis, a systematic framework for writing documentation. It starts with a simple premise: documentation must serve the needs of its users. It then goes on to identify those needs and define different types of documentation components that can be used to address them.

The framework quadrant

I leaned heavily on Diátaxis when structuring Pavex's documentation.

rustdoc is great, but it's not enough

The Rust community has a great tool for writing documentation: rustdoc. It's great at what it does: writing a comprehensive (and well-tested) API reference. But users need more than an API reference!

They need tutorials, teaching the basics as they walk you through a series of scripted steps.
They need high-level explanations, covering the framework's design and how everything fits together.
They need how-to guides, tailored to the problem they're trying to solve.

All these things are hard to write in rustdoc because rustdoc is code-oriented.
Everything has to be attached to a specific Rust item, be it a module or a type. The module hierarchy becomes the documentation hierarchy, even though it's not necessarily the best way to present the information to the user.
You see Rust crates adding fake modules just to attach high-level documentation somewhere.

Pavex's documentation

For Pavex, I decided to augment the API reference generated by rustdoc with a separate documentation site1. It's built with Material for MkDocs, another incredible tool for writing documentation.

The rustdoc API reference is still there, but it's just a part of the whole picture.
And that picture is big! In just over a month, we have:

on top of the existing API reference and its doc examples.

Stale docs are the worst

One of the biggest challenges with documentation is keeping it up to date.
It's incredibly frustrating to follow a tutorial and get stuck because the code that's being shown doesn't compile anymore.

rustdoc is great at that: all code examples are compiled and tested every time you run cargo test.

Things get a lot more complicated when you're writing tutorials and guides. You are guiding the user through a learning journey and the code changes at every step as you progress through the tutorial project.
This is a challenge I'm familiar with from my work on "Zero to Production in Rust": you can think of the book as a 600-page-long tutorial. When I update a code snippet, I have to make sure I've updated all the other snippets that reference it or relate to it in a later section or chapter. It's tricky and error-prone.

I wanted a better solution for Pavex.

Test all the things

Every section of Pavex's documentation site is backed by a YAML manifest.
In the manifest, we specify:

This manifest is fed into a custom tool I built, tutorial_generator, to generate the snippet files (*.snap) that are then embedded into the documentation site using an mkdocs plugin:

# Routing

## Route registration

All the routes exposed by your API must be registered with its [`Blueprint`][Blueprint].  
In the snippet below you can see the registration of the `GET /api/ping` route, the one you targeted with your `curl`

--8<-- "doc_examples/quickstart/demo-route_registration.snap"

If anything changes in Pavex (e.g. we modify the starter template returned by pavex new), the snippets will automatically reflect the changes. Since the snippets are committed to version control, we can review the changes and make sure that they are still correct. If they're not, we update the YAML manifest and regenerate the snippets by rerunning the command.

In CI, instead, we just make sure that the snippets are up-to-date: if they're not, the build fails.

This system introduces a bit of complexity, but it's worth it.
I can make sweeping changes to the framework and be confident that I won't miss anything in the documentation. In the few weeks it has been up and running it saved me more than once from leaving stale examples around!

What's next?

I'm really excited to have the closed beta up and running!
I'm looking forward to the feedback from the first cohorts of testers to help me shape the framework.

In the coming month, I'll be splitting my focus on three fronts (in order of priority):

That's all for December, see you next month!

You can discuss this update on r/rust.

Subscribe to the newsletter if you don't want to miss the next update!
You can also follow the development of Pavex on GitHub.


The hosted version of the docs is not publicly available yet. I'll share it once we reach the open beta phase! In the meantime, you can have a peek at it on GitHub if you're curious.


New batches of invites will be sent out every few weeks. Sign up to join the beta!


It's already happening (1, 2, 3) and so far the patching has been easy enough, thanks to Miguel's incredible bug reports. Thank you so much!