LiveDoc links Markdown documentation to code symbols and warns when the linked code changes.
When a function, method, interface, type alias, or Go symbol changes, LiveDoc identifies the related documentation fragment and marks it as possibly outdated. This helps teams keep documentation close to the code and verify documentation freshness in local development, pre-commit hooks, and CI.
Documentation often becomes outdated after code changes. Tests can verify behavior, but they usually cannot tell whether a README, guide, or API description still matches the current function signature.
LiveDoc adds an explicit link between a Markdown section and a code symbol:
<!-- livedoc: code_id = "mymodule.calc:add" -->
## `add`
Adds two numbers and returns the result.On the first run, LiveDoc stores the current code signatures. On later runs, it compares the current code with the stored baseline and reports documentation connected to changed symbols.
- Links Markdown sections to code through invisible HTML comment anchors
- Detects signature changes that may make documentation outdated
- Validates that every documented
code_idexists in the scanned project - Reports the source file and line of changed symbols
- Initializes new projects with
livedoc init - Discovers reusable
code_idvalues withlivedoc symbols - Detects duplicate
code_idvalues - Supports text and JSON output
- Supports project configuration through
.livedoc.json - Supports path exclusions through
.livedocignoreand--ignore - Works locally, in pre-commit hooks, and in CI
- Has no required runtime dependencies
- Python: functions, async functions, instance methods, class methods, static methods, positional-only and keyword-only parameters,
*args,**kwargs, type annotations, default values, and return annotations - TypeScript/JavaScript: functions, arrow functions, classes, methods, overload implementations, interfaces, and type aliases in
.ts,.tsx,.js, and.jsxfiles - Go: functions and methods, including pointer and value receivers
LiveDoc excludes common generated, dependency, build, and test paths by default. Additional paths can be excluded through configuration or command-line options.
Install the latest release from PyPI:
pip install living-docTo pin this release:
pip install "living-doc==0.2.0"Check the installed version:
livedoc --versionYou can also run LiveDoc as a Python module:
python -m livedoc --versionLiveDoc requires Python 3.10 or newer.
From the project root:
livedoc init .This creates:
.livedoc.json
docs/
docs/README.md
Existing configuration and documentation files are preserved. Use --force only when you intentionally want to overwrite the generated .livedoc.json and starter docs/README.md files.
To use a different documentation directory:
livedoc init . --docs documentationlivedoc symbols .For machine-readable output:
livedoc symbols . --format jsonCopy the required code_id from the output.
Add a LiveDoc anchor before the section it describes:
<!-- livedoc: code_id = "mymodule.calc:add" -->
## `add`
Adds two numbers and returns an integer.livedoc . --docs docsThe first check creates:
.livedoc/code_signatures.json
Commit this file to the repository. It is the baseline that future checks compare against.
After changing the linked function or method, run:
livedoc . --docs docsLiveDoc reports the connected documentation section as possibly outdated and shows what changed.
After intentionally changing the API and updating its documentation:
livedoc . --docs docs --updateCommit the updated .livedoc/code_signatures.json together with the code and documentation changes.
LiveDoc anchors are HTML comments, so they do not appear in rendered Markdown.
<!-- livedoc: code_id = "package.module:function_name" -->
## Function documentation<!-- livedoc: code_id = "package.module:func_a", "package.module:func_b" -->
## Related functionsAn anchor can be written across multiple lines:
<!-- livedoc:
code_id = "package.module:Service.create"
-->
## Creating a serviceThe anchor applies to the following Markdown section.
For the complete mapping specification, see spec/code-doc-mapping.md.
mymodule.calc:add
mymodule.service:UserService.create
Format:
module.path:function_name
module.path:ClassName.method_name
src.utils:add
src.services.user:UserService.create
src.models:User
Format:
path.to.file:symbol
path.to.file:ClassName.methodName
calculator:Add
service:(*UserService).Create
service:UserService.Validate
Format:
package:FunctionName
package:(*Type).Method
package:Type.Method
Create .livedoc.json in the project root:
{
"docs": "docs",
"ignore": ["build", "generated"],
"ignore_code_ids": ["generated.client:*"],
"format": "text"
}Supported keys:
| Key | Type | Description |
|---|---|---|
docs |
string | Documentation directory relative to the project root |
ignore |
array of strings | Additional ignored path segments or glob patterns |
ignore_code_ids |
array of strings | Symbol patterns excluded from validation and freshness checks |
format |
text or json |
Default output format |
Command-line options override configuration values where applicable.
Create .livedocignore in the project root to exclude paths, one pattern per line:
# Generated files
build
generated
scripts/vendor
Empty lines and lines beginning with # are ignored.
Main commands:
# Initialize configuration and starter documentation
livedoc init .
# Initialize with a custom documentation directory
livedoc init . --docs documentation
# List discovered symbols and reusable code_id values
livedoc symbols .
# List symbols as JSON
livedoc symbols . --format json
# Scan the current project using docs/
livedoc .
# Use a custom documentation directory
livedoc . --docs documentation
# Add ignored paths
livedoc . --ignore tests --ignore generated
# Produce machine-readable check output
livedoc . --format json
# Reduce non-essential output in CI
livedoc . --quiet
# Accept reviewed code and documentation changes
livedoc . --update| Code | Meaning |
|---|---|
0 |
Documentation is up to date, or the first baseline was created successfully |
1 |
Possibly outdated documentation or unknown anchor references were found |
2 |
Configuration, parsing, filesystem, baseline, or duplicate-symbol error |
Text reports include:
- the affected documentation fragment
- the Markdown file and approximate line
- the change reason
- the previous and current signatures
- the current code location
Example:
Possibly outdated documentation (code changed):
* docs/api.md#add
File: docs/api.md, line ~1
Section: add
Reason: param default changed
[mymodule.calc:add] add(a: int, b: int) -> int -> add(a: int, b: int = 0) -> int
Code: mymodule/calc.py:4
Use:
livedoc . --format jsonThe JSON report contains:
okoutdatedunknown_anchors- signature differences
- parameter-level change details when available
- code file and line information
JSON output is intended for CI integrations and other developer tools.
Before enabling CI:
- Add LiveDoc anchors to the Markdown files.
- Run LiveDoc locally once.
- Commit
.livedoc/code_signatures.json.
Create .github/workflows/livedoc.yml:
name: Living documentation
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
permissions:
contents: read
jobs:
livedoc:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
- name: Install LiveDoc
run: python -m pip install "living-doc==0.2.0"
- name: Check documentation freshness
run: livedoc . --docs docs --quietReplace docs if the project uses a different documentation directory. You can also set the directory in .livedoc.json and run livedoc . --quiet.
Add a local hook to .pre-commit-config.yaml:
repos:
- repo: local
hooks:
- id: livedoc
name: LiveDoc
entry: python -m livedoc
language: system
pass_filenames: falseInstall the hook:
pip install pre-commit
pre-commit installRun it manually:
pre-commit run livedoc --all-filesInstall the project with development dependencies:
python -m pip install -e ".[dev]"Run the quality checks:
python -m ruff check .
python -m pytest -q
python -m livedoc examples --docs docsCheck the version:
python -m livedoc --versionLiveDoc/
├── .github/workflows/ # CI workflows
├── examples/ # Python, TypeScript, and Go examples
├── spec/ # Code-to-documentation mapping specification
├── src/livedoc/
│ ├── core/ # Link graph and signature comparison
│ ├── parsers/ # Python, TypeScript/JavaScript, Go, and Markdown parsers
│ ├── report/ # Text and JSON report generation
│ ├── cli.py # Command-line interface
│ └── config.py # Project configuration loader
├── tests/ # Automated tests
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
└── pyproject.toml
See CONTRIBUTING.md for the development setup, testing commands, coding guidelines, and pull request checklist.
The main local checks are:
python -m ruff check .
python -m pytest -q
python -m build
python -m twine check dist/*Build and validate the distributions:
python -m build
python -m twine check dist/*Upload the release:
python -m twine upload dist/*PyPI token authentication uses __token__ as the username and the API token as the password.
Possible future improvements:
- richer pull-request annotations
- additional language parsers
- IDE and LSP integration
- generated documentation views with outdated-section highlighting
- optional automatic documentation update suggestions
Contributions, bug reports, and feature requests are welcome. See CONTRIBUTING.md before opening a pull request.
LiveDoc is distributed under the MIT License. See LICENSE.