Generates and validates UML class and component diagrams for TypeScript source trees, injecting them into Markdown documentation files.
This tool uses component to denote a cohesive group of TypeScript source files
that live in a single directory under src/. This is the same concept Java
developers know as a package — a named namespace boundary that groups related
types and controls visibility. The word "package" is avoided here because in a
Node/npm workspace it already means something else (a publishable npm artifact),
which would create ambiguity.
Given a TypeScript project organised into components (one directory per
component under src/), this tool:
- generates a component overview flowchart showing cross-component import dependencies
- generates a components table with one row per component
- generates per-component class diagrams showing classes, interfaces, and type aliases
All three sections are injected into a single Markdown file between fixed marker pairs. Running the tool again is a no-op if nothing has changed — output is fully deterministic.
npm install --save-dev @datalackey/update-markdown-umlPlace three marker pairs in the Markdown file where you want the diagrams to appear:
<!-- UML:components:START -->
<!-- UML:components:END -->
<!-- UML:components-table:START -->
<!-- UML:components-table:END -->
<!-- UML:component-details:START -->
<!-- UML:component-details:END -->
Then run:
npx update-markdown-uml README.mdThe tool discovers src/ automatically when it exists next to the target
Markdown file. Use --source <path> to override.
For CI drift detection, use --check:
npx update-markdown-uml --check README.mdupdate-markdown-uml [options] <file>
Options:
--source <path> Override source root discovery (default: src/)
--exclude-components <cmp1,cmp2> Leaf directory names to exclude from all output
--test-patterns-to-skip <pat1,pat2> Glob patterns for test files to skip during discovery
-t <pat1,pat2> Short form of --test-patterns-to-skip
--check Do not write; exit non-zero if content is stale
--verbose Print per-component type counts
--quiet Suppress all non-error output
--debug Print debug diagnostics to stderr
--help Show this help message and exit
--version Print version and exit
This tool processes a single Markdown file per invocation. Recursive folder
traversal is not supported — each UML diagram is tied to a specific source
tree, so the association must be declared explicitly. For workspace-wide runs
use autogen-markdown-doc.
For full documentation of shared CLI behavior (--check, --verbose,
--quiet, exit codes) see
Common CLI Behavior.
This folder contains a sample project that demonstrates the tool's output.
Running the sample and reproducing the output you see above by actually installing and running the tool is a good way to get a feel for how it works. Copy/paste the code below to clone the sample, install dependencies, and run the tool.
To view the rendered mermaid graph you could use VSCode's built-in markdown preview, or push it to github and view it in the browser.
rm -rf /tmp/run-sample
mkdir /tmp/run-sample
cp -r javascript/update-markdown-uml/tests/e2e/fixtures/math-cli/* /tmp/run-sample/
cd /tmp/run-sample/
npm install
npx update-markdown-uml README.md
echo Load the README file into your favorite Markdown viewer. Enjoy the injected UML diagrams.
A simple two-component project: a cli layer that delegates computation to
a math-engine layer.
src/
cli/
AddCommand.ts
ArgParser.ts
CliCommand.ts
CliRunner.ts
CommandRegistry.ts
ParsedArgs.ts
SubtractCommand.ts
math-engine/
MathEngine.ts
MathError.ts
MathResult.ts
Operation.ts
cli imports from math-engine. math-engine has no dependency on cli.
Component overview — one subgraph per component, arrows show import direction:
flowchart TB
subgraph cli["cli"]
end
subgraph math-engine["math-engine"]
end
cli --> math-engine
Components table — names link to the class diagram section below.
Descriptions are read from an optional _COMPONENT_INFO.md file in each
component directory; TBD appears when the file is absent. The description
is the first sentence of the file — text up to and including the first
period (.); everything after that period is ignored.
Note: if the file exists but contains no period, the description is
treated as missing (TBD) and a warning is printed identifying the file.
To suppress TBD without providing a description, create
_COMPONENT_INFO.md with a blank first line (no period needed for an
empty file).
| Component | Description |
|---|---|
| cli | Command-line interface layer that parses arguments and dispatches math operations to the math-engine component |
| math-engine | Code for System Backend -- which enables CLI front-end access to a suite of sophisticated math functions |
Class diagrams — one per component, showing classes, interfaces, type aliases, and relationships:
classDiagram
direction TB
class AddCommand {
+name unknown
+description unknown
-engine MathEngine
+execute(args) void
}
class ArgParser {
+parse(argv) ParsedArgs
}
class CliCommand {
<<interface>>
+name string
+description string
+execute(args) void
}
class CliRunner {
-registry CommandRegistry
-parser ArgParser
+run(argv) void
}
class CommandRegistry {
-commands Map<string, CliCommand>
+register(command) void
+get(name) CliCommand | undefined
+listAll() CliCommand[]
}
class ParsedArgs {
<<interface>>
+command "add" | "subtract"
+a number
+b number
}
class SubtractCommand {
+name unknown
+description unknown
-engine MathEngine
+execute(args) void
}
AddCommand ..|> CliCommand
SubtractCommand ..|> CliCommand
classDiagram
direction TB
class MathEngine {
+add(a, b) MathResult
+subtract(a, b) MathResult
-validate(op, a, b) void
}
class MathError {
+operation Operation
}
class MathResult {
<<interface>>
+value number
+operation Operation
+operands [number, number]
}
class Operation {
<<type>>
}
Properties initialised with a
literal value and no explicit type annotation (e.g. readonly name = "add")
are rendered as unknown because the tool reads TypeScript source without
full type resolution. Adding an explicit annotation
(readonly name: string = "add") resolves this.
@datalackey/tooling-core— shared CLI framework and utilitiests-morph— TypeScript compiler API for class and import analysis
For the full workspace tech stack see: TECH-STACK.md
For code overview, development setup, build workflow, and release procedures (including how to trigger a publish via Changesets), see CONTRIBUTING.md.