goldmark
| Language | Go |
|---|---|
| License | MIT |
| Repository | github.com/yuin/goldmark |
| Documentation | pkg.go.dev/github.com/yuin/goldmark/v2, README, playground |
| Depends on | standard library only |
| Read / write | parses CommonMark 0.31.2 plus extensions; renders HTML (other renderers via extensions) |
goldmark parses Markdown into an AST and renders it to HTML. It passes the CommonMark test suite, is fast, and is built for extension: you can add block and inline parsers, paragraph and AST transformers, and node renderers. Built-in extensions cover GFM (tables, strikethrough, linkify, task lists), definition lists, footnotes and a typographer. Many third-party extensions exist: syntax highlighting, math, emoji, mermaid, front matter (goldmark-meta).
Version 2 separates the parser from the renderer, uses generics, keeps source positions on every node and supports building ASTs in code. It’s new (2026), so not every third-party extension supports it yet; if you depend on one that doesn’t, stay on v1 (github.com/yuin/goldmark, goldmark.New(goldmark.WithExtensions(...)).Convert(src, &buf)). The examples below use v2.
Raw HTML and dangerous URLs are omitted unless you pass html.WithUnsafe().
Installation#
go get github.com/yuin/goldmark/v2
Basic usage: convert Markdown to HTML#
package main
import (
"bytes"
"fmt"
"log"
"os"
"github.com/yuin/goldmark/v2/parser"
"github.com/yuin/goldmark/v2/renderer/html"
)
func main() {
source, err := os.ReadFile("README.md")
if err != nil {
log.Fatal(err)
}
p := parser.New()
r := html.New()
doc := p.Parse(source)
var buf bytes.Buffer
if err := r.Render(&buf, source, doc); err != nil {
log.Fatal(err)
}
fmt.Print(buf.String())
}
How to enable GitHub Flavored Markdown#
Each extension has a parser half and an HTML renderer half:
import (
"github.com/yuin/goldmark/v2/extension"
"github.com/yuin/goldmark/v2/parser"
"github.com/yuin/goldmark/v2/renderer/html"
)
p := parser.New(parser.WithExtensions(extension.NewGFMParser()))
r := html.New(html.WithExtensions(extension.NewGFMHTMLRenderer()))
GFM enables tables, strikethrough, linkify and task lists. Use the individual constructors (NewTableParser, NewTaskListParser, …) to pick a subset.
How to add footnotes and heading IDs#
p := parser.New(
parser.WithAutoHeadingID(), // <h2 id="installation">
parser.WithExtensions(extension.NewGFMParser(), extension.NewFootnoteParser()),
)
r := html.New(
html.WithExtensions(extension.NewGFMHTMLRenderer(), extension.NewFootnoteHTMLRenderer()),
)
How to allow raw HTML#
r := html.New(
html.WithUnsafe(), // render raw HTML and javascript: links as written
html.WithHardWraps(), // optional: newlines become <br>
)
Only use WithUnsafe for trusted input, or sanitize the result (for example with bluemonday).
How to add custom attributes to headings#
p := parser.New(parser.WithAttribute())
// "## Install {#setup .big}" renders as <h2 id="setup" class="big">Install</h2>
Tips#
- Parsers and renderers can be reused for many documents; create them once.
- The
sourcebyte slice must be passed toRender: AST nodes store positions into it, not copies of the text. parser.WithParseDelimiterFunc(parser.ParseDelimiterSimple)orparser.WithEscapedSpace()give more natural emphasis rules for Chinese, Japanese and Korean text.