Why typeof null === ‘object’ Is a Bug That Can Never Be Fixed
JS Edition
Open your browser console right now and type this:
typeof nullIt returns "object".
It’s wrong. Everyone knows it’s wrong. The people who built JavaScript knew it was wrong. And it will never be fixed. Here’s the full story of why.
First, let’s confirm it’s actually a bug
null is not an object. It’s a primitive value that explicitly represents the absence of a value. It has no properties. It has no prototype. You can’t call methods on it. It is, by definition, nothing.
null instanceof Object // false
Object.keys(null) // TypeError
null.toString() // TypeErrorEven JavaScript agrees null isn’t an object — instanceof returns false. But typeof still says "object". That’s not a design decision. That’s a bug.
Brendan Eich, who created JavaScript in ten days in 1995, has acknowledged this publicly. It was a mistake in the original implementation that shipped, got copied into every browser, and became part of the web.
Why it happened
To understand this you need to go back to how JavaScript stored values internally in those early days.
Values in the first JavaScript engine were stored with a type tag — a few bits at the start of the value that identified what type it was. The type tags looked something like this:
000 = object
001 = integer
010 = double
100 = string
110 = booleannull was represented as a null pointer — literally the value 0x00 in memory. All zeros. And when typeof looked at the type tag bits of null, it saw 000 — which was the tag for object.
That’s it. That’s the whole bug. null was a zero pointer, the object type tag was zero, and typeof couldn’t tell the difference.
A correct implementation would have checked for the null pointer first, before reading the type tag. It didn’t. The code shipped. The web was built on top of it.
Why it can’t be fixed
This is the part that matters.
In 2006, a proposal was submitted to the ECMAScript committee to fix typeof null to return "null" instead of "object". It was a reasonable proposal. It was rejected.
The reason: the web would break.
Not metaphorically. Literally. Millions of websites, at the time, had code that looked like this:
if (typeof value === 'object') {
// treat as object
}If you’re checking whether something is an object, and you write it this way, you’re accidentally including null. Changing typeof null to return "null" would mean that code no longer catches null — and depending on what it does with it, things break.
More specifically, a lot of code that was “working” was working precisely because of this bug. People wrote null checks that relied on the wrong behaviour, not because they intended to, but because they didn’t know better — or they did know and worked around it that way anyway.
This is the core problem with fixing JavaScript bugs: the language runs in browsers, browsers serve the web, and the web is 30 years of accumulated code. Changing a fundamental behaviour, even to correct it, doesn’t just affect new code. It affects every old page that still loads in a browser.
The JavaScript committee calls this the cost of “web compatibility.” It’s why bugs get preserved as features.
How to actually check for null
Because typeof null === 'object', you can’t use typeof to check for null. You have to use strict equality:
value === nullThat’s the only reliable null check. Not typeof, not instanceof, not truthiness (which also catches undefined, 0, "", and false).
If you want to check for a non-null object — which is probably what you meant when you wrote typeof value === 'object' — you need:
typeof value === 'object' && value !== nullOr more explicitly:
function isObject(value) {
return value !== null && typeof value === 'object';
}This pattern shows up everywhere in JavaScript internals and well-written libraries because everyone who digs deep enough eventually hits this bug and has to work around it.
The deeper lesson
typeof null isn’t the only JavaScript wart that exists because fixing it would break the web. It’s one of many. document.all being falsy but also defined. arguments being array-like but not an array. == coercion rules that make [] == false return true.
These aren’t oversights that nobody noticed. They’re known bugs that the committee has explicitly chosen to preserve because the cost of fixing them exceeds the cost of living with them.
JavaScript is the only language in the world where the bug report says “won’t fix — too many people depend on the broken behaviour.” And because it runs in every browser on every device, that calculus will never change.
typeof null === 'object' is thirty years old. It’ll be there when JavaScript turns sixty.


