HTML-to-Markdown is an open-source Go library and command-line tool that converts HTML input — including entire websites — into clean, readable Markdown, with plugin support for customizing the conversion.
What is HTML-to-Markdown?
HTML-to-Markdown is an open-source Go project maintained by Johannes Kaufmann, available on GitHub. It provides a v2 Golang library (github.com/JohannesKaufmann/html-to-markdown/v2) and a CLI executable called html2markdown. The converter takes HTML as input — from a string, a file, or piped stdin — and outputs Markdown text. It implements the CommonMark specification for core formatting and the GitHub Flavored Markdown spec for its table plugin. The library's main entry point is htmltomarkdown.ConvertString(), a wrapper around converter.NewConverter() with the base and commonmark plugins registered.
Key Features
- Bold and italic support — Handles emphasis even within single words, producing correct Markdown emphasis markers.
- Full list handling — Converts ordered and unordered lists with nesting support, matching CommonMark list rules.
- Nested blockquotes — Supports blockquotes that contain other elements, including nested quotes.
- Code block preservation — Correctly handles backticks and multi-line code blocks, preserving code structure without breaking fenced blocks.
- Link and image conversion — Properly formats multi-line links and images, adding escapes for blank lines where needed.
- Smart escaping — Escapes special characters only when necessary to avoid accidental Markdown rendering, with details documented in ESCAPING.md.
- Configurable tag handling — Choose to remove or keep specific HTML tags using
TagTypeandRendererForregistration, with a priority system (e.g.PriorityEarly) to override defaults like the removal of<style>. - Plugin system — Extend functionality with pre-built plugins (Strikethrough converts
<strike>,<s>, and<del>to~~; Table implements GFM tables with alignment, rowspan, and colspan) or write custom plugins and publish them.
Who should use HTML-to-Markdown?
- Go developers — Integrate HTML-to-Markdown into Go applications using
ConvertString()or the lower-levelconverter.NewConverter()with the base and commonmark plugins for full control over conversion. - Content and automation engineers — Script bulk conversion of HTML files or website output into Markdown using the CLI's
--inputand--outputflags, including glob patterns and selectors like--include-selectorand--exclude-selector. - Documentation and static-site maintainers — Convert existing HTML documentation or blog exports into Markdown for use in GitHub pages, static site generators, or knowledge bases, optionally making relative links absolute with
--domain. - CLI users — Perform quick conversions from the command line with pipe input, e.g.
echo "<strong>important</strong>" | html2markdown.
What can you do with HTML-to-Markdown?
- Web scraping to notes: Fetch a webpage with
curl --no-progress-meter http://example.com | html2markdownto get a clean Markdown version for personal notes or archiving. - Site-wide conversion: Use
html2markdown --input "src/*.html" --output "dist/"to convert a folder of HTML files to Markdown, preserving relative links with--domain. - Plugin-based customization: Add the table plugin via
--plugin-tableto convert HTML tables with rowspan and colspan, or write a custom Go plugin and register it to handle web components or custom elements. - API or online demo: Try the hosted REST API at html-to-markdown.com/api or the online demo at html-to-markdown.com without installing anything.
How does HTML-to-Markdown work?
The library parses HTML with Go's html.Parse() and walks the resulting DOM, applying registered converters and plugins. The CLI reads input from stdin, a file, or a glob pattern, converts it using the same engine, and writes to stdout or a file. Relative URLs can be made absolute with WithDomain in the library or --domain in the CLI.
Pros and cons
- Pros: Open source under the MIT license; supports both library and CLI usage; handles complex HTML including nested lists, blockquotes, and code blocks; provides plugins for extended syntax; thread-safe
Converterusable from multiple goroutines. - Cons: Does not sanitize untrusted HTML — the documentation recommends using an HTML sanitizer such as bluemonday before displaying converted output in a browser; expects input already encoded as UTF-8 and will emit replacement characters for other charsets; some v1 plugins (e.g. YouTube embed, Confluence) are not yet ported to v2 and are marked as planned.
FAQ
Is html-to-markdown free?
Yes, the project is open source and licensed under the MIT license, and the source code is available on GitHub.
What input formats are supported?
The tool accepts any HTML, including entire web pages. Internally it uses Go's html.Parse() and requires the input to be UTF-8 encoded; it does not handle charset detection or conversion.
Does html-to-markdown sanitize the output?
No. The library does not sanitize untrusted content. If you render the resulting Markdown back to HTML for display, you should pass it through an HTML sanitizer like bluemonday to prevent malicious content from being shown.
Can I use html-to-markdown from multiple goroutines?
Yes, the Converter type is safe for concurrent use because a mutex protects internal state, and the project includes a test covering this behavior.
How do I extend the converter?
You can write custom logic and register it with conv.Register (for example, TagType, RendererFor, or a custom plugin). The documentation includes a WRITING_PLUGINS.md guide, and the repo has example code for registration.








