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 keep contracts on in dev/test and
strip them entirely from prod builds. :purge removes the override at
compile time, so the production BEAM contains 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.