Developer
News and Updates
Get Support
Sign in
Get Support
Sign in
DOCUMENTATION
Cloud
Data Center
Resources
Sign in
Sign in
DOCUMENTATION
Cloud
Data Center
Resources
Sign in
Last updated Sep 10, 2026

Markdown ↔ ADF Conversion

Technical Guide

Introduction

Markdown is a well-established, lightweight markup language for representing rich content with plain text. In this respect, it has the same goals as Atlassian Wiki Markup, which was invented independently around the same time. More comparisons of Markdown with Atlassian Wiki Markup and Markdown as well as a brief history of these two formats is provided on the About Wiki Markup page.

As with Atlassian Wiki Markup, there are features that do not translate directly between Markdown and ADF. Document references, anchor links, relative URLs, and media references are all difficult to support. Tables are not part of the standard Markdown format, though GitHub’s extensions for them have widespread adoption.

adf-builder-java-markdown

Experimental

This library provides a separate adf-builder-java-markdown module with two capabilities:

Both capabilities should be considered EXPERIMENTAL — they have not undergone extensive testing to ensure production readiness and their APIs are subject to change.

The following extensions are enabled:

Example

Both of these should result in the same (or at least very similar) ADF:

Markdown

1
2
3
4
5
6
7
## Heading 2

Paragraph text

1. List item 1
2. List item 2

Java

1
2
3
4
5
6
7
8
9
doc(
    h2("Heading 2"),
    p("Paragraph text"),
    ol(
        li("List item 1"),
        li("List item 2")
    )
)

Usage

1
2
3
4
    String markdown = "## Heading 2\n\nParagraph text…";
    MarkdownParser parser = new MarkdownParser();
    Doc doc = parser.unmarshall(markdown);

ADF to Markdown

MarkdownEncoder converts an ADF Doc to a Markdown string. It is the inverse of MarkdownParser.

Supported nodes

All standard ADF block and inline nodes are supported. Nodes that have no direct Markdown equivalent are handled with graceful degradation:

ADF nodeMarkdown output
paragraph, hardBreakparagraph / \n line break
headingATX heading (# … through ###### …)
rule---
blockquote> blockquote
codeBlockfenced code block (```) with language hint
bulletList, orderedList- / 1. list, nested with two-space indent
taskList- [ ] / - [x] GFM task list
decisionListbullet list (graceful degradation)
tableGFM pipe table; mediaSingle caption → image alt text
mediaSingle, mediaGroup![alt](url); file media falls back to ![alt](media)
panelblockquote with bold type label (e.g. > **[info]**)
expand, nestedExpandbold title followed by content
layoutSectioncolumns flattened in order
bodiedExtension, multiBodiedExtensionbody content only
extension (block), inlineExtensionextension key as plain-text placeholder
blockCard, embedCard, inlineCard[url](url) Markdown link
mentiondisplay text (with @ prefix) or @id
emojishort name (e.g. :smile:)
statusplain text label
datetimestamp string

Text marks with no Markdown equivalent (textColor, backgroundColor, annotation, subSup, fontSize) and block/paragraph marks (alignment, indentation, breakout) are silently ignored.

Text escaping

Inline-structural Markdown characters (\, `, *, _, [, ]) are escaped in plain text nodes so that content is not accidentally interpreted as formatting. Characters that are only significant at the start of a line (#, -, ., !) are not escaped. Pipe characters (|) are escaped in table cell content by the table encoder.

Usage

1
2
3
4
5
6
7
8
9
    Doc doc = doc(
        h2("Heading 2"),
        p("Paragraph text"),
        ol(li("List item 1"), li("List item 2"))
    );
    MarkdownEncoder encoder = new MarkdownEncoder();
    String markdown = encoder.marshall(doc);
    // markdown == "## Heading 2\n\nParagraph text\n\n1. List item 1\n2. List item 2"

Further Reading

Rate this page: