Prettier ConfigPrettier Config

experimentalTernaries β€” an opt-in answer to Prettier's longest-running formatting argument

The Prettier Experimental Ternaries option

experimentalTernaries switches on an alternative layout for conditional expressions, sometimes called curious ternaries, in which the question mark sits at the end of the condition line rather than at the start of the consequent. It is opt-in and still labelled experimental, but it addresses a genuinely unresolved problem.

Use curious ternaries, with the question mark after the condition.
Prettier's own description, from the official options documentation
Default
false
Type
boolean
CLI flag
--experimental-ternaries

The problem it is trying to solve

How to format a nested ternary is the oldest open argument in Prettier's issue tracker. The difficulty is that a chain of conditionals is logically a flat list of cases, but syntactically a right-nested tree, and the two views want different indentation.

The conventional formatting indents each level, so a chain of four conditions marches steadily to the right even though the cases are peers. Flattening it reads better but misrepresents the syntax, and every attempt to do so has broken some other case.

What the option changes

With the option enabled, the ? moves to the end of the condition and the branches align beneath it:

const label =
  count === 0 ?
    'none'
  : count === 1 ?
    'one'
  : 'many';
experimentalTernaries: true

The claim is that the condition now reads as a question ending in a question mark, and that the : at the start of each following line makes the branches scan as a list of alternatives. Chained conditionals stay flat instead of stepping rightwards.

Whether to adopt it

  • It is genuinely easier to read for chains of three or more conditions, which is where the old formatting hurts most.
  • It looks unfamiliar. Nobody arriving at your codebase will have seen it before, and initial reactions are frequently negative.
  • It is still marked experimental, which means the exact output may change between releases and reformat your code again.
  • It is all or nothing for the project β€” there is no way to apply it only to long chains.

A reasonable position is to leave it off in shared codebases until it loses the experimental label, and to try it in a personal project first so you have an informed opinion when it stabilises.

The alternative worth considering first

If nested ternaries are hurting, the formatting may not be the real problem. An early-return function, a lookup object keyed by the discriminant, or a switch will usually read better than any layout of a four-deep conditional. This option makes bad ternaries more legible; it does not make them good.

Common mistakes

  • Enabling it in a shared repository without discussion. It is the most visually surprising option in Prettier.
  • Treating experimental as merely cautious labelling. The output really can change between minor releases.
  • Reaching for it instead of restructuring genuinely convoluted conditional logic.

Where the name comes from

The layout is often called the curious ternary, a name from the discussion that produced it. The idea is that the condition should end with its question mark β€” reading as an actual question β€” and the branches below it should read as the possible answers.

The design was worked through over an unusually long and well-documented debate in Prettier's issue tracker, with a great many proposed layouts tested against real code. The experimental label reflects that the winner is still being validated in the wild rather than that it was chosen carelessly.

How it behaves on a single, simple ternary

Most of the discussion concerns nested conditionals, but the option applies to every ternary. A short one that fits on a line is unaffected β€” there is nothing to lay out. A single ternary that has to break gains the new shape:

const message =
  hasUnsavedChanges ?
    'You have unsaved changes'
  : 'All changes saved';
One conditional, broken, with the option enabled.

Whether that reads better than the conventional form is genuinely a matter of taste when there is only one condition. The argument for it strengthens as the chain lengthens, which is why teams that adopt it tend to do so after hitting a three- or four-deep conditional they could not make legible any other way.

Use it in .prettierrc

Drop experimentalTernaries into your Prettier config file:

{
  "experimentalTernaries": false
}
Try it in the generator

Worked examples

The same code formatted with each value of experimentalTernaries.

experimentalTernaries: true

const user = {
  name: "Ada",
  "user-id": 7,
  roles: ["admin", "editor"],
  active: true,
};
const greet = (name) => `Hello ${name}`;
const label =
  user.active ? "active member of the team" : "inactive member of the team";
export function summarize(items) {
  return items
    .filter((i) => i.active)
    .map((i) => i.name)
    .join(", ");
}

experimentalTernaries: false

const user = {
  name: "Ada",
  "user-id": 7,
  roles: ["admin", "editor"],
  active: true,
};
const greet = (name) => `Hello ${name}`;
const label = user.active
  ? "active member of the team"
  : "inactive member of the team";
export function summarize(items) {
  return items
    .filter((i) => i.active)
    .map((i) => i.name)
    .join(", ");
}

Common questions

Is it safe to use in production code?
The output is valid and correct. The risk is churn: the option is experimental, so its exact layout may change in a future release and reformat those expressions again.
Can I enable it only for nested ternaries?
No. It applies to every conditional expression in the files it covers. You can scope it to particular files with an overrides block.

Other JavaScript options

Generated from Prettier 3.9.6.