Boolean Naming Should Not Start With "is

In the realm of software engineering, naming is far more than a mere stylistic choice; it is a fundamental discipline of self-documenting code. Well-chosen names reduce cognitive load, minimize maintenance costs, and clarify intent. However, a common reflex among developers is to prefix every Boolean variable with is—resulting in names like isClosed, isAvailable, or isEnabled.

While this convention is deeply ingrained in many programming cultures, modern software engineering, API design, and framework standards are increasingly moving toward a more streamlined approach: avoiding the is prefix for Boolean properties. This article explores why this shift is occurring and how you can implement more elegant naming conventions.
Before adopting a new pattern, it is essential to understand why the traditional is prefix can sometimes become a liability rather than a help.

1. Semantic Ambiguity: Property vs. Method

In Object-Oriented Programming (OOP), the prefix is often signals a query or an action—a method that performs a check and returns a result (e.g., isEmpty()). When is is used as a property name in a data class, it can create confusion. Furthermore, many frameworks use reflection to generate Getters and Setters. A property named isDeleted might lead to a generated method named getIsDeleted() or simply isDeleted(), creating naming collisions or awkward API surfaces that are difficult to navigate.

2. Redundancy and Verbosity

Modern type systems are highly expressive. When a variable is explicitly typed as a boolean, its nature as a truthy/falsy value is already established. Adding is often adds "noise" without adding "signal." For instance, in a configuration object, enabled: true is more concise and direct than isEnabled: true. The extra characters provide no additional semantic value but increase the verbosity of the codebase.

3. The Serialization Nightmare

One of the most practical reasons to avoid the is prefix is the friction it creates during serialization and deserialization. Popular libraries like Jackson (Java) or Gson often follow specific conventions when mapping object properties to JSON.

A property named isDeleted might be serialized into JSON as "deleted" or "isDeleted", depending on the library's configuration and the presence of a getter. This inconsistency frequently leads to bugs in cross-platform communication, where a backend service sends deleted: true but the frontend expects isDeleted: true. By naming the property directly (e.g., deleted), you ensure a predictable, one-to-one mapping between your code and your data interchange format.

The Core Principle: Direct State Representation

The goal of modern Boolean naming is to express a state or a characteristic directly. Instead of asking a question (which is what is does), you should describe the attribute itself.

There are three primary ways to achieve this:

  • Use Adjectives: Describe the current characteristic of the object.
    • Use active instead of isActive.
    • Use valid instead of isValid.
    • Use visible instead of isVisible.
  • Use Past Participles: Describe a state resulting from a completed action.
    • Use completed instead of isCompleted.
    • Use connected instead of isConnected.
    • Use loaded instead of isLoaded.
  • Use Nouns or Noun Phrases: Ideal for representing flags, roles, or permissions.
    • Use admin instead of isAdmin.
    • Use success instead of isSuccess.

Comparative Analysis

Let’s look at how this looks in practice, specifically within a TypeScript context, which is common in modern web development.

The Traditional Approach (Verbose)

// Example: Using the 'is' prefix for properties
interface UserConfig {
  isEnabled: boolean;
  isAdmin: boolean;
  isLoggedIn: boolean;
}

const config: UserConfig = {
  isEnabled: true,
  isAdmin: false,
  isLoggedIn: true
};

// Usage feels slightly repetitive
if (config.isLoggedIn) {
  console.log("User is logged in.");
}

In large-scale systems, this approach often requires manual mapping layers to ensure that the JSON sent over the wire matches the expected field names in the frontend.

// Example: Direct state naming
interface UserConfig {
  enabled: boolean;
  admin: boolean;
  loggedIn: boolean;
}

const config: UserConfig = {
  enabled: true,
  admin: false,
  loggedIn: true
};

// Usage is clean and reads like natural language
if (config.loggedIn) {
  console.log("User is logged in.");
}

The second approach is cleaner, more predictable for serialization, and aligns better with the way modern APIs are structured.

The Exception: When is is Still King

It is important to note that "avoiding is" is not a universal law for all code. The distinction lies in Data vs. Behavior.

The rule against is primarily applies to variables, object properties, DTO (Data Transfer Object) fields, and state flags. These represent what something is.

However, for methods and functions that perform a logical check, using is, has, can, or should remains the industry standard. These prefixes clearly signal that a computation or a logic check is being performed.

  • isValid(): A method that validates an input.
  • hasPermission(): A function that checks a user's rights.
  • canEdit(): A logic gate determining if an action is allowed.
  • shouldRetry(): A function determining the next step in a workflow.

By reserving is for behavioral methods, you create a clear distinction in your codebase: properties are static data, while is-prefixed methods are active logic.

Conclusion

Moving away from the is prefix for Boolean properties is not about following a trend; it is about embracing clarity, reducing redundancy, and preventing technical friction in serialization. By shifting your focus toward direct state representation—using adjectives and past participles—you produce code that is more concise and easier to maintain.

Next time you find yourself typing is before a Boolean property, pause and ask: "Does this add value, or is it just noise?" Often, the most elegant solution is the simplest one.