embedmd: keeping code samples in Markdown in sync with the source
embedmd: embed code into markdown and keep everything in sync
At a glance
- What is it?
- embedmd is a small Go command that embeds files, or fragments of files, into Markdown documents, driven by comments in the Markdown that stay invisible when it is rendered. It exists so that the code in a README is the code that compiles, and it can rewrite the document in place or show you the difference.
- Who is it for?
- embedmd suits a documentation writer who keeps examples in a README and keeps forgetting to update them, because a single command regenerates every embedded snippet from the source and the pointers stay in the document as invisible comments, so the file remains readable without the tool.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Activity is slowing. The repository last received commits 6 months ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem it solves in one sentence
The README opens with the complaint directly, and it is worth repeating because it is the entire use case.
It asks whether you are tired of copying code into your README file, only to forget about it later and end up with unsynced copies, or worse, with code that does not even compile.
That is a real and very common failure in Go projects in particular, where the README example is often a small program that a reader will copy. When the example drifts, it stops being documentation and becomes a liability, and nobody notices until a reader tries it.
embedmd answers it by inverting the direction of the copy. Instead of copying code into Markdown and maintaining the copy, you leave a pointer in the Markdown and the tool fills it in from the source every time you run it.
The tool is written in Go, is published as github.com/campoy/embedmd, and is Apache 2.0 licensed. The README also carries a disclaimer that is unusually explicit for a small utility: it is not an official Google product, experimental or otherwise, it is just code that happens to be owned by Google.
The directive syntax
The mechanism is a comment that is a subset of Markdown comment syntax, which means the pointer is invisible when the document is rendered. The README gives the general form.
[embedmd]:# (pathOrURL language /start regexp/ /end regexp/)The path or URL is either a relative path in the local file system, always with forward slashes as the directory separator, or a URL starting with http or https, in which case the tool fetches the content.
The embedded content starts at the first line matching the start expression and finishes at the first line matching the end one. Several variations exist for the cases you actually need.
Omitting the second expression embeds only the piece of text that matches the first one.
[embedmd]:# (pathOrURL language /regexp/)To embed the whole line that matches, wrap the expression so it matches the entire line.
[embedmd]:# (pathOrURL language /.*regexp.*/)To embed from a point to the end of the file, use the dollar sign as the end expression.
[embedmd]:# (pathOrURL language /start regexp/ $)And to embed a whole file, omit both expressions.
[embedmd]:# (pathOrURL language)The language can be omitted in every case, in which case the file extension is used for syntax highlighting. The README is careful about the limitation of that shortcut: it works when the extension matches the language name, as with Go files, but it fails for files such as Markdown files, whose language name is markdown rather than md. In that case you pass the language explicitly.
Running it, and the two flags that matter
The command takes a list of Markdown files, and if no list is given it reads from standard input.
Two flags do the real work.
The write flag modifies the file in place. Running embedmd with the write flag on a document will modify it and add the corresponding code snippets, and the README points at the sample result file to show the output.
The diff flag is the safer one and should be your default while you are learning the tool. It displays the difference between the contents of the document and the output the tool would produce, without touching anything.
That pairing is the design: generate a diff, review it, then write it. A tool that rewrites documentation files without showing you what it did would be a bad neighbour in a repository, and the author made the read only mode the obvious first step.
The standard input mode is what makes the tool composable. You can pipe a document in and get the result back, which means you can use it inside a larger pipeline or a build script without staging files on disk.
Installing and the shape of the repository
Installation is one Go command, and the README explains what it does.
go install github.com/campoy/embedmd@latestThat downloads the code, compiles it, and leaves an embedmd binary in the GOPATH bin directory. The README notes that binaries for every operating system and architecture may come later, with the word eventually carrying some emphasis.
The repository layout is small, which suits the size of the tool. There is a main.go at the root, a directory named embedmd holding the implementation, an internal directory for the parts that are not part of the public surface, and the sample directory with the example files the README walks through, including a hello.go program, a docs.md that embeds it in several different ways, a result.md showing the generated output, and a test subdirectory used by one of the embedding examples.
There is also an integration_test.go at the root, a main_test.go beside it, a releases directory, and a .github directory for the continuous integration configuration.
The module file is minimal. It declares a Go 1.11 version, which is a deliberate choice for a tool that should build on old machines, and it has one dependency, a diff library used to produce the difference output the diff flag prints.
Where it sits against the alternatives
The alternatives to embedmd are all reasonable, and the difference is where the truth lives.
The first alternative is manual copying, which is what everybody does, and its failure mode is the one the README names: the copy drifts, and eventually it no longer compiles.
The second is a continuous integration check that fails when the embedded code differs from the source. That gives you the guarantee without the automation, and it works. The difference in approach is that embedmd does the copying for you, so the fix is a command rather than a commit, and the document is never out of date in the first place.
The third is a general Markdown include mechanism, where a preprocessor resolves includes at render time. That is the opposite design, and it has a real cost: the document on disk is incomplete, so anything that reads the file without running the preprocessor, a code search tool, a reviewer on the web interface, or a language server, sees a document with holes in it.
embedmd keeps the pointers in the file and the code alongside them, so the file is complete and readable as plain text. That is the trade it makes, and it is why the tool is called embedmd rather than a preprocessor.
The example in the README shows this nicely, with a document that embeds a whole file, a range from a function to the end of the file, a single package statement, an import block, and one line matching a time expression, all in the same page.
Maintenance, licensing and what to check
The licence is Apache 2.0, with the LICENSE file at the root of the repository, and the disclaimer makes the provenance clear without pretending to more.
On maintenance, the last push was on 2026-04-11 and the repository has no GitHub releases, which for a tool installed with go install at the latest tag is a mild risk rather than a problem. The continuous integration badge points at Travis CI and there is a Go Report Card badge, both of which are the older generation of CI signals.
The module requiring Go 1.11 tells you something about the compatibility target, and it also means the tool builds on much older toolchains than a current Go project would expect, which is useful on a machine where you do not want to upgrade Go.
Three things to check when you adopt it.
Whether the language names you need for highlighting can be inferred from the file extensions, since the README warns that the mapping only works when the extension matches the language name and that Markdown files are a case where it does not.
Whether your documentation needs the source and the document to live in the same repository, because the paths are relative to the document and a URL is the only way to reach content elsewhere.
And whether your workflow can accommodate the write step. If your documentation is generated as part of a build, embedmd fits as a step in that build. If the Markdown is edited by hand in a browser interface, running the tool locally is friction, and you will want the diff flag to review the changes before they are pushed.
Editorial conclusion
embedmd suits a documentation writer who keeps examples in a README and keeps forgetting to update them, because a single command regenerates every embedded snippet from the source and the pointers stay in the document as invisible comments, so the file remains readable without the tool. It is the wrong choice when the code in the documentation is deliberately different from the code in the repository, since the tool can only copy what is there, and the wrong choice if you need a general include mechanism such as a preprocessing step for every Markdown file in a site. Verify first that the language you want for syntax highlighting can be inferred from the file extension, since the README notes that a file such as a Markdown file does not match its language name, and run the diff flag before the write flag until you trust the transformation.
Frequently asked questions
What does embedmd do?
It embeds files or fragments of files into Markdown documents, replacing embedmd commands that are a subset of Markdown comment syntax, so the pointers stay in the document but are invisible when it is rendered.
How do I install embedmd?
With go install github.com/campoy/embedmd@latest, which downloads the code, compiles it and leaves an embedmd binary in the GOPATH bin directory.
How do I embed only part of a file?
Give a start expression and an end expression in the directive, and the embedded content runs from the first matching line to the first matching end line. A single expression embeds only the matching piece, a dollar sign as the end expression embeds to the end of the file, and omitting both embeds the whole file.
What do the write and diff flags do?
The write flag modifies the Markdown file in place, adding the embedded snippets, while the diff flag shows the difference between the current file and the output the tool would produce without changing anything.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/campoy-embedmd)Was this useful?