Skip to content
wit-breaking

Is this WIT interface change safe to ship?

The WebAssembly Component Model lets components compiled in different languages call each other through a shared WIT contract. If a new version silently changes a function's signature, every component importing the old interface fails to compose -- often far from the actual change.

wit-breaking answers one question: does this WIT interface change break every component that imports it?

$ npm install wit-breaking

Every difference, classified

Give it two WIT documents -- before and after -- and it walks every interface and function in both, classifying each difference as breaking (removed function, removed/reordered required param, changed return type) or safe (new optional capability, added function).

src/diff.ts
import { diffWit } from "wit-breaking";

const result = diffWit(beforeWit, afterWit);

if (result.breaking.length > 0) {
  console.error(result.summary);
  process.exit(1);
}

One function, a bracket-depth-aware parser underneath

01

diffWit

diffWit(before, after)

Parses both WIT documents and classifies every interface/function change as breaking or safe.

02

result.breaking

result.breaking: Change[]

Every change that would fail to compose with an existing importer.

03

result.safe

result.safe: Change[]

Additive changes -- new functions, new optional capabilities.

Why this exists

Protobuf and OpenAPI solved this years ago with dedicated tools (buf breaking, oasdiff) that diff two versions of a schema and tell you, in plain language, what would break. WIT had no equivalent -- this project is that tool for WIT.

Also ships as a GitHub Action, published on the GitHub Marketplace, for CI use.

before.wit: func: func(a: string, b: u32) -> result

after.wit:  func: func(a: string) -> result


diffWit() → breaking: param "b" removed

What wit-breaking doesn't do

  • Textual diffing, not semantic wasm analysis.
    Operates on WIT text -- deliberately avoids a vulnerable dependency chain in tools that extract WIT from .wasm binaries.
  • Doesn't rewrite your interface.
    It classifies the change; fixing it is your call.
  • Not a full Component Model linker.
    It diffs interfaces, it doesn't compose or link components.

Catch the break before it reaches every importer

Free and open source under the MIT license.

$ npm install wit-breaking