Skip to content

Instantly share code, notes, and snippets.

@rpggio
Last active June 30, 2025 16:12
Show Gist options
  • Save rpggio/071d83a9e07bca178cd0506b9721e340 to your computer and use it in GitHub Desktop.
Save rpggio/071d83a9e07bca178cd0506b9721e340 to your computer and use it in GitHub Desktop.

Module IDL (ModIDL) — A concise behavioural contract for JavaScript modules (Draft 0.1, 28 Jun 2025 — feedback welcome)


1 Purpose

Module IDL captures both public surface (types, events, async flows) and observable behaviour (state, ordering, invariants) of a single JS/Wasm module, in a form parseable by humans, code generators, automated tests, and AI agents. It is a minimal subset of the WHATWG Web IDL ecosystem—roughly 30 % of the full grammar—plus a disciplined prose template for algorithms.

2 Scope

  • In-process modules: libraries published to npm, embedded Wasm, Node add-ons.
  • Not a network protocol spec; pair with OpenAPI/gRPC when wire contracts are needed.
  • File extension: .modidl (or .webidl if you prefer unchanged tooling).

3 Kept grammar (normatively references Web IDL §2–4)

Category Tokens kept Notes
Interface definition interface, mixin, namespace [Exposed=Module] is optional default.
Members attribute, readonly attribute, operations (incl. overloads), constructors Extended attributes limited to [Exposed], [Throws], [Clamp], [EnforceRange], [Cancelable].
Data shapes dictionary, enum, typedef, callback, Promise<T>, sequence<T>, record<K,V> ReadableStream<T> & EventTarget allowed to model event or SSE style streams.
Internal state Any [[slotName]] used in prose Must be referred to in at least one algorithm.

4 Pruned items (M-IDL processors MUST ignore)

[Global], [Legacy*], [SecureContext], [CEReactions], [Exposed=Window|Worker|AudioWorklet], [SameObject], [PutForwards], legacy platform array behaviour, interface/attribute modifiers tied to browser security-model quirks.

5 Behavioural prose (“algorithm blocks”)

Immediately after each operation or constructor, authors append a fenced code block:

/* Steps for transfer(from, to, amount):
   1. If amount ≤ 0, throw RangeError.
   2. Let debit = balances[from] − amount.
   3. If debit < 0, queue "InsufficientFunds" event, abort these steps.
   4. Set balances[from] = debit; balances[to] += amount.
   5. Resolve promise with void and queue "TransferCompleted".
*/

Rules: numbered imperatives, limited vocabulary (“queue a task”, “fire an event”, “abort these steps”). All internal slots referenced with [[likeThis]]. This prose is normative; automated conformance tests may be generated from it.

6 Conformance classes

  • Producer: an .modidl file that validates against the kept grammar and lints prose.
  • Implementation: code claiming to implement ModIDL MUST satisfy every algorithm and invariant.
  • Tool: any parser, code-gen, or test generator MAY ignore pruned grammar, but MUST treat unknown kept-grammar constructs as errors.

7 Relationship to other specs

  • ModIDL maps 1-to-1 onto TypeScript declaration generation via webidl2ts (or a custom emitter).
  • May be referenced from OpenAPI via x-behaviour-spec or generated from TypeSpec/Smithy.
  • ReSpec can render .modidl unchanged; existing Web Platform Test harnesses work with minimal tweaks.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment