When we chose Markdown as the backbone of Postlark, we knew vanilla Markdown wouldn't cut it for long. Standard Markdown gives you paragraphs, headings, links, images, bold, italic — the basics. But modern technical writing demands diagrams, math equations, callouts, syntax-highlighted code with file names. Writers expect these things. So we had to decide: how far do we extend the format without turning it into something unrecognizable?
GFM as the Foundation
We started with GitHub Flavored Markdown. It's the de facto standard for developers — tables, strikethrough, task lists, autolinked URLs. If you've written a README on GitHub, you already know the syntax. Zero learning curve, zero debate. The harder question was what comes after.
The Ten-Extension Drop
About five weeks into development, we shipped ten extensions in a single commit. Not because we planned some grand rollout — we'd been accumulating a list of "we really need this" items and just decided to knock them all out at once.
Heading IDs and anchor links. Every heading gets a slug-based ID automatically. Click a heading, get a permalink. For long posts with lots of sections, this is the kind of thing you don't notice until it's missing.
Table of contents. Drop [TOC] anywhere in your post and it renders a linked outline from your headings. Not every post needs one, but for 3000-word tutorials, readers will thank you.
Footnotes. Academic-style [^1] references that collect at the bottom of the page. We debated whether bloggers actually use these. Turns out technical writers love them for citing papers and RFCs without cluttering the main text.
Math rendering. Both inline $E = mc^2$ and display-mode $$ equations, rendered via KaTeX on the client side. Niche, but for anyone writing about machine learning or statistics, it's non-negotiable. You can't describe a loss function in prose alone.
Mermaid diagrams. Wrap a fenced code block in mermaid and it renders as a flowchart, sequence diagram, entity-relationship diagram, or whatever else Mermaid supports. This was probably the most-requested feature before we even had a public beta.
Callouts. GitHub's > [!NOTE] syntax for styled info boxes — NOTE, TIP, WARNING, CAUTION, IMPORTANT. Genuinely useful for documentation-style posts where you need to flag something without breaking the reader's flow. A short aside that stands apart visually from the surrounding paragraphs.
Emoji shortcuts. :rocket: becomes 🚀. We mapped about 40 common shortcuts — the ones developers actually type. Could we have gone further? Sure. But shipping 400 emoji mappings that nobody uses didn't seem like a good use of time.
Task lists. GFM already has - [ ] checkbox syntax, but we added proper styling — custom CSS, checkboxes disabled by default so readers can't accidentally toggle them. Small detail, big visual difference.
Enhanced code blocks. This one deserved extra attention. You can add a title="filename.ts" attribute to your code fences, enable line numbers with showLineNumbers, and highlight specific lines for diff-style presentation. For a platform where most writers are developers, code presentation arguably matters more than any other visual element.
Syntax highlighting. Class-based highlighting powered by highlight.js, loaded asynchronously so it doesn't block page rendering. We wanted the published blog to stay lightweight while still giving code blocks proper coloring across dozens of languages.
Keeping Three Renderers in Sync
Here's the part nobody warns you about when building a publishing platform: you don't render Markdown in one place. Postlark renders it in three — the API when content is stored, the dashboard for live preview while you're writing, and the published blog for readers. All three need to produce identical results, or writers lose trust in the preview.
After the initial ten-extension drop, we ran an audit and found seven inconsistencies. The dashboard preview didn't generate table-of-contents entries at all. Task list items had a different class structure than the published version. A footnote wrapper used a greedy regex pattern that broke when multiple footnotes appeared. Strikethrough styling was completely absent from two of the three surfaces.
Seven bugs from one commit. Every single one was a case where the parser handled things correctly, but the CSS or rendering path diverged somewhere downstream. We fixed them in a follow-up pass, but it reinforced a lesson: markdown extensions are easy to add, genuinely hard to keep consistent across multiple rendering targets.
YouTube Embeds
A couple of days after the main extension drop, we added YouTube embedding as the eleventh extension. Paste a YouTube URL on its own line and it becomes a responsive 16:9 iframe. We use the youtube-nocookie.com embed domain so readers don't pick up Google tracking cookies just because a blog post includes a video.
One subtle decision: video IDs are restricted to an 11-character alphanumeric pattern, which is what YouTube actually uses. Anything that doesn't match gets treated as a regular link. Simple rule, but it closes a class of injection attacks where a crafted URL could look like a video embed but point somewhere else entirely.
What We Chose Not to Build
Plenty of Markdown extensions exist that we deliberately skipped. Abbreviations, definition lists, custom containers with arbitrary class names, raw HTML passthrough without sanitization. Each one has advocates in various communities.
Our filter was blunt: does this feature appear in at least two of our own blogs? If nobody on the team reaches for it, it doesn't ship. Adding features later is straightforward. Removing one that people already depend on is a different kind of problem.
The Dark Mode Tax
Every visual extension needs to work in both light and dark themes. Callout boxes need different background tones. Mermaid has its own theme system, so we detect the reader's color scheme preference and switch the diagram theme automatically. Code blocks need a dark-friendly syntax palette. Even KaTeX formulas need to render in a color that's readable against a dark background.
This roughly doubled the CSS surface area for every feature we shipped. Not glamorous work. But readers notice a broken dark mode callout instantly — it's one of those things where getting it wrong undermines everything else you got right.
Where Things Stand
Postlark now supports eleven markdown extensions on top of GFM. They work across the API, the dashboard editor with live preview, and the published blog. Dark mode is covered for all of them.
The approach has been pragmatic. We're not trying to replace Notion or compete with Google Docs. Markdown with sensible extensions covers the vast majority of what technical bloggers actually write. For the rare post that needs something truly exotic, direct HTML is always there as an escape hatch — sanitized, of course.
Next time: how Postlark generates Open Graph images automatically, and the surprisingly tricky problem of rendering Korean text in a serverless environment.