Handles messy, real-world HTML
Unclosed tags, odd entities, nested tables, mixed encodings — you get clean output without losing content.
Handles messy, real-world HTML
Unclosed tags, odd entities, nested tables, mixed encodings — you get clean output without losing content.
Use it from your language, identical output
One converter behind Python, TypeScript, Go, Ruby, Java, and 11 more runtimes. The same input gives the same result everywhere.
Markdown, Djot, or plain text
Pick the output you need with a single option. Everything else works the same.
Get the metadata too
Pull the title, Open Graph, Twitter Card, JSON-LD, links, and images in the same pass — on by default.
Keep your tables structured
Get HTML tables back as structured rows and cells, spans and headers included, alongside the rendered Markdown.
Customize the conversion
Hook into the conversion to skip, replace, or preserve any element — and pay nothing when you don’t.
| Language | Install | API Reference |
|---|---|---|
| Rust | cargo add html-to-markdown-rs |
Reference |
| Python | pip install html-to-markdown |
Reference |
| TypeScript / Node | npm install @xberg-io/html-to-markdown |
Reference |
| Go | go get github.com/xberg-io/html-to-markdown/packages/go/v3 |
Reference |
| Ruby | gem install html-to-markdown |
Reference |
| PHP | pie install xberg-io/html-to-markdown |
Reference |
| Java | Maven io.xberg:html-to-markdown |
Reference |
| C# | dotnet add package XbergIo.HtmlToMarkdown |
Reference |
| Elixir | {:html_to_markdown, "~> 3.8"} |
Reference |
| R | install.packages("htmltomarkdown") |
Reference |
| C (FFI) | Shared library + header | Reference |
| WebAssembly | npm install @xberg-io/html-to-markdown-wasm |
Reference |
| Swift | Swift Package HtmlToMarkdown |
Reference |
| Dart | dart pub add h2m |
Reference |
| Kotlin Android | Maven io.xberg:html-to-markdown-android |
Reference |
| Zig | Zig package html_to_markdown_rs |
Reference |
| CLI | cargo install html-to-markdown-cli |
CLI Guide |
from html_to_markdown import convert
result = convert("<h1>Hello</h1><p>World</p>")print(result.content)print(result.metadata)import { convert } from "@xberg-io/html-to-markdown";
const result = convert("<h1>Hello</h1><p>World</p>");console.log(result.content);console.log(result.metadata);use html_to_markdown_rs::convert;
fn main() -> Result<(), Box<dyn std::error::Error>> { let result = convert("<h1>Hello</h1><p>World</p>", None)?; println!("{}", result.content.unwrap_or_default()); Ok(())}