npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

markdown-to-html-dom

v0.1.1

Published

Synchronize streaming Markdown to HTML DOM

Downloads

242

Readme

Synchronize streaming Markdown to HTML DOM

markdown-to-html-dom is a minimal browser-focused streaming Markdown renderer, which lets you append Markdown text in chunks and render it incrementally into a target DOM element. This is useful for chat UIs, live logs, and any interface where content arrives over time.

Features

  • Incremental rendering to HTML
  • Keeps finalized blocks stable while rebuilding only the trailing active block
  • Supports common Markdown plus GFM features (tables, task lists, strike-through) via micromark and micromark-extension-gfm
  • Small API surface: push, flush, set, clear, callbacks when elements are created.

Refer to the demo page and the corresponding source code for a full example.

Installation

npm install markdown-to-html-dom

Quick Start

import { MarkdownHTMLConverter } from "markdown-to-html-dom";

const root = document.getElementById("output");
const converter = new MarkdownHTMLConverter(root);

converter.push("# Demo");
converter.push("\n");
converter.push("This paragraph arrives");
converter.push(" in pieces.\n\n");
converter.push("- item one\n");
converter.push("- item two\n");

// Finalize trailing content when the stream ends.
converter.flush();

API

new MarkdownHTMLConverter(rootNode: HTMLElement)

Creates an incremental Markdown renderer bound to an HTML target element.

The element rootNode receives rendered HTML.

Throws TypeError if rootNode is not an HTMLElement.

push(markdownChunk: string): void

Appends a Markdown chunk and re-renders incrementally.

Empty chunks are ignored. Re-render affects only active nodes, finalized nodes are not impacted.

flush(): void

Finalizes any pending trailing block.

Use this when no more chunks are expected (for example, end of stream) so the last active block becomes finalized.

set(markdownText: string): void

Replaces the current output with a full Markdown document.

Renders the provided text as a complete replacement. Clears pending state.

clear(): void

Clears all rendered output and pending state.

onAnchorCreated(callback: (link: HTMLAnchorElement) => void): void

Registers a callback that runs for each newly created anchor element.

Invoked whenever rendered output includes one or more <a href="..."> elements. Useful for setting link behavior (for example target or rel attributes). May be invoked multiple times when active element is cleared and re-populated.

onCodeBlockCreated(callback: (codeBlock: HTMLPreElement) => void): void

Registers a callback that runs for each newly created fenced code block container.

Invoked whenever rendered output includes one or more <pre> code block elements. Useful for syntax highlighting or post-processing rendered code blocks. May be invoked multiple times when active element is cleared and re-populated.

Samples

Nested lists

1. Item 1
2. Item 2
   - Sub-item 2.1
   - Sub-item 2.2

     Paragraph

     > Blockquote
     > across lines

List item contents are wrapped in <p> depending on whether block-level elements are present. This behavior is inherited from micromark.

<ol>
    <li>Item 1</li>
    <li>Item 2
        <ul>
            <li>
                <p>Sub-item 2.1</p>
            </li>
            <li>
                <p>Sub-item 2.2</p>
                <p>Paragraph</p>
                <blockquote>
                    <p>Blockquote across lines</p>
                </blockquote>
            </li>
        </ul>
    </li>
</ol>

Fenced code blocks

~~~python
# Python example
def greet(name):
    return f"Hello, {name}!"

print(greet("World"))
~~~

~~~javascript
// JavaScript example
function greet(name) {
    return \`Hello, \${name}!\`;
}
console.log(greet("World"));
~~~

<pre> elements for fenced code blocks are wrapped in a <div> to allow styling of overflow and borders without affecting the layout.

<div class="code">
<pre><code class="language-python"># Python example
def greet(name):
    return f"Hello, {name}!"

print(greet("World"))
</code></pre>
</div>
<div>
<pre><code class="language-javascript">// JavaScript example
function greet(name) {
    return \`Hello, \${name}!\`;
}
console.log(greet("World"));
</code></pre>
</div>

CSS class hints

In order to help styling, the CSS classes code and table are applied to <div> elements that wrap <pre> and <table> elements, respectively. <ul> elements that represent task lists have the CSS class tasklist.

Active Block Marker

While content is still incomplete, the current trailing block is marked with the attribute data-active. This can be used for styling or UI affordances while streaming.

Usage Notes

This package is browser-oriented and expects DOM globals (document, HTMLElement).

Output is rendered as HTML. If Markdown input is untrusted, validate/sanitize according to your application security requirements.