Exploring Markdoc

Hello! Today's post will focus on Markdoc, an open-source library created by Stripe that powers Codu's text editor for the blog. Codu uses a lot of technologies in its stack, like TypeScript, TRPC, and React, and I hope a post like this will encourage you to be less intimidated by the codebase, which you can find here

Introduction to Markdoc


Markdoc is a library that extends the Markdown syntax. It lets users create more expressive markdown documents with custom tags and nodes. It allows for more elaborate document structures and the ability to incorporate interactive components.

One of Markdoc's primary functions is to render content. Rendering is the process of converting a renderable tree into an output format. In the case of HTML, this means creating an HTML document as a string. For React, it translates to creating a React element.

Core Concepts


Don't be intimidated by the term "node" – here it just describes the various elements that make up a document.

Nodes in Markdoc represent the basic building blocks of a document. They can be text, images, links, etc.

> Blockquote


Markdoc inherits its nodes from Markdown, specifically the CommonMark specification, making it easier for those familiar with Markdown to understand the structure and organization.

Markdoc comes with built-in nodes for each of the CommonMark types, such as headings, paragraphs, images, lists, tables, and more. Check them out here

In our next post about Markdoc, we'll dive into customizing node rendering to make it work just the way we want. Take links, for example - out of the box, Markdoc doesn't open them in new tabs, like [link](www.link-to-site.com). We needed to tweak that for Codu. So we can look at that in the next post, or if you want to see the pr for it now, you can see it here.


Tags in Markdoc are custom elements that allow for more flexibility and functionality in your post. They resemble HTML tags but are specific to Markdoc. These custom tags enable users to create interactive components and add unique features to their content.

For those familiar with Django's template language, tags in Markdoc serve a similar purpose, providing a way to add dynamic content and behavior to your documents.

Here's an example of how you can create a table using Markdoc's tag syntax:

{% table %}

* Heading 1

* Heading 2


* Row 1 Cell 1

* Row 1 Cell 2


* Row 2 Cell 1

* Row 2 cell 2

{% /table %}

see if you can recreate the table from above, you can escape characters with a backslash.

Here is a custom tag for Codu to try out, we can go over it in a later post.

{% media src="https://www.youtube.com/watch?v=tM_S-pa4xDk" /%}

Rendering Process

When it comes to rendering the content, Markdoc first parses the input and generates an Abstract Syntax Tree (AST). This tree represents the document's structure, and nodes are organized in a hierarchy.

Once the AST is created, Markdoc converts this tree into the desired output format, such as HTML or a React element.

Here is a simple example from a feature I am working on at the moment.

const parseMarkdown = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
    const ast = Markdoc.parse(e.target.value);
    const content = Markdoc.transform(ast);
    const reactOutput = Markdoc.renderers.react(content, React);

It is just taking the value from a text area, parsing it into an AST, and transforming it into a renderable tree, a "serializable intermediate representation of what will eventually be rendered". Then finally it renders the content.

For more information about ASTs, you can refer to a previous blog post here.

I hope this sparked a bit of interest in Markdoc and I hope you read the next part about how to do some nice customization. Codu is trying to implement a lot of nice features around the blog editor and it will be great to see more people coming up with ideas for it!!!

All the best,


Avatar for Daniel Callaghan

Written by Daniel Callaghan

Software engineer at Guidewire Software. I like React, next and board games.


Fetching comments

Hey! 👋

Got something to say?

or to leave a comment.