Content editor is a very important function for creative platform, powerful editor can let creators focus on the creation of “pen”. One of the best ways to please programmer writers is to support Markdown writing, since most programmers write in Markdown.

Markdown, a programmer’s writing favorite, has many advantages:

  • Typesetting through syntax, no need to click to manually set styles

  • Fast implementation of complex content, such as code blocks, hyperlinks, formulas, etc

  • Gives creators more time to focus on content

However, there are also some disadvantages:

  • There are certain barriers to learning and are not very friendly to non-programmers

  • Looking at the original document is like looking at “code”, and the preview effect requires tool or editor support

Is there a way to keep the convenience of Markdown while lowering the barrier to entry? Most veteran players will blurt out: Typora

Typora is perfectly fine to use directly, but since it is not open source. If you want to implement a similar Markdown editor in your own project, you need to look elsewhere.

If you’re looking for powerful, easy-to-access, WYSIWYG Markdown editors, components, plugins, take 5 minutes to read this article!

The next open source project HelloGitHub brings to the table meets the above requirements. Milkdown is a wySIWYG (what you see is what you get) Markdown editor, component, and plug-in.

Github.com/Saul-Mirone…

It has all the functions you want, and the functions you don’t want can be reduced by deleting plug-ins. Markdown is a Markdown editor that you can customize in minutes.

Follow the author of the project to experience the charm of Milkdown.

One, to fit

Here are two ways to experience it firsthand:

Dev /#/online-de…

VS Code plug-in: marketplace.visualstudio.com/items?itemN…

1.1 Function Display

Easy to write tables:

Paste and copy Markdown text directly:

Even co-editing:

Two-column Markdown editors are common. But there is only one bidirectional binding Markdown editor:

The function is introduced so much, below with Milkdown easy implementation of an editor.

1.2 The first editor

Milkdown’s core and various plug-ins are independent NPM packages that can be installed directly through NPM.

npm i @milkdown/core @milkdown/preset-commonmark @milkdown/theme-nord
Copy the code

Getting started is easy:

import { Editor } from '@milkdown/core';
import { nord } from '@milkdown/theme-nord';
import { commonmark } from '@milkdown/preset-commonmark';

Editor
  .make()
  .use(nord)
  .use(commonmark)
  .create();
Copy the code

We use make to initialize the editor, use to load the plug-in, and finally create the editor.

1.3 Rich plug-ins

Plug-in is the core of Milkdown, which is essentially a plug-in loader, and all functions are provided by plug-ins. A table is a plug-in, a theme is a plug-in, even a simple line of text is a plug-in.

Many plugins have been made available to ensure that they work out of the box. Here are just a few of them:

The name of the describe
plugin-clipboard Add markdown format copy and paste capability
plugin-cursor Add drop and gap cursors
plugin-listener Add listener support
plugin-collaborative Added collaborative editing support
plugin-table Added table syntax support (already included in GFM)
plugin-prism addprismUsed to support code block highlighting

You can also write your own plug-ins for more details

2. Technology stack

Milkdown is implemented based on the following tools:

  • Prosemirror: a toolkit for building rich text editors on the Web side
  • Remark: The correct Markdown parser
  • TypeScript: Write in TypeScript
  • Emotion: Powerful CSS in JS tool for building styles
  • Prism: Code block support
  • Katex: High-performance rendering mathematical formula

The rich text editor itself is a sinkhole. Although ContentEditable looks lovely, in practice it is full of problems. So we implement rich text editor based on Prosemirror. It’s mature, it’s industry hardened, and it has a good architecture and API design.

Three, architecture,

The core logic of Prosemirror is similar to React. It reflects the relationship between the UI and the internal state of the editor through a functional data mapping, as shown in the figure below:

The editor uses EditorState to save the current state, and EditorState generates EditorView, the UI view. User actions on the UI view eventually generate DOM events, such as input events and click events. DOM Events generate transactions and represent changes to State, similar to actions in Redux or Vuex. These transactions are evaluated against the original EditorState, producing a new EditorState, and so on.

In this way, Prosemirror stores each state in the editor as EditorState, which is a tree structure. Any programming language has an AST (Abstract syntax tree). So all we need is to establish a connection between EditorState in Prosemirror and Markdown’s abstract syntax tree. Remark fits our needs perfectly because it has a well-designed AST and is easy to extend its own syntax.

So Milkdown’s architecture became clear:

Markdown <-> Remark AST <-> Prosemirror State <-> UI

Four, conclusion

Before starting this project, I tried a variety of Markdown editors, but couldn’t find one that I was particularly happy with. Because they are closed source, and the features are provided by the developer, some features are too bloated, others are too simple. In this case, I decided to make a Markdown editor that can be easily customized and used by non-programmers, and you can see Milkdown.

It is hoped that the open source Milkdown will give users more freedom of choice and break the “monopoly” of Markdown editor. Open source is not easy if Milkdown is helpful to you, please also send a Star✨.

Github.com/Saul-Mirone…

Finally, thank you to HelloGithub for your support and help. Milkdown was lucky enough to be selected for issue 65 and then invited to collaborate on this article to spread the word about my open source project.


Follow the HelloGitHub official account to receive updates as soon as possible.

There are more open source projects and treasure projects waiting to be discovered.