Imagine writing a let binding, but with its body omitted and its type mandatorily written down:
external myCFunction: int => string = "theCFunction";
external getElementsByClassName : string => array Dom.element = "document.getElementsByClassName" [@@bs.val];
You'd use an external value/function as if it was a normal let binding.
externals before you get to write 100% pure idiomatic Reason code.
Reason takes interoperating with existing code very seriously. Our type system has very strong guarantees. However, such strong feature also means that, without a great interop system, it'd be very hard to gradually convert a codebase over to Reason. Fortunately, the FFI allows us to cooperate very well with dirty, existing code. The combination of a sound type system + great interop means that we get the benefits of a traditional gradual type system regarding incremental codebase coverage & conversion, without the downside of such gradual type system: complex features to support existing patterns, slow analysis, diminishing return in terms of type coverage, etc.