> An Options object is a worse API, since it assumes an implicit dependency.
No, it would be an explicit dependency.
// definition:
function decodeText(input, [format | options])
// use:
decodeText(someBuffer, 'utf8')
// or:
const opts = {encoding: 'utf8', fatal: true, ignoreBOM: false}
decodeText(someBuffer, opts)
decodeText(somethingElse, opts)
> Why?
Because a pure function is idiomatic, concise and clear. Its easier to use, easier to document and easier to understand. The only benefit of a class is that it encapsulates its state behind an interface. That makes sense for a BTree or a database. But TextDecoder has no mutable state. It has no state at all except for its passed-in configuration.
Decoding text is a verb not a noun. In programming, verbs are translated to functions, not classes. You don't have an "adder object" to add things. You don't have to instantiate a JSON stringifier before calling JSON.stringify. If thats not obvious, you may have spent too long in OO languages.