Instantly share code, notes, and snippets.

@bmeck /Bad Secret
Created Nov 17, 2016

What would you like to do?

Bad Points from

Type Quirks

The behaviors below are quirks of the JS language that stand out as odd when coming from other languages.

typeof null // "object"

In the first implementations of JS, tagging for type was encoded within values. null shared the same tag as an object. There is an interesting note here that null and undefined are separate since null can be encoded into Java which was important at the time but undefined is unable to be represented in Java. undefined can be used to represent missing values of Java primitives; while null can represent missing values of Java Objects. So in some sense, the value of "object" makes sense here.

x == y

Type coercion is something that few languages do. JS does it for almost all binary operators. I would avoid this and use ===. By using === you can avoid the need for VMs to check types, avoid potentially costly Symbol.toPrimitive, .toString, and .valueOf calls. In addition, there are some security attacks that rely on type coercion that can be avoided by using ===. Linters can help you here.

0.1 + 0.2 != 0.3 // true

This is a result of strict compliance with floating point IEEE implementation. This is actually unrelated to language problems. JS does not allow for margin of error within IEEE comparisons. If you need arbitrary precision, use a "big number" library.

NaN === NaN // false

This again comes to IEEE. NaN can be represented in many values but only has one JS constant. NaN is a popular discussion at TC39. NaN === NaN is false in most languages, but PHP returns true.


NPM is slow

Configuration is key with npm. In particular change cache-min to be a much larger value.

This will aid with development situations, but may not help you with production deployment. Definitely use a build server to produce builds and do not run npm on production machines, both for speed and security reasons.

NPM runs scripts

Yes! Though you can turn this off with npm --ignore-scripts. I would suggest doing this when possible.

You can force native modules to be built using npm rebuild, but like most build systems, this also allows script execution.

yarn has made a claim that they are more secure for not doing this, however they still run gyp and suffer similar problems to npm, this seems more of a marketting ploy than fact.

yarn also claims that a lockfile (similar to a shrinkwrap file) is a security mechanism. It is a consistency mechanism and should not be treated like a security feature. Lockfiles produce consistent results, they do not relate to security. Over the life of your project you will want security updates, a lockfile would prevent these updates from landing. ALWAYS check what you are about to install before shipping and ALWAYS run checks against your production system even if it is already deployed.

I would also take a look at various projects like the Node Security Platform that have CLI tools that can check if there are security problems with your dependency tree.

Using all of the above you would have this workflow:

npm install --ignore-scripts
npm shrinkwrap
nsp check # you can use this and `cron` for periodic checks
npm rebuild

Documentation needs to be better

Agreed! The core team is struggling to keep up with the current amount of work it has to do and would love for more people to get involved so that time can be freed up for more documentation. There is also a desparate need for a new UI/UX for documentation so that it can be more useful to people reading it. If you are interested the Docs Working Group might be the right place to look. Most of the stuff done there is in the github issues.

Async APIs

Ineffective Streams API

Node's Streams are vastly different from WHATWG's Streams. They both try to solve similar problems, however, Node's Streams are older and suffer from having multiple versions using the same API with breaking changes. This has led to some inefficiency.

In the future look towards async iteration and observables as a potential way to get an effective userland streams implementation from the language that does not differ between Node and Browser APIs.

Promises in Core

We have been talking about this for a while now and Chris Dickinson has put lots of effort into this. Unfortunately, the API which Promises use in the JS standard causes some problems with debugging core dumps. This has led to problems ever using them in Node's Core since it would prevent post-mortem debugging.

Also, there are some people wondering if there will be a "promisified" API for Core. This also is unlikely since several APIs use both a return value and callbacks like net.createConnection large portions of Core would need to be completely replaced with new APIs.

Remove Sync APIs

This is unlikely to be removed but the reasons to use Sync APIs could be removed if top level await ever became part of the JS specification.


The JS Date API is strange, always. There is some collaboration though between MomentJS and TC39 to figure out what a new API might look like.

Memory Usage

There should be some better memory usage in Node v7, however JS as a language is very memory heavy. If memory is a concern, I might suggest looking at using TypedArrays whenever it makes sense to do so. Another thing to look at is what is holding onto value references by taking a Heap Snapshot. I suggest looking at using node --inspect and using Chrome DevTools to debug memory usage these days. Bradley Farias (Bradley Meck) is working on improving the inspector, and hope to add additional metrics sometime in the future.


LTS is short

It was a struggle to get 30 month support for LTS actually, several parts of the CTC and TSC would like it to be shorter. In large part, this relates to the amount of man hours required to back port changes. After a year or two it becomes a very difficult task to back port changes to VMs since V8 also has a short LTS.

Centralized Package Management

With the advent of competition to npm like yarn I expect the next year to discuss this more seriously. Although people do run their own npm registries through NPM Enterprise or Artifactory there appears to be some interest in a new decentralized P2P registry. There are security concerns with P2P as well and code signing would most likely need to be looked at first though.

API Stability

Node has always allowed breaking changes to existing APIs. The long stagnation period of v0.10 led some people to belive that no breaking changes to existing APIs were allowed. This is not the case. However, even with the "frozen" status of some parts of Node Core that does not mean that additional features will not be added to them. Software is never done and continues to evolve :).

Too Many Experts

This is a result of the difficulty of fully understanding Node's internals. More people contributing to the JS and C++ of Core might allow for a less specialized contributor workflow. This problem is being discussed in various meetings in part due to the bus factor.


Hazing/ Shaming/ English being used as Lingua Franca

There is a need for a well defined language to communicate in and for Node this has been English in github PRs and Issues.

ES Modules

TC39 and Node are looking at changes to the JS specification that would make this possible. Node can technically implement ESM under the current specification but not in a way that it could interact with CommonJS. Having problems using the Core Modules (which are CommonJS currently) can be worked around by Core implementing a second API just for ESM; however, this would not fix people being unable to use any modules from npm.

Core is trying to support ESM in some form, but cannot implement ESM until VMs such as V8 finish implementing the C++ bindings for Node to use. Chakra has actually finished their ESM implementation under the current specification, but will need to make changes as TC39 and Node continue discussions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment