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.
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.
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:
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:
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 Value | value || "fallback" | value ?? "fallback" |
|---|---|---|
| "hello" | "hello" | "hello" |
| 42 | 42 | 42 |
| true | true | true |
| 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":
function getDisplayName(formData) {
return formData.nickname ?? formData.username ?? "Anonymous";
}
console.log(getDisplayName({ nickname: "", username: "alice99" }));
// "alice99" -- empty nickname means "no nickname," falls through to usernameWith 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":
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:
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.
// 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:
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:
const value = NaN;
console.log(value ?? 0); // NaN (not null or undefined, so kept)
const safe = Number.isNaN(value) ? 0 : value;
console.log(safe); // 0Similarly, nullish coalescing does not validate that a value is of the right type. A string like "not a number" passes through without complaint:
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
| Situation | Use |
|---|---|
| 0, empty string, or false are valid and should not be replaced | ?? |
| Any falsy value should trigger the fallback | OR |
| You need to combine with AND or OR | Wrap one side in parentheses |
| Checking deeply nested properties | Combine ?? with optional chaining |
For more on how the OR version works, see the logical short-circuiting guide.
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.
Frequently Asked Questions
When should I use ?? instead of ||?
Can I chain multiple ?? operators?
Can I use ?? with && or || in the same expression?
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.
More in this topic
JavaScript While Loop Explained: A Complete Guide
A while loop repeats code as long as a condition stays true. Learn the syntax, see practical examples, and understand when a while loop is the right choice over a for loop.
JavaScript Loops Tutorial: for, while, do while
Loops let JavaScript repeat code without writing it twice. Learn the three core loop types, what each one does, and when to choose one over another.
How to Loop Through Arrays Using JS for Loops Guide
Looping through arrays is the most practical use of JavaScript for loops. Learn how to access each element by index, avoid off-by-one errors, and choose between for, for...of, and forEach.