Skip to main content

mdka

A HTML to Markdown converter written in Rust.

crates.io npm pypi License
Documentation Dependency Status CI Executable npm PyPi

logo

mdka balances conversion quality with runtime efficiency — correct, readable Markdown from real-world HTML, at competitive speed and near-flat memory.
"ka" means "化 (か)" pointing to conversion.


Why mdka?

There are several good HTML-to-Markdown converters in the Rust ecosystem. mdka's specific focus is:

  • Reliable output from diverse HTML sources. It is built on scraper, which uses html5ever — the HTML5 parser from the Servo browser engine. html5ever applies the same parsing algorithm that web browsers use, so it handles malformed tags, deeply nested structures, CMS output, and SPA-rendered DOM without special-casing.
  • Crash resistance. Conversion uses non-recursive DFS throughout. There is no stack overflow, no matter the nesting depth. That is a claim about crashing, not speed — deep nesting still costs real time, quadratically; see Scaling: Depth and Width.
  • Configurable pre-processing. Five conversion modes let you tune what gets kept or stripped, from noise-free LLM input to maximum retention. Four of the five currently produce identical output — see Conversion Modes.
  • Multi-language. The same Rust implementation is accessible from Node.js (napi-rs) and Python (PyO3).

Quick Start

Try it from the command line

Download a prebuilt binary (no Rust toolchain needed) from the latest release:

Platform Asset
Linux x64 (glibc) mdka@Linux-x64-gnu-<version>.tar.gz
Linux x64 (musl) mdka@Linux-x64-musl-<version>.tar.gz
Linux aarch64 (musl) mdka@Linux-aarch64-musl-<version>.tar.gz
macOS Apple Silicon mdka@macOS-aarch64-<version>.zip
Windows x64 mdka@Windows-x64-<version>.zip

Other platforms (macOS Intel, Windows ARM, Linux aarch64 glibc) aren't built as binaries — use cargo install mdka-cli below instead.

Extract the archive; it contains one folder holding the mdka binary:

cd mdka@Linux-x64-gnu-<version>  # the folder the archive extracted to

echo '<h1>Hello</h1><p><strong>world</strong></p>' | ./mdka
# # Hello
#
# **world**

Or install via cargo — requires cargo (Rust language) installed:

cargo install mdka-cli

echo '<h1>Hello</h1><p><strong>world</strong></p>' | mdka
# # Hello
#
# **world**
mdka page.html                          # → page.md  (same directory)
mdka --mode minimal --drop-shell -o out/ *.html  # strip nav/header/footer
mdka --help                             # full option list

Add to a Rust project

# Cargo.toml
[dependencies]
mdka = "2"
use mdka::html_to_markdown;

let md = html_to_markdown("<h1>Hello</h1><p><em>world</em></p>");
// "# Hello\n\n*world*\n"

With options:

use mdka::html_to_markdown_with;
use mdka::options::{ConversionMode, ConversionOptions};

let html = "<nav>menu</nav><h1>Hello</h1>";
let mut opts = ConversionOptions::for_mode(ConversionMode::Minimal);
opts.drop_interactive_shell = true;
let md = html_to_markdown_with(html, &opts);
// "# Hello\n"

Add to a Node.js project

npm install mdka
const { htmlToMarkdown, htmlToMarkdownWithAsync } = require('mdka')

const md = htmlToMarkdown('<h1>Hello</h1>')
// "# Hello\n"

async function main() {
  const html = '<nav>menu</nav><h1>Hello</h1>'
  const minimal = await htmlToMarkdownWithAsync(html, {
    mode: 'minimal',
    dropInteractiveShell: true,
  })
  console.log(minimal)
}
main()

Add to a Python project

pip install mdka
import mdka

md = mdka.html_to_markdown('<h1>Hello</h1>')
# "# Hello\n"

html = '<nav>menu</nav><h1>Hello</h1>'
minimal = mdka.html_to_markdown_with(
    html,
    mode=mdka.ConversionMode.Minimal,
    drop_interactive_shell=True,
)

Conversion Modes

Mode Use when
Balanced General use — default
Strict Debugging, diff comparison
Minimal LLM input, text extraction
Semantic SPA content, ARIA-aware pipelines
Preserve Archiving, audit trails

Balanced, Strict, Semantic and Preserve currently produce identical output. They differ only in the defaults of fields that have no effect today, so choosing between them changes nothing today. They remain distinct API and may diverge again — see Conversion Modes, which explains why in full.

Tables are not yet converted. <table> cell text is emitted without structure or separators, so a table becomes a run of joined text. See Supported Elements for the full list of what is and is not supported.


Learn More

Full documentation is published as GitHub Pages, and its source lives in docs/.

https://nabbisen.github.io/mdka-rs/

Topic Link
Installation /getting-started/installation
Rust Usage & Examples /getting-started/usage-rust
Node.js Usage /getting-started/usage-nodejs
Python Usage /getting-started/usage-python
CLI Reference /getting-started/usage-cli
API Reference /api/index
Conversion Modes /api/modes
ConversionOptions /api/options
Supported Elements /api/elements
Design Philosophy /design/philosophy
Performance Characteristics /design/performance-characteristics
Architecture /design/architecture
Features /design/features
Changelog CHANGELOG.md
Roadmap ROADMAP.md

Open-source, with care

This project is lovingly built and maintained by volunteers.
We hope it helps streamline your work.
Please understand that the project has its own direction — while we welcome feedback, it might not fit every edge case 🌱

