1 Operator Basics

1.1 Definition of “nullish” values

Nullish coalescing targets a specific class of “missing” values. In languages that distinguish null and undefined, the term *nullish* refers to expressions whose result is either null or undefined. Values such as 0, false, and the empty string "" are typically *not* nullish, even though they are falsy in boolean contexts.

1.2 Syntax and usage

Nullish coalescing is expressed with the ?? operator. Conceptually, it returns the left-hand expression when that expression is not nullish; otherwise, it returns the right-hand expression as a fallback.

A common shape is:

  • value ?? fallback

In this pattern, fallback is used only when value evaluates to null or undefined, not when value is merely falsy.

1.3.1 Logical OR (||) vs nullish coalescing (??)

Logical OR (`) uses truthiness. That means it triggers the fallback for a wide range of falsy outcomes, including 0, false, "", and null/undefined. Nullish coalescing (??) is narrower: it triggers only for null/undefined`.
The practical difference is that `` can unintentionally replace legitimate “falsy but meaningful” values. Nullish coalescing avoids that by distinguishing missing values from ordinary falsy data.

1.3.2 Ternary operator (condition ? a : b) vs ??

A ternary operator lets you define the condition explicitly. Nullish coalescing is a specialized form focused on the nullish condition. Where the ternary would require writing a check such as `value === nullvalue === undefined ? a : b, ??` provides a built-in equivalent for the common “nullish fallback” case.

The result is typically shorter code and fewer opportunities to write an incomplete null check.

2 Expression Behavior

2.1 Evaluation rules and short-circuiting

Nullish coalescing follows short-circuiting behavior:

  • If the left operand is not nullish, it is the result, and the right operand is not evaluated.
  • If the left operand is nullish, the right operand is evaluated and becomes the result.

This property is important for both performance and correctness, especially when the fallback involves function calls or computations.

2.2 Handling falsy vs nullish values

2.2.1 Falsy examples that should not trigger fallback

With ??, falsy values that are not nullish do not activate the fallback. Examples include:

  • 0 ?? 10 yields 0
  • false ?? true yields false
  • "" ?? "default" yields ""

These behaviors help preserve user-provided or computed values that are valid yet falsy.

2.2.2 Nullish examples that should trigger fallback

Fallback behavior is triggered when the left operand is null or undefined:

  • null ?? "fallback" yields "fallback"
  • undefined ?? 123 yields 123

This aligns with typical “optional value” semantics in programming, where absence is represented explicitly.

2.3 Type inference and propagation

2.3.1 Union types and narrowing behavior

In statically typed settings (commonly TypeScript), ?? can narrow types. If a variable has a union that includes null or undefined, applying ?? fallback typically removes those nullish cases from the resulting type.

For example, if an expression has a type like `stringundefined, then expr ?? "x" tends to produce a plain string rather than a union with undefined`. The exact inferred type depends on the language’s type system and the types of both operands.

2.3.2 Optional values in function results

When functions return optional data—often modeled as `Tundefined or Tnull`—nullish coalescing provides a straightforward way to produce a total value for downstream logic. This is frequently used to:
  • supply defaults for display text,
  • ensure numeric computations receive a number instead of an optional,
  • construct configuration objects with guaranteed properties.

The operator’s narrowing behavior supports safer code by reducing the need for repetitive null checks.

3 Practical Patterns

3.1 Defaulting function parameters

When optional parameters are passed into a function, ?? can establish defaults while respecting falsy-but-valid arguments.

A typical approach is:

  • function f(options) { const limit = options.limit ?? 20; }

Here, a caller can provide 0 intentionally, and the function will keep it rather than substituting the default. This is especially helpful for numeric limits, flags, and indices.

3.2 Setting configuration fallbacks

Configuration objects often contain optional fields. Nullish coalescing supports building a normalized configuration where absent fields become defaults.

For example, an application might define:

  • theme = config.theme ?? "system"
  • itemsPerPage = config.itemsPerPage ?? 25

This ensures missing settings are handled, while explicitly provided values remain unchanged.

3.3 Safe access patterns with optional chaining

Nullish coalescing is commonly used together with optional chaining to handle layered optionality.

A common pattern is:

  • user?.profile?.name ?? "Guest"

Optional chaining prevents runtime errors when intermediate properties are missing, while ?? supplies a fallback string when the final value is nullish. Together, they create resilient data-access code.

3.4 Combining multiple fallbacks

3.4.1 Chaining ?? for layered defaults

Multiple fallbacks can be expressed by chaining ?? operators:

  • primary ?? secondary ?? tertiary

This establishes a priority order. The first non-nullish value is selected, while nullish values fall through to later options.

Chaining is often used for:

  • environment-dependent defaults,
  • progressive enhancement in UI code,
  • merging sources like user settings, stored preferences, and library defaults.

3.5 Avoiding common pitfalls

3.5.1 Side effects in fallback expressions

Because the fallback expression is evaluated only when needed, side effects inside the right operand may not occur in cases where the left operand is non-nullish. This can surprise developers if they expect certain side effects to happen every time.

A safe practice is to keep fallback expressions free of unintended side effects or to ensure that side effects are intentionally conditional.

4 Readability and Maintainability

4.1 Choosing between ?? and other constructs

A useful rule of thumb is:

  • choose ?? when you mean “missing value” (null/undefined),
- choose `` when you mean “no meaningful value” in a broader truthiness sense,
  • choose the ternary when the fallback condition is not limited to nullishness.

Selecting the operator that matches the intent improves clarity for future readers.

4.2 Code style guidelines

Maintainability improves when nullish coalescing is formatted consistently. Common style considerations include:

  • keeping fallback expressions short and descriptive,
  • using parentheses when combining with other operators in complex expressions,
  • avoiding deeply nested chains that obscure priority order.

When chains are long, it can be clearer to assign intermediate values to named variables.

4.3 Naming conventions for fallback values

Fallbacks benefit from naming that communicates why they exist. Instead of inline literals like "default", some codebases use:

  • defaultLanguage,
  • fallbackLabel,
  • maxRetriesDefault.

Even when literals are acceptable, descriptive constants can make the reason for the fallback explicit, which helps when the code is reviewed or modified later.

5 Interoperability and Tooling

5.1 Language and version support

Nullish coalescing is supported in modern versions of several mainstream languages, with TypeScript and JavaScript being the most common context. Availability depends on:

  • the runtime or target environment,
  • the language compiler configuration,
  • whether the project uses a transpiler.

Before adopting it widely, teams typically verify that their minimum supported environments can handle the syntax or that the build pipeline transpiles it as needed.

5.2 Transpilation/build tool considerations

When transpilation is used, build tools may transform ?? into equivalent older syntax. Teams should consider:

  • whether the transpiler preserves short-circuiting semantics correctly,
  • how the operator interacts with minification and source maps,
  • whether generated code affects debugging workflows.

In most modern setups, these concerns are handled automatically, but configuration details can matter in legacy targets.

5.3 Linting and static analysis notes

Static analysis tools often include rules related to nullish coalescing usage. Examples of guidance commonly found in linters include:

- preferring ?? over `` for defaulting optional values,
  • warning when an expression is always non-nullish (making the fallback unreachable),
  • flagging unreachable code due to overly restrictive types.

These checks can help prevent subtle logic errors and improve confidence in refactors.

6 Examples

6.1 Minimal examples

A minimal default:

  • result = maybeValue ?? 42

If maybeValue is null or undefined, result becomes 42. Otherwise, it remains unchanged.

A minimal string fallback:

  • label = userLabel ?? "Untitled"

This avoids replacing an empty string if that empty string is intentionally provided.

6.2 Realistic data-handling examples

Consider an API response where a field may be absent:

  • const pageCount = response.pageCount ?? 0;

If the server omits the field, the code uses 0. If the server sends 0, that value is preserved.

For date formatting:

  • const displayDate = record.dateISO ?? record.createdISO

The fallback takes over only when dateISO is missing, not when it holds a falsy-but-present value (if such a value could exist in the domain model).

6.3 UI and form input defaults (lightweight scenarios)

In UI form logic, empty inputs are often significant, but missing values should be replaced with something safe for rendering. For example:

  • const placeholderText = form.values.placeholder ?? "Type here..."

If the user explicitly clears the field to an empty string, "" will remain, which can be useful for reflecting user intent. If the field is truly absent, the placeholder appears.

7 FAQ

7.1 When should I prefer ?? over ||?

Prefer ?? when the fallback should apply only to truly missing values (null/undefined). Choose ` when the fallback should apply to any falsy outcome, including 0, false, or ""`.

In data and configuration handling, ?? is often the safer defaulting tool because it avoids overwriting meaningful falsy values.

7.2 Why did my value not fall back?

A value does not fall back when it is not nullish. Common causes include:

  • the value is 0, false, or "" (falsy but not nullish),
  • the value is a wrapper object or expression that does not evaluate to null/undefined,
  • the expression is guaranteed by types to be present.

Checking what the left operand actually evaluates to at runtime is usually the quickest way to diagnose the issue.

7.3 Can I use ?? with complex expressions?

Yes. The left and right operands can be complex expressions, as long as the operator’s short-circuiting semantics are what you intend. Keep in mind that the right operand is evaluated only when the left operand is nullish, so any computations or side effects in the right operand happen conditionally.