md-merge is a small cross-platform Go CLI that recursively finds Markdown files under a directory and merges them into one Markdown document.
Use it when you want a single Markdown file from a tree of docs, notes, or project files without adding third-party runtime dependencies.
md-merge ./docs -o merged.mdgo install github.com/shuuuumai96/md-merge@latest
md-merge ./docs -o merged.mdPreview the files that would be merged:
md-merge ./docs --dry-runWrite a merged file with a simple file list TOC:
md-merge ./docs --with-toc -o merged.mdSkip draft and archive paths:
md-merge ./docs -o merged.md --exclude "**/drafts/**" --exclude archive- Bulk documentation review
- Preparing Markdown for AI tools
- Combining project notes
- Preparing a single Markdown input for other tools
go test ./...
go build -o md-merge| Flag | Description |
|---|---|
-o, --output <file> |
Write merged Markdown to a file. If omitted, write to stdout. |
--dry-run |
Print matched files in merge order and do not write merged content. |
--with-toc |
Include a simple file list near the top of the merged Markdown. |
--exclude <pattern> |
Skip a path segment such as archive or a glob-like pattern such as **/drafts/**. Can be repeated. |
--extensions <list> |
Comma-separated extensions. Default: md,markdown. Matching is case-insensitive. |
--sort <mode> |
Sort by path, name, or modified. Default: path. |
--strict |
Stop on unreadable files, invalid UTF-8, or max-size skips. |
--max-size <bytes> |
Skip files larger than this value. 0 means unlimited. Default: 0. |
-h, --help |
Show help message. |
--version |
Show version information. |
Merged output uses this shape:
# Merged Markdown
Source directory: `/path/to/docs`
Generated by: `md-merge`
## Files
- `intro.md`
---
<!-- BEGIN FILE: intro.md -->
## File: `intro.md`
# Intro
<!-- END FILE: intro.md -->The ## Files section is included only when --with-toc is set. Source file contents are not wrapped in code fences, so existing Markdown remains Markdown.
The following path segments are skipped by default:
.git
node_modules
dist
build
coverage
vendor
.cache
Symlinked files and directories are skipped. No warning is printed for skipped symlinks.
| Code | Meaning |
|---|---|
0 |
Success |
1 |
General error |
2 |
Invalid input directory or invalid arguments |
3 |
No Markdown files found |
4 |
Partial read failure in non-strict mode |
5 |
Strict-mode read failure |
md-merge uses a data-oriented design: simple structs describe configuration, file records, scan results, and warnings, while functions transform those values explicitly. Filesystem and stdout/stderr side effects are kept at the edges.
The project uses only the Go standard library and intentionally keeps a small root-level layout. It does not use DDD-style folders such as domain/, usecase/, repository/, or service/.
Source files are treated as UTF-8, and invalid bytes are not silently replaced. Exclude patterns cover simple path segments and common glob-like patterns, not a full shell-specific glob language. Symlinks are not followed.