If one is good, two must be better [markdownlint-cli2 is a new kind of command-line interface for markdownlint]
About 5 years ago, Igor Shubovych and I discussed the idea of writing a CLI for
I wasn't ready at the time, so Igor created
markdownlint-cli and it has been a tremendous help for the popularity of the library.
I didn't do much with it at first, but for the past 3+ years I have been the primary contributor to the project.
This CLI is the primary way that many users interact with the
markdownlint library, so I think it is important to maintain it.
However, I've always felt a little bit like a guest in someone else's home and while I have added new features, there were always some things I wasn't comfortable changing.
A few months ago, I decided to address this by creating my own CLI - and approaching the problem from a slightly different/unusual perspective so as not to duplicate the fine work that had already been done.
My implementation is named
markdownlint-cli2 and you can find it here:
markdownlint-cli2 has a few principles that motivate its interface and behavior:
Faster is better. There are three phases of execution: globbing/configuration parsing, linting of each configuration set, and summarizing results. Each of these phases takes full advantage of asynchronous function calls to execute operations concurrently and make the best use of Node.js's single-threaded architecture. Because it's inefficient to enumerate files and directories that end up being ignored by a filter, all glob patterns for input (inclusive and exclusive) are expected to be passed on the command-line so they can be used by the glob library to optimize file system access.
How much faster does it run? Well, it depends. :) In many cases, probably only a little bit faster - all the same Markdown files need to be processed by the same library code. That said, linting is done concurrently, so slow disk scenarios offer one opportunity for speed-ups. In testing, an artificial 5 millisecond delay for every file access was completely overcome by this concurrency. In situations that play to the strengths of the new implementation - such as with many ignored files and few Markdown files (common for Node.js packages with deep
node_modules) - the difference can be significant. One early user reported times exceeding 100 seconds dropped to less than 1 second.
Configuration should be flexible. Command line arguments are never as expressive as data or code, so all configuration for
It's unconventional for a command-line tool not to allow configuration via command-line arguments, but this model keeps the input (glob patterns) separate from the configuration (files) and allows easier sharing of settings across tools (like the markdownlint extension for VS Code). It's also good for scenarios where the user may not have the ability to alter the command line (such as GitHub's Super-Linter action).
In addition to support for custom rules, it's possible to provide custom
markdown-itplugins - for each directory if desired. This can be necessary for scenarios that involve custom rendering and make use of non-standard CommonMark syntax. By using an appropriate plugin, the custom syntax gets parsed correctly and the linting rules can work with the intended structure of the document. A common scenario is when embedding TeX math equations with the
$ math $or
$$ math $$syntax and a plugin such as
Although the default output format to
stderris identical to that of
markdownlint-cli(making it easy to switch between CLI's), there are lots of ways to display results and so any number of output formatters can be configured to run after linting. I've provided stock implementations for default, JSON, JUnit, and summarized results, but anyone can provide their own formatter if they want something else.
Dependencies should be few. As with the
markdownlintlibrary itself, package dependencies are kept to a minimum. Fewer dependencies mean less code to install, parse, audit, and maintain - which makes everything easier.
So, which CLI should you use? Well, whichever you want!
If you're happy with
markdownlint-cli, there's no need to change.
If you're looking for a bit more flexibility or want to see if
markdownlint-cli2 is faster in your scenario, give it a try.
At this point,
markdownlint-cli2 supports pretty much everything
markdownlint-cli does, so you're free to experiment and shouldn't need to give up any features if you switch.
What does this mean for the future of the original
It's a great tool and it's used by many projects.
I will continue to update it as I release new versions of the
However, I expect that my own time working on new features will be focused on
markdownlint-cli2 for now.
Whether you use
markdownlint-cli, I hope you find it useful!