ESLint's no-lonely-if Rule Explained: Keeping Your Code Clean and Readable


  • You have an if statement followed by an else block.

This lone if statement within the else block is considered a "lonely if" by ESLint.

Why is it an issue?

While it works functionally, it can make the code less clear. It's often easier to understand the logic if you rewrite it using an else if statement instead.

Example

if (condition) {
  // do something
} else {
  if (anotherCondition) {
    // do something else
  }
}

This can be rewritten as:

if (condition) {
  // do something
} else if (anotherCondition) {
  // do something else
}

The else if makes it explicit that the second condition is only checked if the first one isn't met.

Enforcing no-lonely-if

The no-lonely-if rule helps catch these situations and suggests refactoring the code using else if. This can be enabled as an error or warning in your ESLint configuration.

  • While no-lonely-if enforces a specific coding style, it's ultimately about improving code clarity and readability.
  • There are ESLint plugin extensions, like eslint-plugin-unicorn, that offer a more comprehensive no-lonely-if rule. These can also flag lonely if statements within the if block itself, not just the else block.


Code flagged by ESLint (Lonely if)

if (isLoggedIn) {
  showWelcomeMessage();
} else {
  if (isRememberedUser()) {
    prefillLoginForm();
  }
}
  • This is considered a "lonely if" by ESLint.
  • The else block only has a single if statement for checking isRememberedUser().

Refactored code (Using else if)

if (isLoggedIn) {
  showWelcomeMessage();
} else if (isRememberedUser()) {
  prefillLoginForm();
}
  • This clarifies that the prefillLoginForm function is only called if isLoggedIn is false and isRememberedUser is true.
  • We use else if to combine the logic.

Another example (Lonely if in if block)

if (isValidInput()) {
  if (hasSpecialChars()) {
    showWarning();
  }
  // Further processing
}
if (isValidInput()) {
  if (hasSpecialChars()) {
    showWarning();
  }
  // Further processing
}
  • Here, we keep the nested if structure for clarity as it emphasizes that the warning is only shown if the input is valid and has special characters.
  • This example uses a lonely if within the main if block. While ESLint might not flag this specific case by default, some ESLint plugin extensions can catch it.


  1. Combine with a Ternary Operator (Simple cases)
    In very specific instances, you could use a ternary operator to combine the logic within the else block. However, this can make the code less readable for complex conditions. This is generally not recommended for most cases.

Example (Using Ternary Operator)

const message = isLoggedIn ? 'Welcome!' : (isRememberedUser() ? 'Pre-filled login' : '');
  1. Extract logic into functions
    If the lonely if involves complex logic, consider extracting that logic into a separate function. This can improve code organization and readability.

Example (Extracting Logic)

function handleNonLoggedInCase() {
  if (isRememberedUser()) {
    prefillLoginForm();
  }
}

if (isLoggedIn) {
  showWelcomeMessage();
} else {
  handleNonLoggedInCase();
}

Ultimately, the best approach depends on the specific situation and your coding style preferences.

Here are some additional points to consider:

  • Team preferences
    If you're working on a project with a coding style guide, follow the established conventions for handling if statements.
  • Complexity
    For simple conditions, a lonely if might be acceptable. As complexity increases, consider refactoring using else if or other techniques.
  • Readability
    The primary goal is to write code that's easy to understand for you and other developers. Choose the structure that makes the logic most clear.