Skip to content
Beskid Platform specification

Beskid

Jump to a Beskid service

Beskid

Jump to a Beskid service

Canonical pretty-printer with no user knobs

Platform spec ADR

Canonical pretty-printer with no user knobs

Spec standingStandard

Owner
Piotr Mikstacki
Submitter
Piotr Mikstacki

Most modern languages that ship a first-party formatter (gofmt, rustfmt with default config, dotnet format, csharpier) converged on the same answer to the bikeshed question of formatter style: pick one and don’t expose knobs. Languages that allow per-project style files (older prettier configs, clang-format) routinely waste cycles in code review on layout disagreements and create friction for cross-project contributions.

The Beskid formatter starts from a clean slate. The reference implementation in compiler/crates/beskid_analysis/src/format/ is already opinionated (four-space indent, brace on same line, one blank line between members) and ships through a single CLI surface (beskid format / beskid fmt). The question this ADR resolves is whether to expose layout configuration to consumers.

The Beskid formatter must be a canonical, knob-free pretty-printer. The platform ships exactly one layout style. The formatter:

  1. Must not expose user-configurable width, indent unit, brace style, member ordering, blank-line policy, or comment placement.
  2. Must not read project-level style files (no .beskid-format.toml, no [format] section in Project.proj).
  3. Must be a pure function of the parsed AST and the formatter version compiled into the CLI.
  4. May change formatter output between releases under the rules in the parent hub’s Compatibility and versioning section (release notes + idempotency preserved + ADR when the layout policy changes substantively).

The CLI must continue to support the operational flags --write, --check, and --output; these affect where the output goes, not what it looks like.

Pros:

  • Zero bikeshedding in code review: there is exactly one correct way for any given input.
  • Deterministic CI: beskid format --check is a reliable PR gate; no per-repo style file ambiguity.
  • Simpler editor integrations: every plugin can shell out to the canonical CLI without re-implementing layout logic.
  • Faster onboarding: new Beskid contributors don’t need to learn project-specific style files.

Cons / accepted trade-offs:

  • Teams with strong existing house style (especially “tabs” or “2-space”) cannot satisfy that preference via the formatter; this is by design.
  • Future syntactic features that might benefit from style-aware emission (for example, partial-application chains) must take a layout decision once and ship it as part of the formatter, not defer to user preference.
  • Some downstream tools that wrap the formatter and want to expose style flags must either drop those flags or layer them outside the canonical formatter.
  • beskid_analysis::format::policy — single file that owns layout policy; no other formatter file emits \n or indent runs directly.
  • beskid_cli::commands::format::FormatArgs — the clap surface contains only --write, --check, --output; the absence of style flags is observable from beskid format --help.
  • Parent hub Layout policy section — enumerates the fixed indent unit, blank-line rules, and brace style.