Versioning
How capabilities are added, how unknown messages behave, and the channel-name migration story.
The bridge has no version number on the wire. Compatibility is structural: it comes from the dispatch rule, not from a negotiated version.
Additive by construction
New capabilities are added by defining a new type. Because an unknown type
resolves to undefined (never rejects — see
Message envelope), every
combination of web build and host build degrades predictably:
| New host (knows the capability) | Old host (does not) | |
|---|---|---|
| New web (calls it) | Works | Resolves undefined |
| Old web (never calls it) | Unused | Unused |
So a new capability can ship to web and native independently, in either order, without a coordinated release.
Feature detection
Because an unknown type returns undefined rather than rejecting, the web
detects host support by probing the result, not by catching an error:
const result = await channel.postMessage({ type: 'someNewCapability' })
const supported = result !== undefinedThe SDK does this internally for any capability whose absence needs a fallback.
For the v1 capabilities, isAvailable() (channel presence) is enough — a
conforming host implements all three.
What counts as a breaking change
A change is non-breaking (ship freely) when it:
- adds a new
type; - adds an optional field to an existing request;
- adds a field to an existing result (web reads known fields).
A change is breaking (requires a new capability type, never a mutation of
an existing one) when it:
- changes the result shape of an existing
type; - makes a previously optional request field required;
- changes the meaning of an existing field.
Never repurpose an existing type. Introduce a new one and let the old one age
out via the table above.
Channel-name migration
The channel is named todayWebViewBridge. Renaming it is the one genuinely
coordinated change, because the name is how the web finds the host on window.
To migrate without a flag-day:
- The host registers both the old and new channel names, backed by the same implementation.
- Web builds move to the new name (the SDK's
channeloption exists for staged rollout and tests). - Once telemetry shows no web build is using the old name, the host drops it.
Until step 3 completes, both names MUST behave identically.