mdcode keeps the code blocks in your Markdown docs in sync with real source files. You write and test examples as ordinary code, point a code block at the file (or a #region inside it), and mdcode update copies the current code into the document. Your README can't drift from code that compiles and passes its tests.
It also works the other way: mdcode extract writes code blocks out to files, and mdcode run runs a command against each block. It is a TypeScript port of szkiba/mdcode, compatible with its CLI, and adds transform functions, a library API and a versioned --json output.
npm install --save-dev mdcode-tsThis installs the mdcode command. Node.js 22 or later is required. To try it without installing, run npx mdcode-ts --help.
Put the example in a source file and mark the part you want to show with a region:
// src/greet.ts
// #region greet
export function greet(name: string): string {
return `Hello, ${name}!`;
}
// #endregion
console.log(greet("docs"));In your README, add an empty code block that names the file and region:
```ts file=src/greet.ts region=greet
```Preview the change, then apply it:
npx mdcode update README.md # list the blocks that would change
npx mdcode update --diff README.md # review them as a unified diff
npx mdcode update --apply README.md # write themmdcode fills the block with the region's code, leaving out the markers and the rest of the file:
```ts file=src/greet.ts region=greet
export function greet(name: string): string {
return `Hello, ${name}!`;
}
```When src/greet.ts changes, run mdcode update --apply README.md again. In CI, mdcode update --check README.md exits 1 when a block has drifted from its source, without writing anything.
| Command | What it does |
|---|---|
list |
List code blocks with their language, metadata and a preview |
update |
Refresh blocks from the files they reference, or rewrite them with a transform function. Plans by default; --apply writes, --diff and --check review |
extract |
Write blocks to files named by their file= metadata |
run |
Run a shell command on each block, such as a compiler or test runner |
dump |
Pack blocks into a tar archive |
Every command reads a Markdown file or stdin, filters blocks by language, file, name or other metadata, and supports --json. Running mdcode with no command lists the blocks in README.md.
- Package README: the full reference, also published on npm
- CLI usage and flags reference
- JSON contract for scripts and CI
- Library usage and API reference
- Code block metadata, regions and outlines
- CLI examples: worked examples for each command
- Comparison with the Go mdcode
This is a pnpm workspace. packages/mdcode is the published package and packages/usage holds end-to-end tests against the built CLI. See TESTING.md for the test layout.
pnpm install
pnpm build # build packages/mdcode with zshy
pnpm test # unit and E2E tests (E2E runs the built dist/main.js)
pnpm -r lint:ts # type checkRun the CLI from source with Node 22+:
node --experimental-strip-types packages/mdcode/src/main.ts list README.mdOriginal Go implementation by szkiba.