CLI tool
jupyter-book/mystmd avatar
jupyter-book/mystmd

mystmd: a command line toolchain for MyST Markdown

Command line tools for working with MyST Markdown.

526 stars183 forksTypeScriptMIT

At a glance

What is it?
mystmd is the command line side of the MyST Markdown ecosystem, a set of community-driven tools for scientific communication that parses MyST into a standardised AST and renders it to HTML, React, PDF, LaTeX and Word. It ships through npm, PyPI and Conda, and since v1.0.0 the package is ESM only.
Who is it for?
Adopt mystmd if you are writing scientific documentation in MyST Markdown and want one command that builds it to a website, a journal template or a Word file, without maintaining a publishing stack yourself. Do not adopt it for ordinary Markdown that needs no cross-referencing, citations or journal templates, and do not stay on a pre-1.0 version expecting CommonJS to keep working, since the package has been ESM only since v1.0.0.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 8 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One CLI for a whole publishing stack

mystmd is a set of open-source, community-driven tools designed for scientific communication, including an authoring framework that supports blogs, online books, scientific papers, reports and journals articles. The project provides a command line tool, also called mystmd, for working with MyST Markdown projects.

The point of the tool is that the output formats a technical author needs are scattered across several ecosystems, and this one command covers them. The project translates and renders MyST Markdown into HTML for static websites and into modern React for interactive websites, into PDFs and LaTeX documents with specific templates for over 400 journals, and into Microsoft Word export.

The authoring features sit on top of that: cross-referencing, external structured links and scientific citations. Those are the features that make MyST different from plain Markdown, and they are also the reason you would need a dedicated tool rather than a static site generator with a Markdown plugin.

Underneath is a parser that produces a standardised AST following the MyST Markdown Spec. That intermediate representation is the architectural decision worth noticing, because it is what lets one input format feed a static site, a journal PDF and a Word document without three separate source trees.

The audience is a scientific author, a research group or a journal editor who writes in MyST and wants the outputs without assembling the pipeline. The repository topics say the same thing in technical terms: javascript-parser, markdown-it, myst, myst-markdown, myst-parser and unifiedjs.

The project is MIT licensed, the homepage is mystmd.org/guide, and the last push was on 2026-10-15 with release [email protected] on 2026-09-21.

Installing from npm, PyPI or Conda

The first requirement is Node, and the README tells you to ensure you have an updated version installed and shows the check:

bash
node -v
>> v20.4.0

The package manifest pins the requirement more precisely, with the engines field requiring Node >=20.0.0, and the package manager field set to [email protected] for the repository's own workflow.

The CLI itself is available through three different registries, which is unusual and deliberate. It ships on NPM, on PyPI and on Conda:

bash
# Using npm, yarn, or pnpm
npm install -g mystmd
# Or using PyPI
pip install mystmd
# Or using Conda / Mamba
conda install mystmd -c conda-forge

The reason to publish the same tool to PyPI and Conda is worth understanding, because it drives a design choice. If the entire toolchain were Node-only, a Python data science environment would need a Node installation and a global npm package before anything worked. Shipping the CLI to PyPI means pip can install it into an environment that already has Python, with no separate Node toolchain for the user to manage. The same argument applies to Conda, which is how a lot of scientific computing is installed.

The three commands are the same tool. The first use is to create a project and then start it:

bash
myst init
myst start
myst build my-doc.md --tex

Those three cover the whole lifecycle. myst init scaffolds a project, myst start runs the development server with live reloading, and myst build renders a document, here with the --tex flag to produce LaTeX rather than HTML.

A monorepo built on turbo, changesets and bun

The repository layout shows how the project is actually built, and it is a modern JavaScript monorepo.

