Skip to content

Track & test the target ReScript version — output is implicitly ReScript 12 with no declared/CI-enforced compatibility range #159

Description

@jagguji

Problem

The emitted bindings are idiomatic ReScript 12type props = {…} + React.component<props>, @tag/@as variants, record spreads (...HtmlAttrs.x), optional record fields (field?: t), @react.component, and the v12 stdlib surface (Nullable.t, Dict.t, JSON.t, React.element, JsxDOM.style). This target is currently implicit and untracked:

  • package.json declares no engines field and no peerDependency/peerDependenciesMeta on rescript, so nothing records which ReScript major(s) the output is known to compile on. The README says "ReScript 12 is recommended for the generated output," but that's prose, not a checked contract.
  • CI has a single Golden compile (ReScript 12) job — one version, no matrix. There's no signal if the output breaks on a future ReScript, and no evidence of the floor it still works on.
  • The generated artifacts don't carry the target either: _REPORT.md / .bindgen-manifest.json / _bindgen-summary.json record component buckets and dep status but not "these bindings target ReScript ≥ X".

When ReScript 13+ lands this bites: stdlib modules can be renamed or remapped (the Belt/Js → core-stdlib churn is precedent), @react.component / JSX lowering can change, record-props or @tag semantics can shift, and formatting (rescript format) output can drift — silently invalidating the "same Blend version → byte-identical output" guarantee against a newer toolchain. A consumer on a newer ReScript has no declared compatibility range to check against, and this repo (the pinned-preview validation loop for blend-rescript) would only discover breakage by regenerating and compiling by hand.

Impact

Medium — not urgent while ReScript 12 is current, but it's latent tech-debt that turns into a scramble the moment a consumer or CI moves to the next major. A declared, tested version contract is what lets an upgrade be a deliberate, reviewed step instead of a surprise.

Suggested fix (a few independently-shippable pieces)

  1. Declare the contract. Add an engines/peerDependency-style statement of the supported ReScript range to bindgen's package.json (e.g. "rescript": ">=12 <13"), and stamp the target into the generated _REPORT.md header + _bindgen-summary.json (a rescriptTarget field) so every output says what it was built for.
  2. Test the range, not a point. Turn the golden-compile job into a small matrix over the supported ReScript majors (and the intended-next prerelease, allowed-to-fail) so a break on an upcoming version surfaces as a red check with a known cause, not a downstream mystery.
  3. Track the upgrade explicitly. A short docs/ note (or a tracking issue template) capturing the v12-specific idioms bindgen emits — React.component<props>, @react.component, @tag/@as, record spreads/optionals, the stdlib module set — so that when ReScript N+1 changes any of them, there's a checklist of emit sites to revisit rather than rediscovering them. If/when the emit surface needs to diverge per major, a --rescript-version (or auto-detected) switch on the emitter is the natural home; not needed until a real divergence exists, but the tracking note is what tells us when that day arrives.

Filing as a tracking issue for now — no code change requested yet; the goal is that "which ReScript version does the output target, and how do we know when to upgrade" stops being implicit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions