yoda

Require or disallow comparisons with the literal on the left

fixable

A "Yoda condition" puts the literal first: "red" === color instead of color === "red". Most people read the second form more easily, because it matches how you say it: "if the color is red".

The rule checks ==, ===, !=, !==, <, >, <= and >= where exactly one side is a literal. Negative numbers and template literals without ${} count as literals.

--fix swaps the two sides and flips the operator where needed, so 0 < count becomes count > 0.

Configure#

Off by default. To turn it on:

bunfig.toml
[lint.rules]
"yoda" = "error" # or "warn"

Every option, set to its default:

bunfig.toml
[lint.rules]
"yoda" = [
  "error",
  "never", # "always" or "never"
  {
    exceptRange = false,
    onlyEquality = false,
  },
]

Examples#

example.js2 problems
if ("red" === color) {
  stop();
}

if (0 < count) {
  render();
}
example.jsNo problems
if (color === "red") {
  stop();
}

if (count > 0) {
  render();
}

Options#

bunfig.toml
[lint.rules]
yoda = ["error", "never", { exceptRange = true }]

The first option is "never" (default), which wants the literal on the right, or "always", which wants it on the left. The second is an object:

OptionDefaultWhat it does
exceptRangefalseAllow a range test in parentheses, such as (0 <= x && x < 10).
onlyEqualityfalseOnly check == and ===.

With exceptRange, the value can sit between its two limits, or outside them:

example.jswith "never", { "exceptRange": true }No problems
if (0 <= index && index < items.length) {
  select(index);
}

if (value < 0 || 100 < value) {
  reject(value);
}

The parentheses of an if, a while or a call count. Without any around the test, it's still reported:

example.jswith "never", { "exceptRange": true }1 problem
const isPercent = 0 <= value && value <= 100;

With onlyEquality, this isn't reported:

example.jswith "never", { "onlyEquality": true }No problems
if (0 < count) {
  render();
}