Build a Markdown Editor with Live Preview

Markdown editors are everywhere — GitHub issues, Notion, Linear, Reddit. The interview tests whether you understand parsing, security (XSS via injected HTML), and the editor patterns that make Markdown editing feel responsive.

Functional requirements

  • Textarea or contenteditable for typing
  • Live preview pane
  • Syntax highlighting in the source
  • Toolbar (Bold, Italic, Link)
  • Sanitized HTML output

Architecture

Three pieces:

  1. Source editor (textarea or rich)
  2. Markdown parser (markdown → HTML)
  3. Sanitizer (clean HTML)

Source editor: textarea vs CodeMirror

Textarea

Simplest. Plain text. No syntax highlighting. Good for short content.

CodeMirror

Code-editor-style. Syntax highlighting, theming, line numbers. Best for technical Markdown.

Monaco Editor

VS Code’s editor. Heavy (~3MB) but powerful. Overkill for typical Markdown.

Tiptap / ProseMirror

Rich-text editors that can handle Markdown via WYSIWYG-meets-source. Linear and Notion-style. Complex.

For a basic Markdown editor: textarea + syntax highlighting overlay.

Parsing libraries

  • marked: fast, simple, the default
  • markdown-it: more configurable, plugin ecosystem
  • remark / unified: AST-based, powerful but more setup

For most apps, markdown-it is the modern choice.

Sanitization

Markdown allows raw HTML. Without sanitization, an attacker can inject <script>.

Use DOMPurify to clean HTML before rendering. Configure to allow safe elements (img, a) and disallow scripts.

Live preview

Two patterns:

  • Split view: source on left, preview on right (Markdown.com, StackEdit)
  • Tabs: Edit / Preview tabs (GitHub)
  • Inline: formatting appears as you type (Notion, Linear)

Split view is simplest. Inline is more polished but technically demanding.

Performance

For long documents, parsing on every keystroke is slow. Mitigations:

  • Debounce parsing (100–200ms)
  • Incremental parsing (markdown-it supports)
  • Run parser in a Web Worker for very long docs

Toolbar

Common buttons:

  • Bold, Italic, Strike
  • Headings (H1, H2, H3)
  • Link, Image
  • Code block
  • Bulleted list, Numbered list, Blockquote

Implementation: each button wraps selected text in Markdown markers.

Image handling

Most editors support drag-drop or paste of images:

  1. Detect image in clipboard / drop
  2. Upload to your server (or S3)
  3. Insert ![alt](url) at cursor position
  4. Show upload progress

Slash commands

Notion-style: type / to open command menu (heading, code block, list). Powerful UX. Implementation: detect “/” at line start; show floating menu.

Persistence

Auto-save:

  • Debounce 1–2 seconds
  • Save to local storage as fallback
  • Sync to server when online

Important for long-form content; users hate losing work.

Accessibility

  • Toolbar buttons have explicit labels
  • Keyboard shortcuts (Cmd+B for bold)
  • Preview is screen-reader-friendly
  • Source mode is plain textarea (highest accessibility)

Common mistakes

  • Not sanitizing HTML output (XSS hole)
  • Parsing on every keystroke without debounce
  • Image paste does not work
  • No auto-save (users lose work)

Frequently Asked Questions

Should I support GFM (GitHub Flavored Markdown)?

For developer audiences: yes. Tables, task lists, strikethrough are useful. markdown-it supports via plugin.

How do I handle math (LaTeX)?

KaTeX or MathJax. Preview pane renders the math; source shows the LaTeX.

What about diff / comments?

Out of scope for typical Markdown editor. For collaborative review, look at ProseMirror-based editors or specialized tools.

Scroll to Top