Seconding the explicit opt-in. Less magic behind the scenes. Not to mention, compiled and interpreted code now have different behaviors. You could fix this so that they match, but now you have some magic behavior that's not in the spec -- certain functions get magically modified if you set the deferred functions option.

By making it explicit, ES5 and ES6 will continue to have the same behavior in their common subset, and ES6 and ES6-experimental code will have the same behavior in *their* subset. For example, if I want to use a promise-wrapped `fs` without `await` (using the normal chaining patterns). By exposing the wrapping functionality, I can get to it without flipping a special flag. (Another use-case is combining the wrapped functions with `yield`.)

Would it be possible to have the library do something like this?

```
var requireAsync = require('...').requireAsync;

// This will get you a wrapped version without modifying the original.
// You could do caching here, but not needed for correctness.
var fsAsync = requireAsync('fs');

// This will always give you the original fs
var fs = require('fs');
```

And by making these separate, you could go back to your original, simpler `async` wrapping. By the way, I really liked your use of arrow functions in that code. Reminded me of Haskell.