Installation
Install html-to-markdown for your language using the commands below. Each binding wraps the same Rust core, so behavior matches across runtimes. Pick a tab under Language bindings for copy-paste snippets, feature flags, and a quick verification step where applicable.
Requirements
Section titled “Requirements”| Language | Min version | Package |
|---|---|---|
| Rust | 1.85 | html-to-markdown-rs on crates.io |
| Python | 3.10 | html-to-markdown on PyPI |
| TypeScript / Node.js | Node.js 18 | @xberg-io/html-to-markdown on npm |
| Go | 1.26 | github.com/xberg-io/html-to-markdown/packages/go/v3 |
| Ruby | 3.2 | html-to-markdown on RubyGems |
| PHP | 8.2 | xberg-io/html-to-markdown on Packagist |
| Java | 25 | io.xberg:html-to-markdown on Maven Central |
| C# | .NET 10 | XbergIo.HtmlToMarkdown on NuGet |
| Elixir | 1.14 | html_to_markdown on Hex |
| R | 4.2 | htmltomarkdown on CRAN |
| C | — | libhtml_to_markdown (GitHub Releases) |
| WebAssembly | — | @xberg-io/html-to-markdown-wasm on npm |
| Swift | Swift 6.0 | HtmlToMarkdown SwiftPM package |
| Dart | 3.11 | h2m on pub.dev |
| Kotlin Android | Android minSdk 21 | io.xberg:html-to-markdown-android on Maven Central |
| Zig | 0.16 | html_to_markdown_rs Zig package |
Language bindings
Section titled “Language bindings”Add to Cargo.toml:
[dependencies]html-to-markdown-rs = "3.6"Or via cargo add:
cargo add html-to-markdown-rsVerify:
use html_to_markdown_rs::convert;
fn main() { let result = convert("<h1>Hello</h1>", None).unwrap(); println!("{}", result.content.unwrap()); // # Hello}Feature flags
Section titled “Feature flags”By default only the metadata feature is enabled. Opt in to additional features as needed:
| Feature | Enables | Default | Availability |
|---|---|---|---|
metadata |
HtmlMetadata extraction and all extract_* options |
yes | Available by v3.6 |
visitor |
HtmlVisitor trait and ConversionError::Visitor |
no | Available by v3.6 |
inline-images |
data-URI decoding and inline SVG extraction | no | Available by v3.6 |
serde |
Serialize/Deserialize on all public option and result types |
no | Available by v3.6 |
full |
all of the above | no | Available by v3.6 |
# With visitor supporthtml-to-markdown-rs = { version = "3.10", features = ["visitor"] }
# Everythinghtml-to-markdown-rs = { version = "3.10", features = ["full"] }pip install html-to-markdownUsing uv:
uv add html-to-markdownVerify:
python -c "from html_to_markdown import convert; print(convert('<h1>Hello</h1>').content)"# # HelloRequires Python 3.10+. The package ships precompiled wheels for Linux (x86_64, aarch64), macOS (Apple Silicon, x86_64), and Windows (x64). A source distribution is also available if no wheel matches your platform.
npm install @xberg-io/html-to-markdownUsing pnpm or yarn:
pnpm add @xberg-io/html-to-markdownyarn add @xberg-io/html-to-markdownVerify:
import { convert } from '@xberg-io/html-to-markdown';
const result = convert('<h1>Hello</h1>');console.log(result.content);// # HelloRequires Node.js 18+. The package ships both ESM and CJS outputs with bundled TypeScript types. No separate @types/ package needed.
go get github.com/xberg-io/html-to-markdown/packages/go/v3Verify:
package main
import ( "fmt" htmltomarkdown "github.com/xberg-io/html-to-markdown/packages/go/v3")
func main() { result, err := htmltomarkdown.Convert("<h1>Hello</h1>", nil) if err != nil { panic(err) } fmt.Println(*result.Content) // # Hello}Requires Go 1.26+. The module bundles a precompiled libhtml_to_markdown.a static library for each supported platform — no separate Rust toolchain needed.
gem install html-to-markdownOr add to your Gemfile:
gem 'html-to-markdown', '~> 3.8'Verify:
ruby -e "require 'html_to_markdown'; puts HtmlToMarkdown.convert('<h1>Hello</h1>').content"# # HelloRequires Ruby 3.2+. Precompiled native gems are available for Linux and macOS. On unsupported platforms bundle install will compile the extension from source, which requires a Rust toolchain.
This is a native PHP extension (Rust ext-php-rs), installed with PIE — not composer require (Composer cannot load a native extension):
pie install xberg-io/html-to-markdownVerify:
<?phpuse HtmlToMarkdown\HtmlToMarkdownApi;
$result = HtmlToMarkdownApi::convert('<h1>Hello</h1>');echo $result->content;// # HelloRequires PHP 8.2+. PIE downloads the prebuilt extension binary matching your PHP version and platform from the GitHub release (PHP 8.2–8.5 on Linux x86_64/arm64, macOS arm64, and Windows x86_64).
Maven — add to pom.xml:
<dependency> <groupId>io.xberg</groupId> <artifactId>html-to-markdown</artifactId> <version>3.10.6</version></dependency>Gradle — add to build.gradle:
implementation 'io.xberg:html-to-markdown:3.10.6'Or Kotlin DSL (build.gradle.kts):
implementation("io.xberg:html-to-markdown:3.10.6")Verify:
import io.xberg.htmltomarkdown.HtmlToMarkdown;import io.xberg.htmltomarkdown.HtmlToMarkdownRsException;
public class Main { public static void main(String[] args) throws HtmlToMarkdownRsException { var result = HtmlToMarkdown.convert("<h1>Hello</h1>"); System.out.println(result.content()); // # Hello }}Requires Java 25+. The JAR extracts the native libhtml_to_markdown shared library at startup. No separate install step is needed — the library is bundled for Linux x86_64, macOS arm64/x86_64, and Windows x64.
dotnet add package XbergIo.HtmlToMarkdownOr via the NuGet Package Manager in Visual Studio — search for XbergIo.HtmlToMarkdown.
Verify:
using HtmlToMarkdown;
var result = HtmlToMarkdownConverter.Convert("<h1>Hello</h1>", null);Console.WriteLine(result.Content);// # HelloTargets .NET 10. The package bundles native binaries for Linux, macOS, and Windows via NativeLibrary P/Invoke.
Add to mix.exs:
def deps do [ {:html_to_markdown, "~> 3.8"} ]endThen fetch:
mix deps.getVerify:
{:ok, result} = HtmlToMarkdown.convert("<h1>Hello</h1>")IO.puts(result.content)# # HelloRequires Elixir 1.14+. Uses Rustler NIFs — precompiled NIF binaries are fetched automatically via RustlerPrecompiled. Set RUSTLER_PRECOMPILED_GLOBAL_CACHE_PATH to control cache location.
install.packages("htmltomarkdown", repos = "https://xberg-io.r-universe.dev")Verify:
library(htmltomarkdown)result <- htmltomarkdown::convert("<h1>Hello</h1>")cat(result$content)# # HelloRequires R 4.2+. Available on CRAN for Linux (x86_64), macOS (arm64, x86_64), and Windows.
Download a prebuilt release archive for your platform from the GitHub Releases page. Each archive contains:
libhtml_to_markdown.so/.dylib/.dll— shared librarylibhtml_to_markdown.a— static libraryhtml_to_markdown.h— C header
Build from source (requires Rust toolchain):
git clone https://github.com/xberg-io/html-to-markdown.gitcd html-to-markdowncargo build --release -p html-to-markdown-ffi# output: target/release/libhtml_to_markdown.{so,dylib,dll}Link and verify:
#include "html_to_markdown.h"#include <stdio.h>
int main(void) { HTMAlefHandle result = htm_convert("<h1>Hello</h1>", 0); if (result == 0) { fprintf(stderr, "convert failed: %s\n", htm_last_error_context()); return 1; } char *content = htm_conversion_result_content(result); if (content != NULL) { printf("%s\n", content); htm_free_string(content); } htm_conversion_result_free(result); return 0;}Compile with:
gcc main.c -lhtml_to_markdown -L./target/release -o mainEvery heap-allocated string returned across the FFI must be released with htm_free_string, and every result/options handle must be released with the matching htm_*_free function. The memory belongs to the Rust allocator — do not call free() directly.
npm install @xberg-io/html-to-markdown-wasmVerify:
import { convert } from '@xberg-io/html-to-markdown-wasm';
const result = convert('<h1>Hello</h1>');console.log(result.content);// # HelloThe package’s default (Node.js) entry point loads the .wasm module synchronously — no init() call needed. Browser and bundler consumers import the web/bundler build instead, which exports an async init() function that must complete before the first convert() call. Works in browsers, Cloudflare Workers, Deno, and Bun.
Add the package URL in SwiftPM:
https://github.com/xberg-io/html-to-markdownVerify:
import HtmlToMarkdown
let result = try convert(html: "<h1>Hello</h1>")print(result.content()?.toString() ?? "")Requires Swift 6.0+. The package currently targets macOS 13+ and iOS 16+.
dart pub add h2mVerify:
import 'package:h2m/h2m.dart';import 'package:h2m/src/html_to_markdown_rs_bridge_generated/frb_generated.dart' show RustLib;
await RustLib.init();final result = await H2mBridge.convert('<h1>Hello</h1>');print(result.content);Requires Dart 3.11+. The generated package is pure Dart from the caller’s point of view and uses flutter_rust_bridge under the hood.
Add the Android artifact:
implementation("io.xberg:html-to-markdown-android:3.10.6")Requires Android minSdk 21. This is an Android AAR with bundled JNI libraries; Kotlin/JVM users should use the Java artifact (io.xberg:html-to-markdown) directly.
Use the Zig package html_to_markdown_rs from the release artifacts or the repository package metadata.
const html_to_markdown = @import("html_to_markdown_rs");Requires Zig 0.16+. The package wraps the generated C FFI library.
Troubleshooting on Windows
Section titled “Troubleshooting on Windows”If pip install html-to-markdown fails on Windows 11 with Python 3.14 or later, try these steps:
-
Force the prebuilt wheel:
Terminal window pip install --only-binary=:all: html-to-markdownThis prevents fallback to source build. If this fails, a wheel resolution issue exists — try updating
piporuv. -
Enable MSVC compiler (if sdist build is required): Install Microsoft Visual Studio Build Tools with the “Desktop development with C++” workload. Then ensure MSVC’s
link.exeprecedes any GNU variants inPATH. Check withwhere link— the first result should be a path underVC\Tools\MSVC. -
Update pip or uv: Python 3.14 wheel tags are recent. Run
pip install --upgrade piporuv self updateto ensure correct wheel matching.
Install via Cargo, or use cargo-binstall to grab the prebuilt binary from GitHub Releases:
cargo install html-to-markdown-clicargo binstall html-to-markdown-cliOr via Homebrew:
Homebrew 6.0+ requires explicit trust for third-party taps. Trust once, then install:
brew trust xberg-io/tapbrew install xberg-io/tap/html-to-markdownVerify:
echo "<h1>Hello</h1>" | html-to-markdown# # HelloSee CLI reference for all flags and options.
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.