JS Nullish Coalescing Operator: Full Guide

The ?? operator provides a fallback value only when the left side is null or undefined. Learn how it differs from || and when to use each one.

5 min read

The nullish coalescing operator (??) returns the value on its right side only when the value on its left side is null or undefined. If the left side is anything else, even an empty string, 0, or false, the left side is returned as-is.

javascriptjavascript
console.log(null ?? "default");      // "default"
console.log(undefined ?? "default"); // "default"
console.log("hello" ?? "default");   // "hello"   (kept, not nullish)
console.log(0 ?? "default");         // 0          (kept, not nullish)
console.log("" ?? "default");        // ""         (kept, not nullish)
console.log(false ?? "default");     // false      (kept, not nullish)

It is a more precise version of OR (||) for fallback values. Where OR triggers on any falsy value, ?? triggers only on null and undefined.

Why ?? Exists: The Problem with ||

The OR operator has been used for default values since JavaScript's early days, but it has a flaw. It treats 0, an empty string, and false the same as null and undefined:

javascriptjavascript
function getScore(score) {
  return score || 50;
}
 
console.log(getScore(100)); // 100 (expected)
console.log(getScore(0));   // 50  (bug: 0 is a valid score!)
console.log(getScore(null)); // 50 (expected)

A score of 0 is a perfectly valid value, but OR replaced it anyway because it only checks whether the value is truthy or falsy. The ?? operator fixes this by checking specifically for null and undefined instead of every falsy value:

javascriptjavascript
function getScore(score) {
  return score ?? 50;
}
 
console.log(getScore(100));  // 100 (expected)
console.log(getScore(0));    // 0   (fixed: 0 is kept)
console.log(getScore(null)); // 50  (expected)
console.log(getScore());     // 50  (undefined triggers the fallback)

?? vs ||: The Complete Comparison

Left Valuevalue || "fallback"value ?? "fallback"
"hello""hello""hello"
424242
truetruetrue
false"fallback"false
0"fallback"0
empty string"fallback"empty string
NaN"fallback"NaN
null"fallback""fallback"
undefined"fallback""fallback"

The pattern is clear: nullish coalescing only falls back for null and undefined. Everything else stays.

Real-World Use Cases

Form input defaults

When a form field is left blank, its value is an empty string, not null. The nullish coalescing operator preserves the empty string so you can tell the difference between "user typed nothing" and "field was not submitted":

javascriptjavascript
function getDisplayName(formData) {
  return formData.nickname ?? formData.username ?? "Anonymous";
}
 
console.log(getDisplayName({ nickname: "", username: "alice99" }));
// "alice99" -- empty nickname means "no nickname," falls through to username

With OR, the empty nickname would be treated as falsy, which is the same outcome here. But if username could also be empty, nullish coalescing gives you more control.

Numeric zero is meaningful

This is the strongest case for nullish coalescing. Zero means zero, not "missing":

javascriptjavascript
const settings = {
  volume: 0,        // user set volume to zero (muted intentionally)
  brightness: null  // user never set brightness
};
 
const volume = settings.volume ?? 50;       // 0 (kept, zero is intentional)
const brightness = settings.brightness ?? 70; // 70 (null triggers default)

If you used OR here, volume would become 50, ignoring the user's choice to mute.

Configuration with environment variables

When reading configuration values that might not be set:

javascriptjavascript
const config = {
  port: process.env.PORT ?? 3000,
  host: process.env.HOST ?? "localhost",
  retries: process.env.RETRIES ?? 3
};

If PORT is set to 0, which is a valid port in some systems, nullish coalescing keeps it. OR would replace it with 3000 instead.

The Safety Rule: No Mixing Without Parentheses

JavaScript does not let you mix ?? with AND (&&) or OR in the same expression without parentheses. This is intentional: it prevents ambiguity about which operator the developer meant to use first.

javascriptjavascript
// This is a syntax error:
// const result = a || b ?? c;
 
// These are fine because parentheses make the intent clear:
const result1 = (a || b) ?? c;
const result2 = a || (b ?? c);

If you write an OR and a nullish coalescing operator side by side with no parentheses, JavaScript throws a syntax error and refuses to guess. The fix is always to add parentheses around one pair.

Chaining ?? Operators

You can chain the nullish coalescing operator to check multiple fallback values in order:

javascriptjavascript
const primary = null;
const secondary = undefined;
const tertiary = "final fallback";
 
const result = primary ?? secondary ?? tertiary;
console.log(result); // "final fallback"

JavaScript checks each value left to right. The first non-nullish value wins. If all are nullish, the last value is returned.

Where ?? Does Not Help

Nullish coalescing only checks for null and undefined. If your data might contain NaN, you still need an additional check:

javascriptjavascript
const value = NaN;
console.log(value ?? 0); // NaN (not null or undefined, so kept)
 
const safe = Number.isNaN(value) ? 0 : value;
console.log(safe); // 0

Similarly, nullish coalescing does not validate that a value is of the right type. A string like "not a number" passes through without complaint:

javascriptjavascript
const input = "not a number";
const port = input ?? 3000;
console.log(port); // "not a number" (kept, not nullish)

Nullish coalescing is about presence vs absence, not validity. Use additional checks when you need to validate the value itself.

When to Use Which

SituationUse
0, empty string, or false are valid and should not be replaced??
Any falsy value should trigger the fallbackOR
You need to combine with AND or ORWrap one side in parentheses
Checking deeply nested propertiesCombine ?? with optional chaining

For more on how the OR version works, see the logical short-circuiting guide.

Rune AI

Rune AI

Key Insights

  • ?? returns the right side only when the left side is null or undefined.
  • Unlike ||, ?? does not treat 0, '', or false as trigger values.
  • Use ?? for safer default values when zero and empty strings are meaningful.
  • You cannot mix ?? with && or || in the same expression without parentheses.
  • ?? short-circuits: if the left side is non-nullish, the right side never runs.
RunePowered by Rune AI

Frequently Asked Questions

When should I use ?? instead of ||?

Use ?? when 0, '' (empty string), or false are valid values that should not be replaced by a default. For example, a score of 0 is a real score, but || would replace it. Use || when you want to catch any falsy value, including empty strings and zero.

Can I chain multiple ?? operators?

Yes. count ?? backupCount ?? 0 returns the first non-nullish value from left to right. It works the same way as chaining ||, but only skips null and undefined.

Can I use ?? with && or || in the same expression?

No. JavaScript forbids mixing ?? with && or || without parentheses. This is a safety rule to prevent ambiguity. If you need both, wrap one side in parentheses: (a && b) ?? c.

Conclusion

The nullish coalescing operator (??) gives you a clean way to provide fallback values for null and undefined without accidentally overriding 0, '', or false. It is more precise than || and should be your default choice for fallback values when those falsy-but-valid edge cases matter. Use || when you specifically want to catch all falsy values, and remember that you cannot mix ?? with && or || without wrapping one side in parentheses.