Milkdown
Plugin-driven WYSIWYG markdown editor built on ProseMirror + remark. Markdown-native with clean round-tripping.
Try it
Edit the content below — it's a full WYSIWYG markdown editor. The markdown source updates live below the editor.
Milkdown Editor Loading...
Markdown Output
Architecture
Milkdown uniquely combines two powerful systems — ProseMirror for editing and remark for markdown processing:
typescript
// Milkdown's pipeline:
//
// Input: Markdown string
// ↓ remark-parse → MDAST
// ↓ transform → ProseMirror document
// ↓ edit in ProseMirror (WYSIWYG)
// ↓ serialize → MDAST
// ↓ remark-stringify → Markdown string
// Output: Markdown string (round-trip safe)
//
// Key insight: the source of truth is always Markdown,
// but the editing experience is rich text.Markdown
remark-parse
MDAST
transform
ProseMirror Doc
serialize
MDAST
remark-stringify
Markdown
Setup
typescript
import { Editor, rootCtx, defaultValueCtx } from '@milkdown/core';
import { commonmark } from '@milkdown/preset-commonmark';
import { gfm } from '@milkdown/preset-gfm';
import { listener, listenerCtx } from '@milkdown/plugin-listener';
import { nord } from '@milkdown/theme-nord';
const editor = await Editor.make()
.config((ctx) => {
ctx.set(rootCtx, document.getElementById('editor'));
ctx.set(defaultValueCtx, '# Hello Milkdown');
// Listen for markdown changes
ctx.get(listenerCtx).markdownUpdated((ctx, md) => {
console.log('Markdown:', md);
});
})
.use(nord) // Theme
.use(commonmark) // CommonMark support
.use(gfm) // GFM: tables, task lists, strikethrough
.use(listener) // Change listener plugin
.create();Plugin System
Everything in Milkdown is a plugin:
@milkdown/preset-commonmark
Paragraphs, headings, lists, blockquotes, code blocks, images, links
@milkdown/preset-gfm
Tables, task lists, strikethrough, autolinks
@milkdown/plugin-slash
Slash commands for block insertion
@milkdown/plugin-tooltip
Selection tooltips and formatting menus
@milkdown/plugin-block
Block-level drag handles and controls
@milkdown/plugin-listener
Document change events for integration
Keyboard Shortcuts
| Action | Shortcut |
|---|---|
| Bold | Ctrl+B |
| Italic | Ctrl+I |
| Code | Ctrl+E |
| Heading 1-6 | Type # at line start |
| Bullet list | Type - at line start |
| Task list | Type - [ ] at line start |
| Blockquote | Type > at line start |
| Code block | Type ``` + Enter |
Strengths
- Truly markdown-native — clean round-tripping
- Clean architecture (ProseMirror + remark)
- Headless — fully customizable UI
- Plugin system for everything
- Uses familiar tools under the hood
Weaknesses
- Smaller community than Tiptap
- Less mature ecosystem
- Documentation has gaps
- Version compatibility can be tricky
- Fewer ready-made examples