Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Configuration

Plumb reads plumb.toml from the working directory by default. Pass --config <path> to plumb lint to override. A starter file is written by plumb init; the canonical example is examples/plumb.toml in the repo.

This page is the full reference. Every section is optional. When you omit a section, Plumb uses that section’s defaults. Rules with usable defaults can still run — for example spacing/grid-conformance, edge/near-alignment, and a11y/touch-target. Rules that need a non-empty scale or token list skip when that input is empty.

Editor autocomplete

Generate the canonical JSON Schema and point your editor at the local file for inline validation and hover docs:

plumb schema > plumb.schema.json

VS Code with the Even Better TOML extension:

// .vscode/settings.json
{
  "evenBetterToml.schema.associations": {
    "plumb.toml": "./plumb.schema.json"
  }
}

JetBrains: open Settings → Languages & Frameworks → Schemas and DTDs → JSON Schema Mappings, and add plumb.schema.json against the file pattern plumb.toml.

The schema is for editor association only. Do not add a $schema field to plumb.toml or any JSON config file; Plumb rejects unknown configuration fields.

Top-level shape

[viewports.<name>]    # one or more required for real URLs
[spacing]             # spacing scale and tokens
[type]                # type scale, families, weights, tokens
[color]               # named color tokens + ΔE tolerance
[radius]              # allowed border-radius values
[alignment]           # grid spec + near-alignment tolerance
[shadow]              # allowed box-shadow values
[z_index]             # allowed z-index values
[opacity]             # allowed opacity values
[rhythm]              # vertical-rhythm baseline and tolerance
[a11y]                # contrast + touch target
[rules."<id>"]        # per-rule overrides
[[ignore]]            # selector-scoped runtime suppressions

If [viewports.*] is omitted, Plumb defaults to a single desktop viewport at 1280×800. Real runs SHOULD declare every viewport explicitly.

[viewports.<name>]

[viewports.mobile]
width = 375
height = 667
device_pixel_ratio = 2.0

[viewports.desktop]
width = 1280
height = 800
device_pixel_ratio = 1.0

Each named viewport is a snapshot target. width and height are CSS pixels. device_pixel_ratio is optional; defaults to 1.0. The viewport name appears in the rule output ([mobile], [desktop]) so name them after how you’ll read the report.

[spacing]

[spacing]
base_unit = 4
scale = [0, 4, 8, 12, 16, 24, 32, 48]
tokens = { xs = 4, sm = 8, md = 16, lg = 24, xl = 32, "2xl" = 48 }
FieldTypeDefaultMeaning
base_unitu324Grid base for spacing/grid-conformance.
scale[u32][]Allowed discrete spacing values. Empty disables spacing/scale-conformance.
tokens{string => u32}{}Named aliases. Slash-prefixed names act as namespaces.

Consumed by spacing/grid-conformance and spacing/scale-conformance.

[type]

[type]
families = ["Inter", "system-ui"]
weights = [400, 500, 600, 700]
scale = [12, 14, 16, 18, 20, 24, 30, 36, 48]
tokens = { caption = 12, body = 16, heading = 24 }
FieldTypeDefaultMeaning
families[string][]Allowed font-family values. Empty skips the family check.
weights[u16][]Allowed font-weight numeric values.
scale[u32][]Allowed font-size values in CSS pixels.
tokens{string => u32}{}Named font-size aliases.

Consumed by type/scale-conformance.

[color]

[color]
tokens = { "bg/canvas" = "#ffffff", "fg/primary" = "#0b0b0b", "accent/brand" = "#0b7285" }
delta_e_tolerance = 2.0
FieldTypeDefaultMeaning
tokens{string => hex}{}Named palette colors. Slash-delimited names group by prefix in diagnostics.
delta_e_tolerancef322.0CIEDE2000 ΔE threshold for color/palette-conformance.

Consumed by color/palette-conformance.

[radius]

[radius]
scale = [0, 2, 4, 8, 12, 16, 9999]
FieldTypeDefaultMeaning
scale[u32][]Allowed border-radius values. Empty disables the rule.

Consumed by radius/scale-conformance. The sentinel 9999 is the conventional “fully rounded pill” value.

[alignment]

[alignment]
grid_columns = 12
gutter_px = 24
tolerance_px = 3
FieldTypeDefaultMeaning
grid_columnsu32?nullNumber of grid columns, if you use one.
gutter_pxu32?nullGutter width in CSS pixels.
tolerance_pxu323Edge-clustering window for edge/near-alignment — elements off by 0 < delta <= tolerance_px get flagged.

