Installation
Install with Go 1.27.2 or later:
go install github.com/emlang-project/emlang/cmd/emlang@latest
Or download a precompiled binary from the releases page. Each release includes a SHA256SUMS file to check the downloads:
sha256sum -c SHA256SUMS --ignore-missing
Usage
emlang <command> [flags] <file>
Available commands:
| Command | Description |
|---|---|
init |
Initialize a .emlang.yaml configuration file |
parse |
Parse and display YAML document structure |
lint |
Analyze YAML files for issues and best practices |
fmt |
Format YAML source files |
diagram |
Generate an HTML diagram |
version |
Print version and specification information |
help |
Display help message |
Global Flags
-c, --config
Path to the configuration file. See Configuration Reference for details on .emlang.yaml.
| Flag | Type | Default |
|---|---|---|
-c, --config |
string | .emlang.yaml |
The configuration file is resolved in the following order:
- The
-c/--configflag value - The
EMLANG_CONFIGenvironment variable - A
.emlang.yamlfile in the current working directory
If an explicit path (flag or environment variable) does not exist, the CLI returns an error. If the default path does not exist, an empty configuration is used.
emlang init
Create a .emlang.yaml configuration file with default values in the current directory.
Usage
emlang init
The command exits with an error if a .emlang.yaml file already exists in the current directory.
Examples
# Initialize a new config file
emlang init
emlang parse
Parse and display the structure of a YAML document. Useful for inspecting slices, elements, and tests.
Usage
emlang parse <file>
Arguments
| Argument | Description |
|---|---|
<file> |
Path to a YAML file, or - to read from stdin |
Output
Displays a summary of the document including the number of slices, and for each slice: its name, element count, element details (type, swimlane, name, properties), and attached tests.
Examples
# Parse a file
emlang parse model.yaml
# Parse from stdin
cat model.yaml | emlang parse -
emlang lint
Analyze YAML files for issues and best practices. Returns a list of warnings and errors with file location.
Usage
emlang lint <file>...
Arguments
| Argument | Description |
|---|---|
<file>... |
Paths to one or more YAML files. Use - once to read from stdin. |
Output
If no issues are found:
model.yaml: OK (no issues found)
If issues are found, they are reported with file location, severity, and rule name:
model.yaml: 2 issue(s) found
----------------------------------------
model.yaml:25:5: warning: command should be followed by an event or exception [command-without-event]
model.yaml:30:5: warning: exception without preceding command [orphan-exception]
----------------------------------------
Summary: 0 error(s), 2 warning(s)
With several files:
- Each file is linted on its own and gets its own report.
- A file that cannot be read or parsed counts as one error. The other files are still linted.
- A last line gives the totals:
Total: 3 file(s), 0 error(s), 2 warning(s). - The exit code is 1 if any file has an error.
Rules can be ignored via the lint configuration.
Linting Rules
| Rule | Severity | Description |
|---|---|---|
command-without-event |
warning | Command not followed by event or exception |
orphan-exception |
warning | Exception without preceding command |
slice-missing-event |
warning | Slice without events |
trigger-without-command |
warning | Trigger not followed by a command before the next trigger |
unknown-test-element |
warning | Test element that is not a step of any slice in the same document. Exceptions are not checked. |
view-without-event |
warning | View that no event comes before, in any slice of the same document |
Examples
# Lint a file
emlang lint model.yaml
# Lint several files
emlang lint models/*.yaml
# Lint from stdin
cat model.yaml | emlang lint -
# Lint with a custom config
emlang -c custom-config.yaml lint model.yaml
emlang fmt
Format YAML source files to canonical output:
- Element keys use one style: short (
e) or long (event). - A slice without tests uses the direct form, a list of elements without a
stepskey. - Keys follow a fixed order:
stepsbeforetests;given,when, thenthen; the element type beforeprops. - Element names and swimlanes are trimmed:
" Lane / Name "becomes"Lane/Name".
Comments, quoting, prop values, and the order of slices, tests, elements and props are kept as written.
Usage
emlang fmt [flags] <file>...
Arguments
| Argument | Description |
|---|---|
<file>... |
Paths to one or more YAML files, or - alone to read from stdin. Several files need -w or --check. |
Flags
| Flag | Type | Default | Description |
|---|---|---|---|
-w, --write |
bool | false |
Write the result to each source file instead of stdout. A file already formatted is not rewritten. Cannot be used with stdin. |
--check |
bool | false |
Print the name of each file that is not formatted, without changing it. The exit code is 1 if any file is not formatted. Cannot be used with -w. |
--keys |
string | short |
Key style: long (trigger, command, event, exception, view) or short (t, c, e, x, v) |
The --keys flag priority is: flag > config > default (short).
A file that cannot be read or parsed is reported, and the other files are still processed. The exit code is then 1.
Examples
# Format and print to stdout
emlang fmt model.yaml
# Format in-place
emlang fmt -w model.yaml
# Format several files in-place
emlang fmt -w models/*.yaml
# Check that files are formatted, e.g. in CI
emlang fmt --check models/*.yaml
# Format with long keys
emlang fmt --keys long model.yaml
# Format from stdin
cat model.yaml | emlang fmt -
emlang diagram
Generate an HTML diagram from a YAML file. The diagram can be written to a file, printed to stdout, or served with live reload.
Usage
emlang diagram [flags] <file>
Arguments
| Argument | Description |
|---|---|
<file> |
Path to a YAML file, or - to read from stdin |
Flags
| Flag | Type | Default | Description |
|---|---|---|---|
-o, --output |
string | stdout | Output HTML file path |
--serve |
bool | false |
Start a live-reload HTTP server with file watching |
--address |
string | 127.0.0.1 |
Listen address for the live-reload server (used with --serve) |
--port |
int | 8274 |
Port for the live-reload server (used with --serve) |
Output modes
By default, the generated HTML is printed to stdout. Use -o to write to a file instead, or --serve to start a live-reload development server.
The --serve flag watches the input file for changes, regenerates the diagram automatically, and opens your browser. It cannot be combined with -o or stdin (-).
Diagram appearance can be customized via the diagram configuration.
Connectors
A connector links each element to the next one in its slice.
- A connector goes from the name of one element to the name of the next one.
- The last element of a slice is not linked to the first element of the next slice.
- Elements in tests are not linked.
- Connectors use the text color,
--diagram-text-color. - A browser without CSS anchor positioning shows the diagram without connectors.
Comments
A comment block written just above a document, a slice, or a test is shown in the diagram.
- A document comment is shown above the slice names.
- A slice comment is shown under the slice name.
- A test comment is shown under the test name.
- Each comment line starts a new line in the diagram. An empty comment line starts a new paragraph.
- Comments accept GitHub Flavored Markdown:
**bold**,*italic*,~~strikethrough~~,[text](url)links, tables, lists, and task lists. - Links open in a new tab.
- HTML written in a comment is removed.
- Comments at the end of a line, and comments above an element, are not shown.
# Sign-up flow, see the [spec](https://example.com/signup).
slices:
# A customer creates an **account**.
User registration:
steps:
- c: Register user
- e: User / User registered
tests:
# The email is checked *before* the account is created.
Email must be unique:
given:
- e: User / User registered
when:
- c: Register user
then:
- x: Email already in use
Examples
# Generate and save to file
emlang diagram -o diagram.html model.yaml
# Output to stdout
emlang diagram model.yaml
# Live-reload server on default port (8274)
emlang diagram --serve model.yaml
# Live-reload server on custom port
emlang diagram --serve --port 3000 model.yaml
# Pipe from stdin
cat model.yaml | emlang diagram -o diagram.html -
emlang version
Print the CLI version and the specification version it implements. The CLI version is the release tag. A binary built from source with make build shows the output of git describe, and one built with a plain go build shows dev.
Usage
emlang version
Output
emlang version v1.1.0 (spec 1.0.0)
Stdin Support
All content-consuming commands accept - as the file argument to read from stdin:
emlang parse -
emlang lint -
emlang fmt -
emlang diagram -
emlang diagram -o output.html -
The --serve flag in the diagram command does not support stdin, since it needs to watch the file for changes.
Exit Codes
| Code | Meaning |
|---|---|
0 |
Success |
1 |
Error (missing argument, parse failure, lint errors, write failure, etc.) |
Configuration
Emlang uses a .emlang.yaml file for project configuration. The CLI resolves the configuration file in the following order:
- The
-cflag:emlang -c path/to/config.yaml - The
EMLANG_CONFIGenvironment variable - A
.emlang.yamlfile in the current working directory
See the Configuration Reference for the full list of options.