CLI¶
The esdm binary exposes six subcommands. This page is the canonical place to look up the exact invocation, flags, and behavior of each one; subcommands are listed alphabetically so the chapter behaves as a lookup surface. The Getting Started chapter walks through the most common invocations in context.
Run esdm --help for the in-binary version of this overview, or esdm <subcommand> --help for a single subcommand.
esdm add-schema¶
Invocation¶
Anatomy¶
esdm add-schema writes the schemas embedded in the running binary into a schemas/ directory in the current working directory, materializing the layout that the schema's x-esdm-project-layout describes – schemas/core/v1.yaml, schemas/<extension>/v1.yaml. Use this once at project setup so editors with a YAML language server can offer autocomplete and validation against the schemas the linter actually uses.
The command refuses to run if a schemas/ directory already exists. Refreshing an existing one is the job of esdm update-schema; refusing here keeps the two paths cleanly separated and prevents an accidental overwrite of edited or pinned schema files.
esdm documentation¶
Invocation¶
Anatomy¶
esdm documentation renders an ESDM model as a tree of Markdown pages and writes it to the directory named by -o / --output, which is required and has no default. It renders the same containment tree as esdm view: one page per element, a container – Domain, Bounded Context, Aggregate, Dynamic Consistency Boundary, Process Manager, Read Model – as a directory with a README.md index, every other element as a .md file, and a root README.md listing the Domains and the Context Mappings. Directories and files are named after the segments of the element's reference, kind_name, with an underscore where the reference has an equals sign, so esdm:domain=library/bounded-context=cataloging/aggregate=book becomes domain_library/bounded-context_cataloging/aggregate_book/README.md. Context Mappings have no Domain and sit at the root.
Each page states the element's name, kind, and reference, its stats line as esdm view shows it, its description, its details, and its children grouped by kind with relative links. Relationships are written out and linked rather than drawn: a Command publishes Events and is issued by Actors, an Event is published by Commands, a Query reads a Read Model, a Read Model projects Events. A Bounded Context renders its ubiquitous language with each term's translations, a Context Mapping its endpoints and term pairs. A link to an element outside the written tree falls back to the element's reference.
The optional [path] argument narrows the output to a sub-region of the model, with the same syntax as esdm view: Domain, Bounded Context, consistency unit, separated by slashes. Pages keep their full paths. When several elements of different kinds share the name a segment names, every match is written.
The directory holding the model is selected with -d / --directory, defaulting to the current working directory. An output directory that exists and is not empty is refused; --force clears it before writing, so the tree always mirrors the model with no orphaned pages. Linter findings do not block the output; only an unresolvable model, an invalid path, or a non-empty output directory without --force is an error, and the exit code is non-zero only in those cases. The output is neutral Markdown without site configuration or theme.
Typical invocations look like this:
esdm documentation --output docs
esdm documentation --output docs <domain>/<bounded-context>
esdm documentation --output docs --force
esdm glossary¶
Invocation¶
Anatomy¶
esdm glossary reads the ubiquitous language declared on the Bounded Contexts of an ESDM model and writes it to stdout as a Markdown glossary. Each Bounded Context with a ubiquitousLanguage block becomes a section, each term an entry, and every discouraged alternative is called out with a short Avoid note. The output is plain Markdown, so redirecting it into a file – esdm glossary > glossary.md – is the intended way to keep it around.
The optional [path] argument narrows the output to a sub-region of the model. The path follows the model hierarchy – Domain, then Bounded Context – separated by a slash. A single segment selects a Domain and emits the glossary for every Bounded Context inside it; two segments select a single Bounded Context. A bare esdm glossary with no path covers the whole model. A segment that names no such Domain or Bounded Context, or that reaches below the Bounded Context level, is rejected as invalid input.
The optional --language flag takes a BCP 47 language tag such as de or de-AT and renders the glossary in that language: a Bounded Context written in it is rendered as is, every other one through the translations its terms declare, including the translations' own Avoid notes. A term without a translation into the requested language keeps its primary form and is marked with an italic No translation into … note. Without the flag, every Bounded Context is rendered in its own language. A value that is not a language tag is rejected as invalid input.
The directory holding the model is selected with -d / --directory, defaulting to the current working directory. There is no --color flag – the output is Markdown meant for files and renderers, not a terminal. Linter findings do not block the glossary; as long as the model resolves, the command emits whatever ubiquitous language it finds. When no Bounded Context in scope declares any, the output is just the # Glossary heading.
The exit code is 0 on success, the empty-glossary case included. It is non-zero only when the path argument is invalid or the model cannot be resolved at all – run esdm lint to find out why in the latter case.
Typical invocations look like this:
esdm glossary
esdm glossary <domain>
esdm glossary <domain>/<bounded-context> > glossary.md
esdm glossary --language de
esdm lint¶
Invocation¶
Anatomy¶
esdm lint walks a directory and lints every .esdm.yaml file it finds. The directory is selected with -d / --directory, defaulting to the current working directory. The walk is recursive; the linter does not stop at sub-directory boundaries.
The output format is selected with --format. The default is human, which produces a readable report grouped by file, with severity-colored headers and source excerpts. The alternative is json, which produces a machine-readable JSON array with one object per finding, suitable for CI pipelines and editor integrations. The --color flag controls human-output coloring: auto detects the terminal capability, always forces colors on, and never suppresses them. The flag is ignored when --format is json.
The optional --warnings-as-errors flag escalates warning-severity findings to errors for exit-code purposes only. The output and the formatted findings are unchanged; the flag affects nothing other than whether a warning-only run exits with 0 or with a non-zero status. Default is off.
The exit code reflects the model's correctness rather than the run's success. esdm lint exits with 0 when the model is clean and with a non-zero status when at least one finding has severity error. Findings of severity warning are reported but do not by themselves cause a non-zero exit, unless --warnings-as-errors is set – then a single warning is enough.
Every rule, its ID, and its severity is listed on Linter Rules, and every finding carries the address of its entry there: the human format prints it as a trailing see line, the JSON format as documentationUrl.
esdm update-schema¶
Invocation¶
Anatomy¶
esdm update-schema refreshes the local schemas/ directory to match the schemas embedded in the running binary. The schema's x-esdm-schema-revision field is the comparison key: the local files are overwritten when the binary's revision is newer.
The command rejects downgrades. If the local schema revision is newer than the binary's – for example, because a project has been updated to a fresh schema while the local esdm binary has not – the command fails rather than silently overwriting newer files with older ones. Update the binary first, then re-run the command.
esdm version¶
Invocation¶
Anatomy¶
esdm version prints the binary's release version followed by the git commit it was built from. Released binaries print a Semantic Versioning (SemVer) string (e.g. 1.4.0); unreleased builds print (version unavailable) in place of the version. The commit is always present, so a build from an unreleased tree is still uniquely identifiable.
esdm view¶
Invocation¶
Anatomy¶
esdm view renders a hierarchical summary of an ESDM model. The optional [path] argument filters the rendered tree to a sub-region of the model, with the path following the model hierarchy – Domain, Bounded Context, Consistency Unit – separated by slashes. Each segment matches elements by name; when several elements of different kinds share a name at one position, every match is rendered. A bare esdm view with no path renders the full model.
The directory holding the model is selected with -d / --directory, defaulting to the current working directory. The optional --with-details flag (default false) includes node-level details such as schemas, invariants, and rule prose alongside the skeleton; without it, the output is just the structural tree. The --color flag controls coloring with the same auto / always / never semantics as on esdm lint.
Typical invocations look like this: