docmd: Markdown In, Production Docs Out, Zero Config In Between
If you have ever wanted to ship a documentation site and found yourself two hours deep in a build config, fighting a framework you did not ask for, docmd will feel like a glass of water in the desert. It is a minimalist, zero-config static documentation generator: you write standard Markdown in a docs/ folder, run one command, and out comes a complete static website with navigation, full-text search, dark mode, SEO, a sitemap, and optional PWA support. No React, no Vue, no MDX, no client-side framework runtime — just plain HTML with a tiny sliver of JavaScript.
Conceptually it lives in the same neighborhood as MkDocs: Markdown in, fast HTML out, configuration only when you want it. The difference is that docmd is built for the Node and npm ecosystem and comes with modern niceties baked in. It is published on npm as @docmd/core, and it is aimed squarely at developers who look at Docusaurus, Nextra, or Starlight and think, "I just want to publish some docs, not adopt a meta-framework."
Why It Earns a Spot in Your Toolbox
Most popular documentation tooling in the JavaScript world is built on top of a full framework. Docusaurus is React plus MDX plus a bundler. Nextra wants a Next.js project. Starlight wants Astro. VitePress is lighter but still ships a Vue runtime and a hydration model. Each is excellent at what it does, but all of them ask you to bring along a framework and its client bundle just to render some prose.
docmd takes the opposite bet. Its thesis is that for a documentation site you mostly want Markdown turned into fast static HTML, with the expected conveniences, and nothing else. Here is what that buys you:
- Truly zero-config startup. A
docs/folder and a single command is the entire ceremony. - Automatic navigation derived from your file and directory structure, which you only override when you want a custom order.
- A tiny client payload of plain static HTML deployable to any static host on earth.
- Offline full-text search powered by MiniSearch, so there is no Algolia account to wire up.
- Dark mode and theming with system-preference detection and an official theme pack.
- Standard Markdown plus YAML frontmatter, which means no proprietary
.mdxlock-in.
A quick note on naming, because it trips people up. The brand is "docmd," but the npm package is scoped: you install @docmd/core. An older package, @mgks/docmd, still exists as a deprecated wrapper that simply delegates to the new core so existing CI pipelines do not break. If you find a tutorial referencing @mgks/docmd, it is the same project under its previous name.
Getting It Onto Your Machine
You do not strictly need to install anything to try docmd — npx will fetch and run it against a docs/ folder on the spot:
npx @docmd/core dev
For a real project you will usually want it installed. Both npm and yarn work:
# npm, global install
npm install -g @docmd/core
# yarn, global install
yarn global add @docmd/core
Once it is available, the CLI gives you a small, memorable set of commands:
docmd dev # dev server with live reload on http://localhost:3000
docmd build # produce the static site (default output: site/)
docmd migrate # import from Docusaurus, VitePress, or MkDocs
docmd deploy # scaffold Docker / nginx / Caddy deploy configs
The only runtime dependencies outside docmd's own scoped packages are esbuild for bundling and ws for the dev server's live reload websocket. That lean footprint is the whole point.
Your First Documentation Site
The fastest path to a working site is a directory that looks like this:
my-docs/
├── docs/ # your Markdown content drives auto-navigation
├── assets/ # images, logo, favicon
├── docmd.config.json # optional config, .js form also supported
└── package.json
Drop a couple of Markdown files into docs/ and you are already done. Each page is plain Markdown with optional YAML frontmatter at the top:
---
title: Getting Started
description: How to install and run the project in under a minute.
---
# Getting Started
Welcome! This page is just Markdown. No JSX, no imports, no build
incantations. Write content, save the file, and the dev server reloads.
Now start the dev server:
docmd dev
docmd parses the Markdown with its own pure-Markdown engine, renders each page, and automatically builds the sidebar navigation from your directory tree. Open http://localhost:3000 and you have a live, searchable, dark-mode-capable docs site — without having written a line of configuration. When you are happy, docmd build emits the finished static site into site/, ready to drop onto Netlify, Vercel, GitHub Pages, S3, or an nginx box.
Bending the Site to Your Will
Zero-config is a great start, but real projects need a little steering. That is what docmd.config.json is for. Every key is optional, and the file only describes the things you want to change:
{
"title": "My Project",
"url": "https://docs.myproject.com",
"src": "docs",
"out": "site",
"base": "/",
"logo": {
"light": "assets/images/logo-dark.png",
"dark": "assets/images/logo-light.png",
"href": "/",
"alt": "Company Logo",
"height": "32px"
},
"favicon": "assets/favicon.ico",
"layout": {
"spa": true,
"header": { "enabled": true },
"sidebar": { "collapsible": true }
},
"plugins": {
"search": {},
"seo": {},
"sitemap": {},
"pwa": {}
}
}
The plugins block is worth dwelling on because it is delightfully simple: it is a key-value map where each key is a plugin name and the value is its options object. Enabling a plugin is as easy as adding its key. The available plugins cover the documentation essentials — search, seo, sitemap, pwa, analytics, llms, mermaid, and openapi — and you opt in only to the ones you need.
If you would rather configure in JavaScript (handy for comments, conditionals, or pulling values from the environment), there is a defineConfig helper that gives you type hints along the way:
const { defineConfig } = require("@docmd/core");
module.exports = defineConfig({
title: "My Project",
url: "https://docs.myproject.com",
versions: {
// multiple documentation versions live here
},
i18n: {
// locale configuration, e.g. en, zh, de
},
});
Taking Control of Navigation
Auto-generated navigation is great until you want a specific order, grouped sections, or icons. docmd lets you hand-author the sidebar with a navigation array, and it is expressive enough to cover most documentation layouts:
{
"navigation": [
{ "title": "Overview", "path": "/", "icon": "home" },
{ "title": "Quick Start", "path": "/getting-started/quick-start", "icon": "rocket" },
{
"title": "Cloud Services",
"path": "/cloud/overview",
"children": [
{ "title": "AWS Setup", "path": "/cloud/aws" },
{ "title": "GCP Setup", "path": "/cloud/gcp" }
]
},
{
"title": "Formatting & Elements",
"icon": "layout-grid",
"children": [
{ "title": "Syntax Guide", "path": "/content/syntax" },
{ "title": "Rich Containers", "path": "/content/containers" }
]
}
]
}
A few details make this more powerful than it first looks. Every item needs a title. Including a path makes the item a clickable link, while omitting it turns the item into a non-clickable category label — notice how "Cloud Services" is a clickable group header (it has a path) but "Formatting & Elements" is just a label that expands to reveal its children. The icon field accepts any Lucide icon by its kebab-case name, children nests groups to any depth, collapsible controls whether a group folds, and external: true opens a link in a new tab. That single array gives you the whole sidebar, top to bottom.
Search, Diagrams, and AI-Readable Docs
The built-in search deserves a callout because it is one of docmd's quiet superpowers. Enabling it is the empty "search": {} entry you saw above. Under the hood it builds a client-side full-text and fuzzy index with MiniSearch, which means search works entirely offline, across versions and locales, with no external service to provision or pay for. For most teams that is the difference between "docs have search" and "docs were supposed to have search someday."
Diagrams and API references come from plugins too. Turn on mermaid and you can drop Mermaid code fences straight into Markdown to render flowcharts and sequence diagrams. Turn on openapi and docmd can render API reference pages from an OpenAPI spec. Math via KaTeX is available for the LaTeX-inclined.
There is also a thoroughly modern touch: the llms plugin emits an llms.txt file describing your documentation in a form that large language models can ingest cleanly. As more developers point AI assistants at project docs, generating that file automatically is a genuinely forward-looking default.
{
"plugins": {
"search": {},
"mermaid": {},
"openapi": { "spec": "assets/openapi.yaml" },
"llms": {}
}
}
Migrating In, and a Note on Maturity
If you already have a documentation site, you do not have to start from a blank folder. The docmd migrate command imports content from Docusaurus, VitePress, and MkDocs, which lowers the cost of kicking the tires considerably. Pair that with docmd deploy, which can scaffold Docker, nginx, or Caddy configurations, and you have a fairly complete path from "existing docs elsewhere" to "deployed static site."
A bit of honesty is fair here, because it affects how you should adopt the tool. docmd is young and pre-1.0, currently at 0.8.4, with a single primary maintainer and a roughly monthly release cadence. In 0.x land, minor versions can carry breaking changes, the plugin set is first-party only for now, and the ecosystem of community themes and third-party answers is far smaller than what surrounds Docusaurus or MkDocs. The performance numbers the project cites — a roughly 18 to 20 kilobyte client payload and a Lighthouse 100 — come from its own materials, so treat them as the project's claims rather than independently audited facts. And by design, there is no MDX, so if your docs need embedded interactive React components, docmd is intentionally the wrong tool.
The Bottom Line
docmd is, in spirit, "MkDocs for the JavaScript ecosystem": Markdown-first, configuration-light, and free of any client framework, but with the modern conveniences — offline search, dark mode, SEO, sitemaps, PWA, i18n, versioning, Mermaid, OpenAPI, and llms.txt — included rather than bolted on. It trades the deep ecosystems and React interactivity of the framework-based generators for speed, simplicity, and a refreshingly small output.
Reach for it when you want a documentation site today, with npx @docmd/core dev and a folder of Markdown, and you care more about a fast, tiny, framework-free result than about embedding interactive components. For a side project, an internal tool, a CLI's docs, or any library that deserves clean documentation without a build-tooling tax, docmd hits a sweet spot that is genuinely hard to find elsewhere. Just go in with eyes open about its pre-1.0 youth, and let the simplicity do the rest.