Consumed by edge/near-alignment.

[shadow]

[shadow]
scale = [
  "none",
  "0 1px 2px rgba(0, 0, 0, 0.05)",
  "0 4px 8px rgba(0, 0, 0, 0.08)",
  "0 12px 24px rgba(0, 0, 0, 0.12)",
]
FieldTypeDefaultMeaning
scale[string][]Allowed box-shadow values. Each entry MUST match the exact string returned by getComputedStyle. Empty disables the rule.

Consumed by shadow/scale-conformance.

[z_index]

[z_index]
scale = [0, 10, 100, 1000]
FieldTypeDefaultMeaning
scale[i32][]Allowed z-index values. Negative integers are accepted. Empty disables the rule.

Consumed by z/scale-conformance.

[opacity]

[opacity]
scale = [0.0, 0.5, 0.75, 1.0]
FieldTypeDefaultMeaning
scale[f32][]Allowed opacity values in the closed range [0.0, 1.0]. Empty disables the rule.

Consumed by opacity/scale-conformance.

[rhythm]

[rhythm]
base_line_px = 8
tolerance_px = 2
cap_height_fallback_px = 0
FieldTypeDefaultMeaning
base_line_pxu320Vertical-rhythm grid step in CSS pixels. 0 disables the rule.
tolerance_pxu322Pixels of drift allowed before a baseline is reported off-rhythm.
cap_height_fallback_pxu320Cap-height value to use when the snapshot lacks font metrics. 0 keeps the rule’s built-in heuristic.

Consumed by baseline/rhythm.

[a11y]

[a11y]
min_contrast_ratio = 4.5

[a11y.touch_target]
min_width_px = 24
min_height_px = 24
FieldTypeDefaultMeaning
min_contrast_ratiof32?nullOptional stricter global floor for color/contrast-aa. The rule still keeps WCAG AA’s built-in 4.5:1 normal / 3.0:1 large defaults.
touch_target.min_width_pxu3224Minimum touch-target width per WCAG 2.5.8. Raise to 44 for AAA.
touch_target.min_height_pxu3224Minimum touch-target height.

Consumed by a11y/touch-target and color/contrast-aa.

[[ignore]]

Selector-scoped runtime suppressions. Each [[ignore]] block silences every violation whose CSS selector path matches selector exactly (string equality only — Plumb does not run a CSS engine over the snapshot). When rule_id is set, the suppression is constrained to that single rule; when rule_id is omitted, every rule fired at the selector is suppressed. Suppressed violations are partitioned out of the report and counted under ignored rather than silently dropped.

[[ignore]]
selector = "html > body"
rule_id = "spacing/grid-conformance"
reason = "mdBook root padding is theme-controlled"

[[ignore]]
selector = "main > article"
reason = "vendor widget styles its own column"
FieldTypeDefaultMeaning
selectorstringrequiredExact SnapshotNode.selector path to suppress.
rule_idstring?nullOptional rule id (e.g. spacing/grid-conformance). When omitted, all rules at selector are suppressed.
reasonstringrequiredHuman-readable justification. Documents why the exemption is intentional.

plumb lint --suggest-ignores emits one suggestion per active violation in the same shape — pipe its output into [[ignore]] blocks to converge on a clean baseline. See --suggest-ignores for the full footer format.

[rules."<category>/<id>"]

Per-rule overrides. Every rule is enabled by default at its declared severity.

[rules."spacing/grid-conformance"]
severity = "error"

[rules."edge/near-alignment"]
enabled = false
FieldTypeDefaultMeaning
enabledbooltrueDisable the rule entirely.
severity"error" | "warning" | "info"rule-definedPromote or demote the severity.

Use plumb explain <category>/<id> (or the Rules chapter) for per-rule docs.

Schema and plumb init

plumb init writes the starter plumb.toml shown above. Pass --force to overwrite an existing file.

plumb schema prints the canonical JSON Schema on stdout. Pipe it to disk and point your editor at it for autocomplete:

plumb schema > plumb.schema.json

The schema MUST round-trip: every field documented above appears in the schema with the same defaults and the same constraints. CI checks this against the rendered examples/plumb.toml.

Where to go next

  • CLI — flags and exit codes.
  • Rules — per-rule reference.
  • Quick start — the five-minute path if you skipped it.