Skip to content
On this page

Development recommendations

Before continuing, make sure you've read:

  2. API documentation
  3. Architecture description

General considerations for plugins.

  1. Try to find the right place for your plugin rule:
  • Will it conflict with existing markup (by priority)?
    • If yes - you need to write an inline or block rule.
    • If no - you can morph tokens within core chains.
  • Remember that token morphing in core chains is always more simple than writing block or inline rules, if you don't copy existing ones. However, block and inline rules are usually faster.
  • Sometimes, it's enough to only modify the renderer, for example, to add header IDs or target="_blank" for the links.
  • Plugins should not require the markdown-it package as dependency in package.json. If you need access to internals, those are available via a parser instance, passed on plugin load. See properties of main class and nested objects.
  1. Search existing plugins or rules, doing something similar. It can be more simple to modify existing code, instead of writing all from scratch.
  2. If you did all steps above, but still has questions - ask in tracker. But, please:
    • Be specific. Generic questions like "how to do plugins" and "how to learn programming" are not accepted.
    • Don't ask us to break CommonMark specification. Such things should be discussed first on CommonMark forum.

Notes for NPM packages

To simplify search:

  • add to package.json keywords markdown-it and markdown-it-plugin for plugins.
  • add keyword markdown-it for any other related packages.


I need async rule, how to do it?

Sorry. You can't do it directly. All complex parsers are sync by nature. But you can use workarounds:

  1. On parse phase, replace content by random number and store it in env.
  2. Do async processing over collected data.
  3. Render content and replace those random numbers with text; or replace first, then render.

Alternatively, you can render HTML, then parse it to DOM, or cheerio AST, and apply transformations in a more convenient way.

The right sequence is to split text to several tokens and add link tokens in between. The result will be: text + link_open + text + link_close + text.

See implementations of linkify and emoji - those do text token splits.

Note. Don't try to replace text with HTML markup! That's not secure.

Why my inline rule is not executed?

The inline parser skips pieces of texts to optimize speed. It stops only on a small set of chars, which can be tokens. We did not made this list extensible for performance reasons too.

If you are absolutely sure that something important is missing there - create a ticket and we will consider adding it as a new charcode.

Why do you reject some useful things?

We do a markdown parser. It should keep the "markdown spirit". Other things should be kept separate, in plugins, for example. We have no clear criteria, sorry. Probably, you will find CommonMark forum a useful read to understand us better.

Of course, if you find the architecture of this parser interesting for another type of markup, you are welcome to reuse it in another project.