Skip to content

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.

Package: html-to-markdown on PyPI Requires: Python ≥ 3.10

Terminal window
pip install html-to-markdown
from 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.

Package: @xberg-io/html-to-markdown on npm Requires: Node.js ≥ 18

Terminal window
npm install @xberg-io/html-to-markdown
import { 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

Terminal window
go get github.com/xberg-io/html-to-markdown/packages/go/v3
import 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

Terminal window
gem install html-to-markdown
require '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:

Terminal window
pie install xberg-io/html-to-markdown
use 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.

NuGet: XbergIo.HtmlToMarkdown Requires: .NET 10

Terminal window
dotnet add package XbergIo.HtmlToMarkdown
using 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.

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}")
end

convert/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

Terminal window
npm install @xberg-io/html-to-markdown-wasm
import 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

Terminal window
dart pub add h2m

The package is pure Dart from the caller’s point of view and uses the generated flutter_rust_bridge runtime.

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.