Node streams have a reputation. James Halliday wrote a "stream-handbook" repo over a decade ago that became canonical, and the existence of a handbook told you everything. For years, asking a Node developer about backpressure was a way to find out which job they were about to quit.

The reputation was earned, but it's mostly obsolete now. The API got fixed in stages between 2018 and 2021, and nobody made a clean announcement of it, so the cultural memory stayed at "streams are scary" while the actual code became, for most uses, boring.

Why they were hard

The short version: three eras of API coexisting in one type, errors that didn't propagate through .pipe(), backpressure as an advisory boolean that ninety percent of code ignored, and four different events all roughly meaning "done" ('end', 'finish', 'close', plus a null from read()). The longer version is the stream-handbook itself.

Pre-2018, writing correct stream code meant remembering, for every pipeline, that you had to attach 'error' to every stage because .pipe() didn't propagate errors and a downstream failure would orphan the upstream stages, hanging the process or leaking file descriptors. You had to check the return value of .write() and listen for 'drain', because otherwise your writable buffer grew until the process OOMed. You had to know which mode (paused or flowing) your readable was in, because attaching a 'data' listener flipped it, and once flowing you could lose chunks if you attached late. And you had to distinguish 'end' (no more reads) from 'finish' (all writes flushed) from 'close' (resource released), because they fired at different times and meant different things.