Prettier ConfigPrettier Config

experimentalOperatorPosition β€” whether a wrapped operator trails the line above or leads the line below

The Prettier Experimental Operator Position option

experimentalOperatorPosition decides where the operator goes when a binary expression is too long for one line. The default end leaves it trailing the line above; start moves it to the front of the continuation, so the operator is the first thing you read on each line.

Where to print operators when binary expressions wrap lines.
Prettier's own description, from the official options documentation
Default
"end"
Type
choice
CLI flag
--experimental-operator-position
Allowed values
startend

What the option does

When a chain of &&, ||, + or a comparison has to wrap, something must decide which side of the break the operator lands on.

const ready =
  isLoaded &&
  hasPermission &&
  !isBlocked;
end (default)
const ready =
  isLoaded
  && hasPermission
  && !isBlocked;
start

The argument for start

Leading operators put the connective in a fixed column, so the structure of the expression is visible down the left edge. You can tell at a glance whether a chain is all && or mixes in an ||, which is exactly the mistake that produces subtle logic bugs.

With trailing operators the connective sits at a ragged right edge, at whatever column the previous operand happened to end. Scanning for a stray || in a long condition means reading to the end of every line.

Leading operators also make diffs slightly cleaner when a condition is added or removed, since the operator travels with the operand it precedes rather than being stranded on the line above.

The argument for end

Trailing operators are what almost all JavaScript looks like, and familiarity is worth something. A line ending in && also signals unambiguously that the statement continues β€” with leading operators you have to look at the next line to know the previous one was incomplete.

This is why the default is end despite the readability case for start being reasonably strong.

Experimental status

The experimental prefix is a real caveat. The option was introduced in Prettier 3.5, its behaviour on some operator combinations is still being refined, and adopting it now means accepting that a future release may reformat those expressions again.

For a personal project that is a fine trade. For a shared codebase, waiting until the prefix is dropped avoids paying the reformat cost twice.

Common mistakes

  • Expecting it to change single-line expressions. It only takes effect once an expression has to wrap.
  • Assuming it covers every operator uniformly β€” assignment and arrow tokens follow their own rules.
  • Adopting an experimental option across a large codebase and then absorbing a second reformat when it changes.

What other languages settled on

JavaScript's trailing-operator habit is not universal, and the arguments have been rehearsed elsewhere. Haskell and Elm lead with operators as a matter of course. Python's PEP 8 was revised specifically to recommend breaking *before* a binary operator, reversing its earlier advice, on the grounds that it puts the operator next to its operand and makes long formulae easier to check.

SQL conventions overwhelmingly lead with AND and OR for the same reason: a WHERE clause is read as a list of conditions, and the connective belongs with the condition it introduces.

None of that settles the question for JavaScript, where the trailing form is entrenched. But it is worth knowing that the case for start is not a novelty β€” it is the majority position in several communities that thought about it carefully.

Which operators are affected

The option governs binary and logical operators β€” arithmetic, comparison, &&, ||, ??, and the bitwise family. It does not govern every token that can end a wrapped line:

  • Assignment stays at the end of the line; a leading = is not produced.
  • The arrow of an arrow function is not repositioned.
  • Member access in a method chain follows its own rules, and already leads with . on each line.
  • Ternary ? and : are governed by experimentalTernaries, not by this option.

So enabling start changes boolean and arithmetic chains while leaving chained calls looking exactly as they did β€” which is arguably a consistency gain, since method chains already lead.

Use it in .prettierrc

Drop experimentalOperatorPosition into your Prettier config file:

{
  "experimentalOperatorPosition": "end"
}
Try it in the generator

Allowed values

start
Print operators at the start of new lines.
end
Print operators at the end of previous lines.

Common questions

Why is my short expression unaffected?
The option only applies when a binary expression wraps. Anything that fits within printWidth stays on one line, and there is no operator position to decide.
Should I use start?
It has a real readability advantage in long boolean chains, because the operators line up in one column. Weigh that against unfamiliarity and the experimental label β€” a future release may change the output again.

Other JavaScript options

Generated from Prettier 3.9.6.