Skip to content

Repository files navigation

markdown-code

CI Buildnpm versionLicense

Stop copy-pasting code into documentation. Keep your markdown examples automatically synchronized with real source files.

The Problem

Your documentation has code examples, but they get outdated:

  • You update your source code but forget to update the docs
  • Code examples in README/docs become stale and misleading
  • Copy-paste errors introduce bugs in documentation
  • Code examples can't be validated, linted, or tested like real source code
  • Maintaining multiple copies of the same code is painful

The Solution

markdown-code keeps your documentation in sync automatically:

  • Single source of truth: Code examples come from real files
  • Always accurate: Documentation updates when code changes
  • Validated code: Snippets can be linted, type-checked, and tested like any source file
  • Zero maintenance: Sync happens automatically in CI/CD
  • Extract existing: Migrate current docs with one command

Example

Before: Manual copy-paste (gets outdated)

```jsfunctiongreet(name) {
return'Hello '+ name; // Oops, code changed but docs didn't!
}
```

After: Automatic sync from real files

```js snippet=src/utils/greet.jsfunctiongreet(name) {
return`Hello, ${name}! Welcome to our app.`; // Always current!
}
```

Result: Your documentation stays accurate as your code evolves.

Agent Skill

Install the markdown-code skill to give your AI coding agent knowledge of this tool's workflows and commands:

npx skills add scalvert/markdown-code

Works with any agent that supports the skills ecosystem.

Installation

No installation required - use it directly:

npx markdown-code --help
npx markdown-code init --extract

Or install once, then use the shorter md-code command:

npm install -g markdown-code

Now you can use the convenient md-code binary:

md-code --help
md-code init --extract

Note: All examples in this README show both npx markdown-code and md-code variants.

How It Works

Snippet Syntax

Use the snippet= directive in your fenced code blocks:

```ts snippet=path/to/file.ts// This content will be replaced``````ts snippet=path/to/file.ts#L10-L20
// This will include lines 10-20 only``````ts snippet=path/to/file.ts#L5
// This will include only line 5``````ts snippet=path/to/file.ts#L5-
// This will include from line 5 to end of file```

Usage

markdown-code provides two powerful workflows for keeping your documentation in sync with your code:

  1. Extract from existing docs - Convert unmanaged code blocks into manageable snippets
  2. Reference source files - Keep documentation in sync with your actual codebase

Workflows

Workflow 1: Extract from Existing Documentation

Perfect for projects with existing markdown documentation that contains code blocks.

Use this when:

  • You have markdown files with unmanaged code blocks
  • You want to extract code examples into separate files
  • You need to start managing existing documentation

How it works:

  1. Run npx markdown-code check (or md-code check) to discover manageable code blocks
  2. Run npx markdown-code init --extract (or md-code init --extract) to extract them into snippet files
  3. Your markdown is updated to reference the new snippet files
  4. Future changes to snippets automatically sync to documentation

Workflow 2: Reference Existing Source Files

Perfect for keeping documentation in sync with your actual project source code.

Use this when:

  • You want documentation to reference your actual source files
  • You need line-range extraction from existing code
  • You want living documentation that stays current with code changes

How it works:

  1. Add snippet directives to reference source files with line ranges
  2. Run npx markdown-code sync (or md-code sync) to populate markdown with current source content
  3. When source files change, npx markdown-code check (or md-code check) detects drift
  4. Run npx markdown-code sync (or md-code sync) to update documentation with latest changes

MDX Support

.mdx files (Docusaurus, Nextra, etc.) are fully supported. Point the glob at them:

{
"markdownGlob": "docs/**/*.{md,mdx}"
}

MDX files are parsed with remark-mdx + remark-frontmatter, so fences nested inside JSX components are found, JSX indentation never produces phantom code blocks, and {...} inside YAML frontmatter parses cleanly. Snippet directives coexist with other fence meta (e.g. ```ts title="app.ts" snippet=app.ts).

Two guarantees worth knowing:

  • Non-destructive extraction: extract only inserts snippet=<ref> into opening fence lines (offset-addressed, never regex-matched) — stripping the annotations reproduces your original file byte-for-byte.
  • Fail-safe parsing: a file that isn't valid MDX (e.g. HTML <!-- --> comments, which MDX forbids) is reported and left untouched.

Note: framework-specific MDX extensions (like Docusaurus {#heading-id} anchors) are not part of the MDX grammar and will be reported as parse errors; those files are skipped safely.

Features

  • Automatic Sync: Replace fenced code blocks with contents from real files
  • MDX Support: Parse .mdx files, including fences nested in JSX
  • Extract Mode: Create snippet files from existing code blocks in markdown
  • Line Range Support: Extract specific line ranges using #Lx-Ly syntax
  • Check Mode: Verify documentation is in sync without making changes
  • Multi-language: Support for any programming language
  • Configurable: Flexible configuration via .markdown-coderc.json

Commands

CommandDescriptionExample
npx markdown-code / md-codeUpdate markdown with snippet content (default)npx markdown-code or md-code
npx markdown-code sync / md-code syncSame as above, explicitnpx markdown-code sync or md-code sync
npx markdown-code check / md-code checkVerify files are in sync (CI-friendly)npx markdown-code check or md-code check
npx markdown-code init / md-code initCreate config and snippets directorynpx markdown-code init or md-code init
npx markdown-code extract / md-code extractExtract code blocks to snippet filesnpx markdown-code extract or md-code extract
npx markdown-code init --extract / md-code init --extractSetup + extract in one stepnpx markdown-code init --extract or md-code init --extract

Global Options

OptionDescriptionExample
--configCustom configuration filenpx markdown-code --config custom.json or md-code --config custom.json
--snippet-rootOverride snippet directorynpx markdown-code --snippet-root ./src or md-code --snippet-root ./src
--markdown-globOverride markdown file patternnpx markdown-code --markdown-glob "docs/**/*.md" or md-code --markdown-glob "docs/**/*.md"
--exclude-globOverride exclusion patternsnpx markdown-code --exclude-glob "node_modules/**,dist/**" or md-code --exclude-glob "node_modules/**,dist/**"
--include-extensionsOverride file extensionsnpx markdown-code --include-extensions .ts,.js,.py or md-code --include-extensions .ts,.js,.py

Configuration

Create a .markdown-coderc.json file in your project root:

{
"snippetRoot": "./snippets",
"markdownGlob": "**/*.md",
"excludeGlob": [
"node_modules/**",
".git/**",
"dist/**",
"build/**",
"coverage/**",
".next/**",
".nuxt/**",
"out/**",
"target/**",
"vendor/**"
],
"includeExtensions": [
".ts",
".js",
".py",
".java",
".cpp",
".c",
".go",
".rs",
".php",
".rb",
".swift",
".kt"
]
}

Configuration Options

OptionDescriptionDefault
snippetRootBase directory for resolving snippet paths"."
markdownGlobGlob pattern to find Markdown files"**/*.md"
excludeGlobArray of glob patterns to exclude from processingCommon build/dependency directories
includeExtensionsFile extensions to consider for snippets and extraction[".ts", ".js", ".tsx", ".jsx", ".py", ".rb", ".go", ".rs", ".java", ".cpp", ".c", ".cs", ".php", ".sh", ".bash", ".zsh", ".fish", ".json", ".yaml", ".yml", ".toml", ".xml", ".html", ".css", ".scss", ".less", ".sql", ".md", ".txt"]

Contributing

See CONTRIBUTING.md for development setup and contribution guidelines.

License

MIT License - see the LICENSE file for details.

About

Keep code examples in Markdown synchronized with actual source files

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages