Language Binding Guides
Every binding wraps the same Rust core. The option names and return shapes are identical across languages; only the syntax differs. This page covers per-language install notes and naming conventions.
Package: html-to-markdown-rs on crates.io
html-to-markdown-rs = "3.6"Option structs follow Rust naming conventions (snake_case). Use the builder API via ConversionOptions::builder() or construct ConversionOptions directly.
See Installation: Feature Flags for the five Cargo features.
Python
Section titled “Python”Package: html-to-markdown on PyPI
Requires: Python ≥ 3.10
pip install html-to-markdownfrom html_to_markdown import convert, ConversionOptions
result = convert("<h1>Title</h1>", ConversionOptions(heading_style="atx"))print(result.content)Option keys match the Rust field names (snake_case). ConversionOptions accepts keyword arguments. ConversionResult is a class with attributes — access fields as result.content, result.metadata, result.tables, result.images, result.document, result.warnings.
TypeScript
Section titled “TypeScript”Package: @xberg-io/html-to-markdown on npm
Requires: Node.js ≥ 18
npm install @xberg-io/html-to-markdownimport { convert } from "@xberg-io/html-to-markdown";
const result = convert("<h1>Title</h1>", { headingStyle: "atx" });console.log(result.content);Option keys are camelCase (headingStyle, linkStyle, outputFormat). The package ships both ESM and CJS outputs. TypeScript types are bundled.
Module: github.com/xberg-io/html-to-markdown/packages/go/v3
Requires: Go ≥ 1.26
go get github.com/xberg-io/html-to-markdown/packages/go/v3import htmltomarkdown "github.com/xberg-io/html-to-markdown/packages/go/v3"
result, err := htmltomarkdown.Convert("<h1>Title</h1>", nil)if err != nil { log.Fatal(err)}fmt.Println(result.Content)Options use Go struct field names (PascalCase). Convert returns (*ConversionResult, error). Errors are standard Go errors. Use errors.Is/errors.As to inspect them.
Gem: html-to-markdown on RubyGems
Requires: Ruby ≥ 3.2
gem install html-to-markdownrequire 'html_to_markdown'
result = HtmlToMarkdown.convert('<h1>Title</h1>', heading_style: :atx)puts result[:content]Options are keyword arguments with snake_case symbols. result is a hash. Errors raise HtmlToMarkdown::ConversionError.
Package: xberg-io/html-to-markdown (native ext-php-rs extension)
Requires: PHP ≥ 8.2
Install with PIE — not composer require, which cannot load a native extension:
pie install xberg-io/html-to-markdownuse HtmlToMarkdown\HtmlToMarkdownApi;use HtmlToMarkdown\ConversionOptions;
$options = ConversionOptions::builder()->headingStyle('atx')->build();$result = HtmlToMarkdownApi::convert('<h1>Title</h1>', $options);echo $result->content;Classes live in the flat HtmlToMarkdown\ namespace. HtmlToMarkdownApi::convert returns a ConversionResult object ($result->content, $result->metadata, $result->tables). Conversion failures throw HtmlToMarkdown\HtmlToMarkdownException.
Maven: io.xberg:html-to-markdown
Requires: Java ≥ 25
<dependency> <groupId>io.xberg</groupId> <artifactId>html-to-markdown</artifactId> <version>3.6.8</version></dependency>import io.xberg.htmltomarkdown.HtmlToMarkdown;import io.xberg.htmltomarkdown.ConversionOptions;import io.xberg.htmltomarkdown.ConversionResult;
ConversionOptions options = ConversionOptions.builder() .headingStyle("atx") .build();ConversionResult result = HtmlToMarkdown.convert("<h1>Title</h1>", options);System.out.println(result.getContent());Uses a builder for options. Conversion failures throw io.xberg.htmltomarkdown.HtmlToMarkdownRsException and its subtypes (ParseErrorException, ConfigErrorException, InvalidInputException, PanicException, OtherException). Native binaries ship in the JAR for Linux x86_64, macOS arm64/x86_64, and Windows x86_64.
C# (.NET)
Section titled “C# (.NET)”NuGet: XbergIo.HtmlToMarkdown
Requires: .NET 10
dotnet add package XbergIo.HtmlToMarkdownusing HtmlToMarkdown;
var options = new ConversionOptions { HeadingStyle = "atx" };var result = HtmlToMarkdownConverter.Convert("<h1>Title</h1>", options);Console.WriteLine(result.Content);Classes live in the HtmlToMarkdown namespace (the XbergIo.HtmlToMarkdown prefix is only the NuGet package id). Properties are PascalCase. Errors throw HtmlToMarkdownRsException and subtypes.
Elixir
Section titled “Elixir”Hex: html_to_markdown
Requires: Elixir ≥ 1.14
{:html_to_markdown, "~> 3.8"}case HtmlToMarkdown.convert("<h1>Title</h1>", heading_style: :atx) do {:ok, result} -> IO.puts(result.content) {:error, reason} -> IO.warn("failed: #{reason}")endconvert/2 returns {:ok, result} or {:error, reason}. Options are a keyword list. The struct fields match the Rust names (snake_case).
CRAN: htmltomarkdown
Requires: R ≥ 4.2
install.packages("htmltomarkdown", repos = "https://xberg-io.r-universe.dev")library(htmltomarkdown)
result <- htmltomarkdown::convert("<h1>Title</h1>", heading_style = "atx")cat(result$content)Options are named function arguments. The returned list matches the ConversionResult shape with snake_case names. Errors stop execution with a message; wrap in tryCatch if you need to handle them.
Link against: libhtml_to_markdown
Header: html_to_markdown.h (HTM*H, all symbols prefixed htm*_/HTM_)
Download a pre-built release archive for your platform from the GitHub releases page, or build from source with cargo build --release -p html-to-markdown-ffi.
#include "html_to_markdown.h"
HTMConversionResult *result = htm_convert("<h1>Title</h1>", NULL);if (result != NULL) { char *content = htm_conversion_result_content(result); if (content != NULL) { printf("%s\n", content); htm_free_string(content); } htm_conversion_result_free(result);}Every heap-allocated string must be released with htm_free_string and every handle with the matching htm_*_free function. The C API is a thin synchronous FFI layer. No async mode, no thread-local state. Conversion errors return NULL and set the thread-local error accessible via htm_last_error_code / htm_last_error_context.
npm: @xberg-io/html-to-markdown-wasm
npm install @xberg-io/html-to-markdown-wasmimport init, { convert } from "@xberg-io/html-to-markdown-wasm";
await init();const result = convert("<h1>Title</h1>", { headingStyle: "atx" });console.log(result.content);init() loads and instantiates the .wasm file. Call it once before any conversion. After that, convert is synchronous. Options use camelCase and have the same shape as the TypeScript binding. The WASM build exposes inline image extraction when built with inline-images; generated native bindings may omit the Rust-only image payload.
Package: HtmlToMarkdown via SwiftPM
Requires: Swift ≥ 6.0
Add the package from https://github.com/xberg-io/html-to-markdown and import HtmlToMarkdown.
Package: h2m on pub.dev
Requires: Dart ≥ 3.11
dart pub add h2mThe package is pure Dart from the caller’s point of view and uses the generated flutter_rust_bridge runtime.
Kotlin Android
Section titled “Kotlin Android”Package: io.xberg:html-to-markdown-android
Requires: Android minSdk 21
Kotlin Android is an AAR with bundled JNI libraries. Kotlin/JVM users should use the Java package (io.xberg:html-to-markdown) directly.
Package: html_to_markdown_rs
Requires: Zig ≥ 0.16
The Zig package wraps the C FFI surface and links to the generated native library.
Found a bug or mistake on this page?
If something here is wrong or out of date, open an issue on GitHub or contribute a fix via pull request.