Understanding the Buffer Deprecation in Node.js 10
A long-standing discussion around the Node.js Buffer constructor was recently revived, addressing the need for a hard runtime deprecation and the potential impact of this decision on the broader Node.js and JavaScript ecosystem.
The Node.js Buffer constructor has had a long and colorful history that has been rather painful for some–both inside the Node.js project itself and in the module ecosystem. That said, the project has now landed on a rather inventive solution that should effectively resolve any outstanding long-term maintenance issues for the ecosystem and ensure a path to guiding the ecosystem to safe and secure usage of the Buffer constructor.
Deprecating the Node.js Buffer Constructor: Prior Context
There was previously an attempt to deprecate the Buffer constructor in Node.js with the release of Node.js v6 in 2016. This update introduced a hard runtime deprecation of using Buffer()
without the new
keyword.
Within a few months of it being merged into Node.js core, the then-CTC (the CTC and TSC have since merged) backtracked on the decision and reverted the change. Despite the original reasoning around security of end-users, the implications were more far reaching than was initially anticipated and there was non-trivial backlash over the deprecation because of that.
The then-CTC had a substantial amount of discussion on the subject of deprecating the Buffer constructor with the community, ending with 146 total comments from 24 individuals that totaled at around 20,000 words. For context, this is the 12th most comment on issue in the history of the core nodejs/node repo, which–at time of writing–has had 7,873 issues filed in the past three and half years.
Deprecating the Node.js Buffer Constructor in Node.js v10
Deprecating the Buffer constructor came back into the conversation recently because improper usage of the Buffer constructor is still a path to insecure code inside an application. Despite the availability of alternatives for the current, unsafe implementation of the Buffer constructor, the same concerns that were raised during the last round of discussions persisted.
One of the biggest issues was that even though developers may not be using the Buffer constructor in our applications, there may be some deeply nested dependency in any given application that is using it. This becomes burdensome for both developers and maintainers. Developers could easily be slapped with warnings that they can’t or don’t know how to fix themselves, and maintainers will gain an added burden of needing to fix every instance of the Buffer constructor in their modules.
The developer pain is non-trivial, but the burden which this change puts on maintainers would be massive–a burden that is intensified for modules that aren’t being actively developed or whose maintainers have stepped away.
With this in mind, the proposed solution to full runtime deprecation of Node.js Buffer constructor is rather simple: deprecate the Buffer constructor outside of node_modules
. This gets around users being stuck with dependencies that they themselves can’t fix, and avoids adding burden to module maintainers, while still encouraging safety for actively developed tooling.
How should you be using Buffers in Node.js?
There are three methods available to replace the deprecated new Buffer()
. These methods should be used anywhere you need to use Buffers in development.
Here are the three new methods, implemented in Node.js core:
Buffer.from() // Creates a new Buffer from the provided string, array of UTF-8 octets, an ArrayBuffer, or another Buffer.
Buffer.alloc() // Creates a new, initialized Buffer of the specified length. Zero filled by default.
Buffer.allocUnsafe() // Creates a new, uninitialized Buffer of the specified length. May contain old (and potentially sensitive) data.
Each of these methods have their own specific use cases, and your mileage may vary on which you need to use. Be sure to check out the official Node.js Buffer documentation for more of the nitty gritty detail on each method and their use cases.
Ecosystem Tooling for Improved Buffer Usage
If you or your team is using ESLint, there is a handy no-buffer-constructor
rule that catches usage of the Buffer constructor and throws an error as appropriate.
To add the no-buffer-constructor
rule, simply add the following line to your ESLint Configuration:
"no-buffer-constructor": "error"
If you are using Standard, the Buffer constructor should be detected and throw an error by default thanks to the usage of the no-deprecated-api
, ESLint ruleset’s usage in Standard.
One Last Thing...
Changes in the tooling we rely on can always be challenging. At NodeSource, we've got an entire team focused on helping other teams be successful with Node.js. If you're curious or need help with Node.js (including with migrating your own applications from using new Buffer
), we'd be happy to help!
Otherwise, if you want to stay in the loop with developments in Node.js and the surrounding ecosystems, be sure to follow @NodeSource on Twitter - we'll be sure to keep you in the loop.