Your docs should quote code that actually runs.
sottovoce syncs real, tested code from source repos into your docs and keeps the two in sync — with the smallest possible footprint in both.
# one comment line marks the snippet; the fence below it is ordinary markdown <!-- sotto local:src/checkout.ts#purchase --> $ npx sottovoce sync ✓ docs/guide.md:12 ← src/checkout.ts#purchase # run it in CI and drift stops being a silent lie $ npx sottovoce check drift: docs/guide.md:12
code samples rot
Docs code samples rot
The example compiles the day you paste it, then the SDK moves and the docs don't. sottovoce makes your docs reference code that actually lives in a repo — ideally one your CI already builds and runs — and keeps the two in sync. Same job as marker-based snippet tools like snipsync, with one design goal added: stay quiet.
Source files need no markers
Reference a whole file, a line range, or a named region. Regions use the // #region / // #endregion markers editors already fold on — they read as ordinary code organization.
One comment line per snippet
Not a wrapper pair. The code fence below the directive is a normal fence — sottovoce rewrites its contents in place, idempotently. Run it twice and nothing changes.
Synced code is committed
Not fetched at build time. Docs builds stay network-free, snippet changes show up in reviewable diffs, and anything indexing your docs sees real code.
Drift is a failing build
sottovoce check exits non-zero if any fence is stale or any directive is broken. Wire it into CI and a stale snippet fails the build instead of shipping a lie.
git on PATH
Install
# add it to the docs repo
npm install --save-dev sottovoce
Requires Node 20+ and git on PATH.
Quickstart
Everything here runs locally — no GitHub org, no credentials. Add sottovoce.json to your docs repo, pointing a source at a directory of example code:
{
"docs": ["docs/**/*.{md,mdx}"],
"sources": {
"local": { "path": "../examples" }
}
}
Reference a snippet in any markdown or MDX file — a directive comment followed by a code fence — then run npx sottovoce sync. Every directive's fence now holds the current code from the source. Run it again and nothing changes — that's the point.
<!-- sotto local:src/checkout.ts#purchase -->
In MDX, use {/* sotto local:src/checkout.ts#purchase */} — an HTML-style comment in an .mdx file still syncs, but prints a warning, since MDX builds fail on HTML comments.
referencing code
Referencing code
The directive form is <source>:<path>[#region] [options].
A named region
uses editor-native fold markers in the source file. Any common comment leader works (//, #, --, ;, /* */, <!-- -->), plus bare #region for C#. Marker lines never appear in output.
// #region purchase const receipt = await checkout(cart); // #endregion
Multiple regions from one file compose with +, so a page can show imports and a function while skipping the code between them — each region is extracted and dedented on its own, joined with one blank line.
<!-- sotto local:src/checkout.ts#imports+purchase -->
A line range is the escape hatch for code you can't annotate — fragile by nature, so prefer regions in files you control. Options are lines=A-B and lang=x; snippets are dedented to their shallowest line, blank edges trimmed, and fences widen automatically around backtick runs.
repo or path
Sources
Each named source is either a GitHub repo pinned to a ref, or a local path:
{
"ts": { "repo": "your-org/examples-ts", "ref": "v1.4.0" },
"wip": { "path": "../examples" }
}
Pin ref to the release tag your docs describe — that's what keeps a docs version honest. Branches, tags, and full commit SHAs all work; if omitted, ref defaults to main. Repos are shallow-fetched into ~/.cache/sottovoce/; --offline reuses the cache without touching the network. Private repos work through your ambient git credentials.
sync, check, list
Commands
| Command | What it does |
|---|---|
sottovoce sync | Rewrites every directive's fence with the current source code, idempotently. Inserts a fence where none exists. Exits non-zero on a broken directive, even after writing every valid fence. |
sottovoce check | The drift alarm. Exits non-zero if any fence is stale or any directive is broken. --diff prints what changed under each drift: line. |
sottovoce list | Prints every directive the docs globs can see, grouped by file. Flags [UNKNOWN SOURCE], [NO FENCE], and [INVALID]. Parse-only, offline, always exits 0. --json emits the same inventory as JSON. |
Broken directives never destroy content — the existing fence is left untouched and the problem is reported.