The root package is marked private and declares its workspaces as packages/* and docs, with turbo as the task runner. The scripts are all turbo passthroughs: build runs turbo run build, test runs turbo run test, and lint has both a general variant and a format variant. There is a separate lint:circular script that runs madge over packages/*/src/*, which is a dependency-cycle check across the workspace, and that is a reasonable thing to have in a project with this many packages.

The package manager is bun, and the lockfile is bun.lock with a bunfig.toml beside it. The build of the site itself uses esbuild, the tests use vitest, and linting is eslint with a set of shared configs including eslint-config-curvenote and eslint-config-next.

Releases go through changesets, with a .changeset/ directory and a changeset script. The version script runs changeset version and then bun install, so the lockfile is refreshed as part of versioning, and the publish script cleans, builds with the force flag, publishes through changeset publish and pushes the tags.

There is also a pre-commit hook installed by husky, with lint-staged configured in the package manifest and a .husky/ directory at the root. A flake.lock and flake.nix sit alongside, so there is a Nix path as well as the npm path, and netlify.toml covers the hosted documentation site.

The end result is a project with about a dozen packages in packages/, each built and tested independently by turbo, with a release process that can publish a subset when only some packages changed.

Journal templates, Word export and what the output is for

The output formats deserve a closer look, because they are the reason to use this rather than a general Markdown pipeline.

The PDF and LaTeX path comes with specific templates for over 400 journals. That number is the headline feature for anyone submitting to a venue, because a journal template is not just a class file, it is a set of required front matter fields, bibliography style, figure handling and reference formatting, and reproducing one by hand for each submission is a known chore. Having them already wired means the document you author once renders in the format the venue expects.

The Word export serves a different purpose. A journal may ask for a .docx, and a document that has been through LaTeX and then converted to Word is not the same as one authored in Word. Producing the Word file directly from the MyST source avoids a conversion step that usually shows up in the output.

The React output is the modern React for interactive websites, and the README uses its own site as the example. The HTML output is the conventional static site path.

What is not stated anywhere in the README is the quality of any of these renderings for a specific journal, or how a particular template handles edge cases. The count of over 400 templates is the project's own claim, and the documentation at mystmd.org/guide is where the per-template detail lives. For an evaluation, the useful step is to build one document with the template your target venue uses and look at the output, rather than to assume the coverage is uniform.

The ESM only boundary at v1.0.0

There is one migration note in the README that deserves its own attention, because it is the kind of change that breaks builds rather than warnings.

As of v1.0.0 this package is ESM only. The README links to a well known write-up on the subject. In practice this means a CommonJS project, one that uses require rather than import, cannot simply require the package any more, and the older pre-1.0 releases are the ones to reach for if you cannot move to ESM.

This is a common direction of travel for JavaScript tooling, and it is not a criticism of the project. But it does mean the choice of which version to install is a real decision rather than a detail, particularly for a tool that is published to three registries and might otherwise be installed with whatever version a package manager resolves.

The release history shows the project settling into that regime. The listed versions are [email protected] from 2026-09-21, [email protected] from 2026-06-05 and [email protected] from 2026-06-04, with the 1.10.0 and 1.10.1 releases a day apart.

For a documentation pipeline, the risk is contained. Documentation builds are usually run in a controlled environment with its own package file, and the Node version is already pinned because the engines field demands it. The migration cost lands on anyone embedding the CLI in an existing CommonJS application, and the README's ESM only note is the flag to watch for them.

Where mystmd is the wrong tool

Three cases where a lighter option wins.

The first is ordinary documentation. If your Markdown has no cross-references, no citations and no journal formatting to satisfy, a static site generator with a Markdown plugin does the same job with fewer moving parts, and there is no MyST-specific feature you would be giving up. The AST layer, the journal templates and the Word export are all effort spent on problems you do not have.

The second is a submission pipeline you already own. If your venue requires a specific LaTeX template, and you have a working setup for it, then the argument for mystmd is the other 399 templates rather than the one you need, plus the risk of a new tool in the final mile before a deadline.

The third is team familiarity. MyST Markdown is not plain CommonMark. The directive syntax, the roles, the cross-reference identifiers and the front matter are all MyST specific, and the authoring framework described in the README covers blogs, books, papers, reports and journal articles, which is a lot of surface area. A team that will be writing in it daily needs to learn it, and that cost is real even though the syntax is pleasant.

One more practical note for evaluators. The documentation for this tool lives at mystmd.org/guide, and the repository's own README is a summary with pointers. Reading the guide is not optional background here; it is where the template list, the configuration and the command reference live.

Editorial conclusion

Adopt mystmd if you are writing scientific documentation in MyST Markdown and want one command that builds it to a website, a journal template or a Word file, without maintaining a publishing stack yourself. Do not adopt it for ordinary Markdown that needs no cross-referencing, citations or journal templates, and do not stay on a pre-1.0 version expecting CommonJS to keep working, since the package has been ESM only since v1.0.0. Verify first that the Node version on your machine satisfies the >=20.0.0 requirement, that the myst init and myst build commands produce the output format you actually need, and that the journal template you want is one of the supported ones before you wire it into a submission pipeline.

Frequently asked questions

What is mystmd and what does it do?

mystmd is a set of open-source, community-driven tools for scientific communication, providing a command line tool for working with MyST Markdown projects. It parses MyST into a standardised AST following the MyST Markdown Spec and renders it to HTML, modern React, PDFs and LaTeX with templates for over 400 journals, and to Microsoft Word.

How do I install the mystmd command line tool?

You need an updated Node installation, with the package requiring Node 20.0.0 or newer. The CLI is published to three registries, so you can run npm install -g mystmd, pip install mystmd, or conda install mystmd -c conda-forge.

Which commands does mystmd provide?

The quick start uses myst init to create a project, myst start to run the development server, and myst build to render a document, with the --tex flag producing LaTeX output as in myst build my-doc.md --tex.

Is mystmd still compatible with CommonJS?

No. The README states that as of v1.0.0 this package is ESM only, with a link to an explanation of the change. Recent releases include [email protected] from 2026-09-21, [email protected] from 2026-06-05 and [email protected] from 2026-06-04.

What licence is mystmd released under?

MIT, with the licence file in the repository. The project is MIT licensed, its homepage is mystmd.org/guide, and the last push to the repository was on 2026-10-15.

Official sources

  1. jupyter-book/mystmd on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/jupyter-book-mystmd.svg)](https://hysenlabs.com/projects/jupyter-book-mystmd)

Was this useful?