Blocks to write in.
Markdown to keep.
The open-source editor inside Memos, packaged for any web app. Write with a slash menu, a toolbar, and the Markdown shortcuts you already know. What it saves is plain Markdown, and the parts you did not touch come back exactly as they went in.
npm install @usememos/editorWorks in React 18 and later, or without a framework. MIT licensed, with no runtime dependencies.
## Release notes #work/editor
This is **@usememos/editor**, the block editor inside Memos. It edits blocks and stores *Markdown*, nothing else. Type `/` for a block, `#` for a tag, `@` for a person, or select some text for the toolbar.
- [x] Watch the Markdown pane while you type
- [ ] Press Tab on a list item to nest it
- [ ] Type `> [!tip] ` at the start of a line
> [!TIP]
> A block you did not touch is saved exactly as it was loaded.
| Shortcut | Becomes |
| :-- | :-- |
| `# ` | Heading |
| `- [ ] ` | Task |
| `---` | Divider |
```ts
const editor = new Editor({ element, content, onChange });
```
Ask @ada to try the link card, then file it under #reading.
Nothing is lost on save.
A block editor whose storage format is Markdown. A block you did not edit is written exactly as it was loaded, down to the list marker and the heading style, so the file you opened is the file you get back.
- Markdown is the stored format
- Loading parses Markdown into blocks, and saving writes the blocks back. There is no second document format to store.
- Every block has a Markdown form
- No columns or colored text. Callouts are GitHub alerts, and collapsible sections are <details>, so anything that renders Markdown can show it.
- Nothing is lost on save
- Markdown the block model cannot hold stays as source. It is edited as text and saved verbatim, never flattened or dropped.
Weekly review============= * Ship the editor page* Reply to the issue Notes from Tuesday's call. 1) Draft the copy2) Check it on a phoneWeekly review============= * Ship the editor page* Reply to the issue Notes from Tuesday's call. Follow up with **Ada**. 1) Draft the copy2) Check it on a phoneOnly the edited paragraph was rewritten. The underlined heading, the asterisk bullets, and the parenthesis numbering are not the editor's own style, and it left them alone.
A block editor after parsing.
Whole blocks can be selected, moved, and changed together. A feature is added only when its result can be written as Markdown that GitHub would render the same way.
/tableSlash menu
Type / for headings, lists, to-dos, quotes, callouts, collapsible sections, code, tables, and dividers.
⌘B ⌘I ⌘KFormatting toolbar
Select text for bold, italic, strikethrough, code, links, quotes, code blocks, and lists. A link card opens, copies, edits, or removes a link.
> [!tip] Typing shortcuts
Markdown you already know turns into blocks and marks as you type. Backspace right after a shortcut puts the characters back.
Esc ⌘C ⌘VBlock selection
Escape selects whole blocks. Copy, cut, paste over, duplicate, delete, or change their type together. Tables, code blocks, and images get a handle with a block menu.
@ad|Autocomplete
One popup for #tags, @people, and :emoji, with async items, sections, and keyboard navigation. Your app decides the syntax and what a pick writes.
Blocks ⇄ SourceSource mode
Switch to the document as Markdown text and back. Nothing changes, undo history survives, and Enter still continues a list.
Shortcuts you already know.
Typed at the start of a line, or around a word. Undo restores the characters, and they are saved escaped so they stay text.
Read the syntax specification- #
- Heading, levels 1 to 6
- -
- Bullet list item
- 1.
- Numbered list item, starting at that number
- [ ]
- Task list item
- >
- Quote
- > [!tip]
- Callout: note, tip, important, warning or caution
- >>>
- Collapsible section with the rest of the line as its title
- ```ts
- Code block in that language
- ---
- Divider, on the third dash
- **bold**
- Bold, with the asterisks removed as you close them
One package. No dependencies.
The core is plain TypeScript with its own CommonMark parser, serializer, and icons inside, so it adds nothing else to your install. The React entry is a thin wrapper over the same editor.
Minified and gzipped, set up for Markdown with tables, task lists, and undo
Measured by the editor project on 2026-10-13 from the npm versions of that day, React not included. The React wrapper adds 1.3 KB, the stylesheet 3.5 KB, and the optional emoji list 18 KB the first time it opens.
import { MarkdownEditor } from "@usememos/editor/react";
import "@usememos/editor/style.css";
function CommentBox() {
const [markdown, setMarkdown] = useState("");
return (
<MarkdownEditor
value={markdown}
onChange={setMarkdown}
onSubmit={post}
placeholder="Leave a comment…"
/>
);
}import { Editor } from "@usememos/editor";
import "@usememos/editor/style.css";
const editor = new Editor({
element: document.querySelector("#editor"),
content: "# Hello",
onChange: (markdown) => save(markdown),
});Your theme, your syntax.
Every color, font, and size is a CSS custom property, set from JavaScript or in a stylesheet, with a light and a dark value. The editor has no border or background of its own, so it sits inside your card, comment box, or chat input. The playground above follows this site's variables the same way.
:root {
--mbe-accent-light: #0969da;
--mbe-accent-dark: #58a6ff;
--mbe-font: Inter, sans-serif;
}- Math
- $…$ and $$ blocks through math(), rendered by a renderer you pass in, such as KaTeX.
- Footnotes
- [^1] references and definitions, collected at the end when read-only, as on GitHub.
- Tags and mentions
- #tag and @name highlighting with your own classes, click handlers, and grammar.
- Files
- Pasted and dropped files reach your upload code, with a widget to show progress in place.
- Views
- Render a syntax or a code language your way, such as a mermaid block as a diagram, or a bare link as a preview card.
- Labels and icons
- Every UI string is overridable for localization, and every Lucide icon can be replaced.
Before you add it.
View the source on GitHub- Is this the editor Memos uses?
- Yes. Memos pins @usememos/editor as a dependency and uses it to write memos. The package is maintained in the usememos/editor repository and published to npm, so any web app can use the same editor.
- Does it need React?
- No. The core is plain TypeScript with zero runtime dependencies and works in any web app. @usememos/editor/react is a thin wrapper with a MarkdownEditor component and a useEditor hook for apps that use React 18 or later.
- Which Markdown does it read and write?
- CommonMark 0.31.2 plus the GFM extensions for tables, task lists, strikethrough, and autolink literals, GitHub alerts as callouts, and <details> as collapsible sections. All 652 CommonMark spec examples and the GFM spec examples produce the reference HTML. Math, footnotes, tags, and mentions are extensions.
- What happens to Markdown the editor cannot represent?
- It is kept as a raw block: shown and edited as source and saved verbatim. Every block you do not edit is saved byte for byte, and loading and saving without edits returns the input unchanged.
- How large is it?
- The project measured the core at about 56 KB minified and gzipped, with the React wrapper adding 1.3 KB and the stylesheet 3.5 KB, on 2026-10-13. The optional emoji list is 18 KB and loads the first time the popup opens.
- How is it versioned?
- Releases follow the Memos calendar versioning, such as 26.10.0 for the first release in October 2026. Versions do not signal breaking changes, so pin an exact version and read the commit log for changes marked as breaking.
- Is the editor open source?
- Yes. Like Memos itself, the editor is MIT-licensed. The code, the Markdown syntax specification, and the architecture notes are on GitHub.