Relune optionally reads a TOML file passed with -c / --config. Values from the file are merged with CLI flags; flags take precedence where both apply.
Unknown keys are rejected during config load. Typoed fields fail fast instead of being ignored.
Merge order
- Built-in defaults
- Config file
- CLI arguments
A full example lives in the repository at fixtures/config/valid_full.toml. Minimal pattern:
[render]
format = "svg"
theme = "light"
layout = "force-directed"
edge_style = "orthogonal"
direction = "left-to-right"
viewpoint = "billing"
group_by = "none"
focus = "orders"
depth = 2
include = ["users", "orders"]
exclude = ["schema_migrations"]
[inspect]
format = "text"
fail_on_warning = false
[export]
format = "schema-json"
viewpoint = "billing"
group_by = "schema"
layout = "hierarchical"
edge_style = "curved"
direction = "top-to-bottom"
focus = "orders"
depth = 1
include = ["users", "orders"]
exclude = ["schema_migrations"]
fail_on_warning = false
[doc]
fail_on_warning = false
[lint]
dialect = "postgres"
deny = "warning"
fail_on_warning = false
[diff]
format = "json"
dialect = "postgres"
fail_on_warning = false
[review]
format = "text"
dialect = "postgres"
deny = "breaking"
except_rules = ["fk-without-index"]
except_tables = ["audit_*"]
[review.severity_overrides."risk/add-not-null-on-existing"]
severity = "info"
[review.severity_overrides."risk/fk-without-index"]
severity = "warning"
[viewpoints.billing]
focus = "orders"
depth = 2
group_by = "schema"
include = ["users", "orders", "payments"]
exclude = ["audit_*"]relune --config relune.toml render --sql schema.sql -o erd.svg| Key | Values |
|---|---|
format |
svg, html, graph-json, schema-json |
dialect |
auto, postgres, mysql, sqlite |
theme |
light, dark |
layout |
hierarchical, force-directed |
edge_style |
straight, orthogonal, curved |
direction |
top-to-bottom, left-to-right, right-to-left, bottom-to-top |
viewpoint |
Name from [viewpoints.<name>] |
group_by |
none, schema, prefix |
focus |
Table name |
depth |
Unsigned integer |
include / exclude |
String arrays |
show_legend, show_stats |
Booleans; --stats on the CLI forces show_stats only |
fail_on_warning |
Boolean; treat warning diagnostics as failures |
layout, edge_style, and direction can be set in the file and overridden with CLI flags. See ReluneConfig::merge_render_args in crates/relune-cli/src/config.rs for exact precedence.
Semantic validation is also applied after merge:
depthmust be at least1depthcan only be set whenfocusis present- table names in
focus,include, andexcludemust be non-empty and must not have surrounding whitespace - the same table cannot appear in both
includeandexclude - if
includeis non-empty, it must contain the focused table - the focused table cannot also appear in
exclude
If viewpoint is set, Relune applies the selected named preset before CLI flags. The precedence for view-related settings is:
- CLI flags such as
--viewpoint,--focus,--include - Selected
[viewpoints.<name>] - Command defaults in
[render]
| Key | Values |
|---|---|
format |
text, json |
dialect |
auto, postgres, mysql, sqlite |
fail_on_warning |
Boolean; treat warning diagnostics as failures |
| Key | Values |
|---|---|
format |
schema-json, graph-json, layout-json, mermaid, d2, dot |
dialect |
auto, postgres, mysql, sqlite |
viewpoint |
Name from [viewpoints.<name>] |
group_by |
none, schema, prefix |
layout |
hierarchical, force-directed |
edge_style |
straight, orthogonal, curved |
direction |
top-to-bottom, left-to-right, right-to-left, bottom-to-top |
focus, depth |
Same as CLI |
include / exclude |
Same as CLI |
fail_on_warning |
Boolean; treat warning diagnostics as failures |
export.format can be set in the config file and overridden with --format. If neither config nor CLI provides a format, the command fails fast. As with render, export.depth requires export.focus, and focused table names must be non-empty after trimming.
export.viewpoint uses the same precedence rule as render: CLI flags override the selected viewpoint, and the selected viewpoint overrides plain [export] focus/filter/grouping defaults.
Named viewpoints let you reuse the same focus, filter, and grouping rules across render and export.
| Key | Values |
|---|---|
group_by |
none, schema, prefix |
focus |
Table name |
depth |
Unsigned integer |
include / exclude |
String arrays |
Use them with render.viewpoint, export.viewpoint, relune render --viewpoint <NAME>, or relune export --viewpoint <NAME>.
| Key | Values |
|---|---|
dialect |
auto, postgres, mysql, sqlite |
fail_on_warning |
Boolean; treat warning diagnostics as failures |
| Key | Values |
|---|---|
format |
text, json |
dialect |
auto, postgres, mysql, sqlite |
profile |
default, strict |
rules |
Array of kebab-case rule IDs to run instead of the profile defaults |
exclude_rules |
Array of kebab-case rule IDs to remove from the active set |
categories |
Array of structure, relationships, naming, documentation |
except_tables |
Array of table patterns to suppress from the report |
deny |
error, warning, info, hint — minimum severity for a non-zero exit when not overridden by --deny |
fail_on_warning |
Boolean; treat warning diagnostics as failures when deny is unset |
default is the balanced schema review profile. strict adds full column comment coverage checks. CLI flags override config values when provided, and array settings follow the same rule: if you pass any CLI values for rules, exclude_rules, categories, or except_tables, those values replace the config list for that key.
| Key | Values |
|---|---|
format |
text, json, markdown, svg, html |
dialect |
auto, postgres, mysql, sqlite |
fail_on_warning |
Boolean; treat warning diagnostics as failures |
diff still requires the before/after inputs on the CLI. The config file supplies defaults for --format, --dialect, and --fail-on-warning, and CLI flags override them when provided. File-based diff inputs are detected by content, so schema JSON copied to a non-.json filename is still treated as schema JSON.
| Key | Values |
|---|---|
format |
text, markdown, json |
dialect |
auto, postgres, mysql, sqlite |
rules |
Array of rule IDs (risk/<id> or bare <id>); empty means "all rules" |
except_rules |
Array of rule IDs to remove from the active set |
except_tables |
Array of table patterns (* glob) whose findings move into suppressed |
deny |
info, warning, caution, breaking — minimum severity that causes a non-zero exit when not overridden by --deny |
review still requires before/after inputs on the CLI. The config file supplies defaults for --format, --dialect, --rules, --except-rule, --except-table, and --deny. CLI flags override config values when provided, and array settings follow the same replacement rule as lint: any CLI values fully replace the corresponding config list.
dialect is consumed twice: by the SQL parser when reading before / after, and by the review rule dispatcher. Setting dialect = "postgres" or "mysql" activates the lock-risk caution rules (risk/add-index-on-large-table, risk/add-fk-on-existing, risk/alter-column-type, and on MySQL risk/rewrite-table); "sqlite" skips them. dialect = "auto" (the default) is promoted to the parser-resolved dialect whenever both before and after parse to the same one — so SQL inputs that both look like Postgres run lock-risk under Postgres automatically. When the two sides resolve to different dialects, the dispatcher stays inactive and emits a REVIEW002 warning so the skip is visible. Schema-JSON inputs carry no parser-side dialect signal, so they keep the historical auto-skip behavior unless dialect is set explicitly. The setting works whether the dialect comes from this TOML key or from the CLI --dialect flag, so relune review can run lock-risk-aware in CI with config alone.
Per-rule severity overrides let you downgrade noisy rules or escalate rules your project cares about without disabling them.
| Key | Values |
|---|---|
severity |
info, warning, caution, breaking |
# Downgrade — treat add-not-null-on-existing as informational only.
[review.severity_overrides."risk/add-not-null-on-existing"]
severity = "info"
# Upgrade — treat missing FK indexes as warnings (so --deny=warning fails the build).
[review.severity_overrides."risk/fk-without-index"]
severity = "warning"
# Downgrade — silence alter-column-type when most of the team's type changes
# are aliases that compile to a no-op rewrite (e.g. CHARACTER VARYING ↔ TEXT
# on PostgreSQL); flag them as info instead of caution.
[review.severity_overrides."risk/alter-column-type"]
severity = "info"Rules:
- The TOML key is the full rule ID (
risk/<kebab>). Bare IDs likeadd-not-null-on-existingare rejected to avoid ambiguity. - Unknown rule IDs are a usage error — typos fail fast on config load instead of being silently ignored.
- Each rule may appear at most once (TOML rejects duplicate keys).
- Overrides are applied after rule evaluation and before summary aggregation, so
summarycounts and the--denydecision both reflect the overridden severity. - There is no CLI flag equivalent in this release; severity overrides are configured via TOML only.
Note
A handful of rules pick a severity case-by-case at evaluation time. risk/drop-pk-or-unique, for example, returns breaking when an incoming FK still references the dropped key and warning otherwise. An override replaces both of those outcomes with the configured severity, so a downgrade to warning will also cover the breaking-with-FK case. Use overrides on case-by-case rules deliberately.
The TOML schema and merge rules are defined in code:
crates/relune-cli/src/config.rs— structure, load, mergefixtures/config/*.toml— examples used in tests