Two operators, two definitions of missing
JavaScript often needs a value to use when another value is unavailable. For example, an interface might display a default label when a name has not been supplied. Both || and ?? can choose a fallback, but they answer different questions. The logical OR operator, ||, asks whether the value on its left is truthy. The nullish coalescing operator, ??, asks whether that value is null or undefined.
If the left value passes the operator’s test, JavaScript returns it; otherwise, it evaluates and returns the value on the right. The difference matters because 0, false and the empty string are falsy, yet each can be an intentional value. Null and undefined, by contrast, commonly represent an absent value. Choose the operator based on what your data means, not simply on which one makes an example appear to work.
See the difference with small examples
The following expressions work in a modern browser console or a JavaScript runtime that supports ?? (introduced in ECMAScript 2020). Evaluate 0 || 10 and the result is 10; evaluate 0 ?? 10 and the result is 0. Likewise, false || true produces true, while false ?? true produces false. For an empty string, "" || "Untitled" produces "Untitled", but "" ?? "Untitled" preserves the empty string.
When the left side is null or undefined, both operators select the fallback: null || "Guest" and null ?? "Guest" each produce "Guest". The same is true when undefined replaces null. A nonempty string or a nonzero number is returned by either operator. These examples reveal the practical question to ask: should a present but falsy value be kept?
Other falsy values include NaN. Objects and arrays are truthy, even when they contain no properties or elements. Neither operator checks whether an object is useful or an array has entries. For example, [] || ["default"] returns the original empty array, and [] ?? ["default"] does too. If your requirement is “use a default when the list is empty,” check its length explicitly.
Match the fallback to the meaning of the value
Use ?? when zero is a valid count, false is a valid setting or an empty string is an accepted input. Consider const pageSize = settings.pageSize ?? 20. This preserves pageSize when it is 0, even if the application later decides that 0 is invalid. Validation and fallback selection are separate tasks: if pageSize must be a positive number, check that condition rather than relying on truthiness to do it indirectly.
Use || when every falsy value should trigger the fallback. For a display label where a blank string is not useful, const label = enteredLabel || "Untitled" may express the intent well. It also replaces 0 and false if they reach that expression, so consider whether those values are possible. If only strings are expected and whitespace-only text should count as blank, neither operator handles that rule by itself; trimming and checking the result makes the rule clearer.
An absent property is another common case for ??. For example, const theme = options.theme ?? "system" uses the default when theme is undefined or null, while preserving an empty string. That does not mean the empty string is necessarily a valid theme. If your component accepts only a defined set of themes, validate against that set before using the value.
Remember evaluation order and grouping
Both operators short-circuit: JavaScript evaluates the right-hand expression only when it needs the fallback. In getName() ?? makeDefaultName(), makeDefaultName() is not called if getName() returns a value other than null or undefined. This is useful when creating a fallback takes work, but it also means side effects on the right may not happen. Prefer fallback expressions that do not need to run for unrelated reasons.
When an expression combines ?? with || or &&, add parentheses to make the intended order explicit. For example, (savedName ?? "") || "Guest" first replaces a missing name with an empty string, then replaces that empty string with "Guest". JavaScript does not allow these operators to be mixed without grouping. Often a simpler expression or a separate variable communicates the rule better.
A reliable habit is to list the values your code may receive—especially null, undefined, 0, false and ""—and decide what should happen to each. If all falsy values mean “use the default,” choose ||. If only null and undefined mean “use the default,” choose ??. When the rule is more specific than either test, write the condition directly.



