Streams offer two major benefits, the first being fine grained control of memory and CPU resources via incremental processing.
The second is a terse yet powerful common interface, that when used as a pattern can provide a clean separation between source inputs, transformation layers, and target outputs.
For instance, imagine we're implementing a protocol layer, that's most likely going to be used with a TCP server.
We could add a layer of abstraction on top of the net module's TCP server, or we could provide a stream that can be piped to it from a net socket.
In the latter case, our protocol implementation is decoupled from the source, allowing alternative (potentially unforeseen uses). For instance, it may become useful to use with WebSockets, or over UDP; perhaps it could be used in a tool that takes input from STDIN.
This recipe rounds off our...