View Source About
Bond is a Design by Contract library for Elixir. It lets you attach executable specifications to functions:
@predescribes what a function expects from its caller.@postdescribes what it guarantees in return.@invariantdescribes properties of a struct that every public function in its defining module preserves.check/1describes sanity assertions inside a function body.
At runtime, Bond verifies these predicates and raises with diagnostic context — label, expression source, captured binding, and source location — on the first violation.
When to reach for Bond
When typespecs aren't enough. Typespecs declare types; contracts
declare relationships: "amount is positive and not larger than
balance", "result equals balance minus amount", "every operation
preserves length(items) <= capacity". Dialyzer can't reason about
those.
To catch bugs sooner than tests would. Tests cover the scenarios you wrote. Contracts run on every call. Long-running dev or staging environments routinely surface contract violations on paths the test suite never exercised.
Without paying for it in production. Per-kind configuration
(true | false | :purge) lets you decide, per environment and per module,
what a build actually checks — everything, preconditions only, or nothing.
:purge removes the override at compile time, so a production BEAM can
contain no contract evaluation code at all.
Alongside what you already have. Contracts compose with StreamData
(your contracts are the PBT oracle), telemetry
([:bond, :assertion, :failure] for every violation), and Norm (data
shape on the boundary, contracts inside).
Background
Design by Contract was developed by Bertrand Meyer for the Eiffel
language in the mid-1980s, building on earlier formal-specification
work by Tony Hoare and others. For prior art in the Elixir ecosystem —
elixir-contracts, ExContract, Oath — and how Bond came to exist
as a distinct library, see the History guide.
For a hands-on walkthrough, see Getting Started.