Acknowledgements

Depends on scraper (+ html5ever), ego-tree, rayon, thiserror.

Also, napi-rs on binding for Node.js and PyO3's pyo3 / maturin on bindings for Python.

Release files for mdka 2.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mdka 2.4.0
File Size Uploaded
mdka-2.4.0.tar.gz 961.7 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for mdka 2.4.0
File
mdka-2.4.0-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
mdka-2.4.0-cp310-abi3-musllinux_1_2_x86_64.whl CPython 3.10 abi3 Linux musl 1.2+ x86-64 Details
mdka-2.4.0-cp310-abi3-musllinux_1_2_aarch64.whl CPython 3.10 abi3 Linux musl 1.2+ ARM64 Details
mdka-2.4.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details
mdka-2.4.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.10 abi3 Linux glibc 2.17+ ARM64 Details
mdka-2.4.0-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details

Total release size: 5.0 MB

Release files / mdka-2.4.0.tar.gz

Download URL mdka-2.4.0.tar.gz
Size 961.7 kB
Tags Source
SHA-256 checksum
How to use checksums
e67116b5ed19f66a2f099216d211ffac36d2368edca5dc7489d0abf49da14a1e
BLAKE2b-256 checksum
How to use checksums
92278e39b60a8ff1b8e9f07fdf1cb525ef280301ddfb53c20620fc640a6527f1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.18 {"installer":{"name":"uv","version":"0.12.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / mdka-2.4.0-cp310-abi3-win_amd64.whl

Download URL mdka-2.4.0-cp310-abi3-win_amd64.whl
Size 530.6 kB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
a44003c7e5feaa50f77f44d7d2c1c1ba6ea407250d7445dcce6980d32ac20528
BLAKE2b-256 checksum
How to use checksums
cf27231d0a95a8b38a1716325e2b05072e2a5bd2a554c7a5e6b71d7b93eb2e8c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.18 {"installer":{"name":"uv","version":"0.12.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / mdka-2.4.0-cp310-abi3-musllinux_1_2_x86_64.whl

Download URL mdka-2.4.0-cp310-abi3-musllinux_1_2_x86_64.whl
Size 864.1 kB
Tags CPython 3.10 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
f419b8956fe606add9a0a291f06391e98c7b4d36eb39efc4178cb8c85107d30c
BLAKE2b-256 checksum
How to use checksums
31eadc44b21a528155eec2f4b860d967b088a8d4f6d0b6ab9095af3b15920650
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.18 {"installer":{"name":"uv","version":"0.12.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / mdka-2.4.0-cp310-abi3-musllinux_1_2_aarch64.whl

Download URL mdka-2.4.0-cp310-abi3-musllinux_1_2_aarch64.whl
Size 812.6 kB
Tags CPython 3.10 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
f706ec030e6d3569dcbda955e135d764cb09df4f56d6b6a43c47504a30d83f43
BLAKE2b-256 checksum
How to use checksums
93ccd371c23689b334bc8dfaf0da9bc31f84e398c6eb0eb25a5dc181b2c981f7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.18 {"installer":{"name":"uv","version":"0.12.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / mdka-2.4.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL mdka-2.4.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 630.8 kB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
b1b066f47dffc386aa993533a4467f1a405918e6b21f3c5e438599b6549cc982
BLAKE2b-256 checksum
How to use checksums
d695e91783008e33f86cd2925848bd761487f3d04088d04b46669d72e4ea5954
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.18 {"installer":{"name":"uv","version":"0.12.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / mdka-2.4.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL mdka-2.4.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 633.2 kB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
cd08b968850284623b90e929af88149d9b62c5bfd30bd1550c8cf25b91b8293f
BLAKE2b-256 checksum
How to use checksums
aa5ffc435321acf9f49a86721052c7577bb0db5517b3c2261d20c4d75ad9cfa8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.18 {"installer":{"name":"uv","version":"0.12.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / mdka-2.4.0-cp310-abi3-macosx_11_0_arm64.whl

Download URL mdka-2.4.0-cp310-abi3-macosx_11_0_arm64.whl
Size 564.5 kB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
cf6d42d6f485c145d827412b71608156bc33469ddfc3ada08a9dc3dbe94ba82e
BLAKE2b-256 checksum
How to use checksums
0acb28e997607419ababe2ef21459d7253307f0d84308d4955d41c25eb27f8f5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.18 {"installer":{"name":"uv","version":"0.12.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

2.9.0

7 release files

2.8.0

7 release files

2.7.0

7 release files

2.6.0

7 release files

2.5.1

7 release files

2.5.0

7 release files

2.4.2

7 release files

2.4.1

7 release files

This release

2.4.0 This release

7 release files

2.3.0

7 release files

2.2.3

47 release files

2.2.2

47 release files

2.2.0

47 release files

2.1.8

47 release files

2.1.5

48 release files

2.1.4

48 release files

2.1.1

48 release files

2.1.0

48 release files

2.0.3

48 release files

2.0.2

48 release files

1.6.8

40 release files

1.6.7

40 release files

1.6.5

40 release files

1.6.4

40 release files

1.6.3

40 release files

1.6.2

40 release files

1.6.1

40 release files

1.6.0

40 release files

1.5.0

49 release files

1.4.7

48 release files

1.4.6

48 release files

1.4.5

48 release files

1.4.4

48 release files

1.4.0

44 release files

1.3.3

44 release files

1.3.2

44 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page