markitdown-html
v0.1.0
Published
A faithful TypeScript port of Microsoft MarkItDown's HTML-to-Markdown converter. Works in Node.js and the browser.
Downloads
26
Maintainers
Readme
markitdown-html
A faithful TypeScript port of the HTML-to-Markdown converter from Microsoft MarkItDown. It turns HTML documents (or fragments) into clean Markdown and runs in both Node.js and the browser.
The conversion algorithm is ported from the
markdownify library
that MarkItDown builds on, plus MarkItDown's own customisations (ATX headings by
default, JavaScript-link removal, data: URI truncation, checkbox inputs, …).
- ✅ TypeScript + ES Modules
- ✅ Isomorphic — works in Node.js and browsers (no DOM required; uses the
pure-JS
htmlparser2parser) - ✅ Zero-config defaults matching MarkItDown
- ✅ Fully typed public API with rich options
- ✅ Linted with ESLint and formatted with Prettier
Installation
npm install markitdown-htmlRequires Node.js 18+ (for the global
TextEncoder/TextDecoder). Works in any modern bundler/browser target.
Quick start
import { convertHtmlToMarkdown } from 'markitdown-html';
const markdown = convertHtmlToMarkdown(
'<h1>Hello</h1><p>This is <strong>bold</strong> and <em>italic</em>.</p>',
);
console.log(markdown);
// # Hello
//
// This is **bold** and *italic*.Getting the document title too
import { convert } from 'markitdown-html';
const { markdown, title } = convert(
'<html><head><title>My Page</title></head><body><p>Hi</p></body></html>',
);
console.log(title); // "My Page"
console.log(markdown); // "Hi"Using the class API
import { HtmlConverter } from 'markitdown-html';
const converter = new HtmlConverter();
converter.convertToMarkdown('<h2>Section</h2>'); // "## Section"
converter.convert('<h2>Section</h2>'); // { markdown: "## Section", title: null }Usage in the browser
Because the library ships as standard ES modules and uses a pure-JavaScript HTML parser, it works directly in the browser with any bundler (Vite, webpack, esbuild, Rollup, …):
import { convertHtmlToMarkdown } from 'markitdown-html';
const html = document.querySelector('#content')!.innerHTML;
const markdown = convertHtmlToMarkdown(html);Or straight from a CDN as an ES module:
<script type="module">
import { convertHtmlToMarkdown } from 'https://esm.sh/markitdown-html';
console.log(convertHtmlToMarkdown('<h1>Hi</h1>'));
</script>API
convertHtmlToMarkdown(html, options?) => string
Convert an HTML string and return only the Markdown text.
convert(html, options?) => { markdown, title }
Convert an HTML string and return the Markdown together with the document
<title> (or null when absent).
class HtmlConverter
convert(html, options?)→{ markdown, title }convertToMarkdown(html, options?)→string
Lower-level exports
MarkdownConverter— the base converter (a port ofmarkdownify).CustomMarkdownConverter—MarkdownConverterplus MarkItDown's overrides.resolveOptions, and theHeadingStyle,NewlineStyle,EmphasisSymbol,StripStyleenums.
Options
All options are optional. Defaults match MarkItDown.
| Option | Type | Default | Description |
| ---------------------- | ----------------------------- | ---------- | --------------------------------------------------------------------- |
| headingStyle | HeadingStyle | 'atx' | 'atx' (#), 'atx_closed' (# … #), or 'underlined' (===). |
| strongEmSymbol | string | '*' | Symbol used for <strong>/<em>. |
| bullets | string | '*+-' | Bullet characters cycled per list depth. |
| newlineStyle | NewlineStyle | 'spaces' | <br> rendering: 'spaces' (two spaces) or 'backslash'. |
| autolinks | boolean | true | Emit <url> when the link text equals its href. |
| defaultTitle | boolean | false | Use the href as the link title when none is given. |
| escapeAsterisks | boolean | true | Escape * in text. |
| escapeUnderscores | boolean | true | Escape _ in text. |
| escapeMisc | boolean | false | Escape miscellaneous Markdown punctuation. |
| keepInlineImagesIn | string[] | [] | Parent tags in which inline images are preserved. |
| codeLanguage | string | '' | Default language annotation for fenced code blocks. |
| codeLanguageCallback | (el) => string \| undefined | — | Per-<pre> language resolver. |
| stripDocument | StripStyle \| null | 'strip' | Document-level newline trimming. |
| stripPre | StripStyle \| null | 'strip' | <pre> newline trimming. |
| subSymbol | string | '' | Wrapper for <sub>. |
| supSymbol | string | '' | Wrapper for <sup>. |
| tableInferHeader | boolean | false | Infer a header row for tables lacking one. |
| wrap | boolean | false | Word-wrap paragraph text. |
| wrapWidth | number \| null | 80 | Wrap width when wrap is enabled. |
| convert | string[] | — | Only convert these tags (mutually exclusive with strip). |
| strip | string[] | — | Remove these tags (mutually exclusive with convert). |
| keepDataUris | boolean | false | Keep full data: image URIs instead of truncating them. |
| strict | boolean | false | Re-throw stack-overflow errors instead of falling back to plain text. |
Examples
import { convertHtmlToMarkdown, HeadingStyle } from 'markitdown-html';
// Setext-style headings
convertHtmlToMarkdown('<h1>Title</h1>', {
headingStyle: HeadingStyle.UNDERLINED,
});
// "Title\n====="
// Keep full data URIs on images
convertHtmlToMarkdown('<img src="data:image/png;base64,AAAA" alt="x">', {
keepDataUris: true,
});
// ""
// Only convert a subset of tags
convertHtmlToMarkdown('<h1>Kept</h1><p>Stripped tag, kept text</p>', {
convert: ['h1'],
});Supported HTML
Headings (h1–h6), paragraphs, br, hr, strong/b, em/i, del/s,
code/kbd/samp, pre, blockquote, a, img, video, ordered and
unordered lists (including nesting), definition lists (dl/dt/dd), tables
(table/thead/tbody/tr/th/td/caption, with colspan), q, sub,
sup, figcaption, and checkbox inputs. script and style content is
removed.
Differences from MarkItDown
This package ports MarkItDown's generic HTML converter. MarkItDown also ships
site-specific converters (Wikipedia, Bing SERP, RSS, …) that pre-process the DOM
before conversion; those are out of scope here. Given the same HTML, the Markdown
body produced by this library matches MarkItDown's HtmlConverter.
Development
npm install
npm run build # compile to dist/
npm test # run the test suite (vitest)
npm run lint # ESLint
npm run format # Prettier
npm run typecheck # tsc --noEmitLicense
This project is an independent reimplementation inspired by microsoft/markitdown (MIT) and python-markdownify (MIT).
