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

ActionShortcut
BoldCtrl+B
ItalicCtrl+I
CodeCtrl+E
Heading 1-6Type # at line start
Bullet listType - at line start
Task listType - [ ] at line start
BlockquoteType > at line start
Code blockType ``` + 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