
Hmmarkdown
Hmmarkdown êŽë š
I rolled my own Markdown library!
Itâs called Hmmarkdown on GitHub. Itâs published on both JSR and NPM (@dbushell/hmmarkdown) too. Iâm testing in production on my own website! That might be a mistake but itâs too late now.
â ïž Work in progress! â ïž
Hmmarkdown is bad code and full of bugs. Okay, well it does work, but with limitations. Some of those limitations are by design!
Backstory
Iâve long used Marked (markedjs/marked) which is a perfectly cromulent choice. Marked has active development and plenty of plugins. It gets the job done.
Why change? I wanted:
- A challenge
- More control over HTML
Most Markdown parsers give up when they find HTML. I created Hmmarkdown to better handle scenarios where I want HTML in my Markdown.
For example Hmmarkdown transforms this:
<aside class="Box">
This is a **boxed** paragraph.
</aside>
Into this:
<aside class="Box">
<p>This is a <strong>boxed</strong> paragraph.</p>
</aside>
Which looks like this:
This is a **boxed** paragraph.
Marked couldnât handle this without a bespoke and hacky extension.
Hmmarkdown is HTML-aware. When it finds HTML it creates a lightweight node tree to isolate text content and apply inline Markdown filters. This works regardless of node depth. Only inline Markdown is supported inside HTML for now. Block Markdown is trickier because Iâll need to track indentation and do some recursive magic. Thatâs the end goal for âv1.0â.
First Iâm considering a major refactor. Iâve hit a bit of a technical wall and probably over-engineered it. I have a better approach I want to try.
Markdown Specification
As CommonMark says:
CommonMark (commonmark.org)
John Gruberâs canonical description of Markdownâs syntax does not specify the syntax unambiguously.

Attempts to standardise Markdown are insane. Just look at the GitHub Flavored Markdown Spec which attempts to support every variation imaginable. No way Iâm parsing that. My syntax support for top-level blocks is extremely strict. See the README documentation.
Hmmarkdown is so strict and unforgiving Iâve spent the last two week correcting errors on my blog. I have no plans to add support for anything beyond basic Markdown. Extended syntax for tables is wild, for example. Itâs easier to just write HTML in my opinion. Thatâs why I created Hmmarkdown. I can break out the HTML and mix-n-match.
Is it Fast?
I benchmarked a few micro-optimisations like checking if a string begins with a specific character before matching:
if (line[0] !== '#') return false;
const match = line.match(/^(#{1,6})\s+/);
I stopped optimising when I realised speed was a non-issue.
Every JavaScript library claims to be the âfastest everâ. The truth with Markdown is that most competent parsers are already as fast as JavaScript allows. The bottleneck becomes I/O and CPU & memory limits. Rendering the ~400 pages on my website takes under two seconds and 90% of that time is waiting for Shiki syntax highlighting. Itâs milliseconds or less per file. If thatâs too slow stop using JavaScript!
Work in Progress
Hmmarkdown is early stage development and not the prettiest code. I will be extending the Markdown syntax support and there will be one or two refactors along the way. It will always be an opinionated library made for my use case; this blog. Itâs open source and MIT licensed so anyone is welcome to try it. It should work in all JavaScript runtimes.
Update for 22 Jan 2026
Hmmarkdown 2 is now a thing! I coded a new tokenizer.