Boolean Props
Using is, has, should, and other prefixes to make yes/no props obvious at a glance.
Loading state prop
interface ButtonProps {
text: string;
loading: boolean;
}interface ButtonProps {
text: string;
isLoading: boolean;
}The is prefix makes boolean props read as yes/no questions: "Is it loading?"
Some established libraries (MUI, HTML) use bare names like disabled — that's fine for well-known HTML attributes. But for custom props, the prefix removes ambiguity: is loading a boolean, an enum, or a string?
Visibility toggle
interface ModalProps {
children: React.ReactNode;
open: boolean;
close: () => void;
}interface ModalProps {
children: React.ReactNode;
isOpen: boolean;
onClose: () => void;
}isOpen makes the boolean explicit, and onClose follows the event callback convention.
Fun fact: MUI uses bare open for modals — that's fine for a well-known pattern. But close as an imperative verb is the real problem here: it should always be onClose to signal it's an event callback, not a command.
Opt-out boolean naming
interface ButtonProps {
children: React.ReactNode;
variant?: 'text' | 'outlined' | 'contained';
/** @default false */
noElevation?: boolean;
/** @default false */
noRipple?: boolean;
/** @default false */
noFocusRipple?: boolean;
}interface ButtonProps {
children: React.ReactNode;
variant?: 'text' | 'outlined' | 'contained';
/** @default false */
disableElevation?: boolean;
/** @default false */
disableRipple?: boolean;
/** @default false */
disableFocusRipple?: boolean;
}The disable* prefix is ideal for opt-out booleans: features that are on by default and can be turned off. <Button disableElevation /> reads as "disable the elevation" — clear and imperative. MUI uses this pattern across its entire library.
The key rule: boolean props should default to false so that the JSX shorthand <Button disableRipple /> means "true".
Intent-specific boolean prefixes
interface ModalProps {
children: React.ReactNode;
isOpen: boolean;
onClose: () => void;
/** Keep in DOM when closed. @default false */
isMounted?: boolean;
/** Hide the backdrop. @default false */
isBackdropHidden?: boolean;
/** Lock body scroll. @default true */
isScrollLocked?: boolean;
}interface ModalProps {
children: React.ReactNode;
isOpen: boolean;
onClose: () => void;
/** Keep children in the DOM when closed. @default false */
keepMounted?: boolean;
/** Hide the backdrop overlay. @default false */
hideBackdrop?: boolean;
/** Prevent body scroll when open. @default true */
disableScrollLock?: boolean;
}Different boolean intents deserve different prefixes: keep* means "preserve this behavior that would normally stop," hide* means "don't render this visual element," and disable* means "turn off this feature."
<Modal keepMounted hideBackdrop /> reads as clear instructions. MUI's Modal uses all three of these exact props.
Complex boolean props
interface NavigationProps {
items: NavItem[];
/**
* Whether the navigation is collapsed.
* @default false
*/
collapsed: boolean;
/**
* Whether to show icons.
* @default true
*/
icons: boolean;
/**
* Whether in mobile layout.
* @default false
*/
mobile: boolean;
}interface NavigationProps {
items: NavItem[];
/**
* Whether the navigation is in collapsed (icon-only) mode.
* @default false
*/
isCollapsed: boolean;
/**
* Whether to show icons alongside labels.
* @default true
*/
hasIcons: boolean;
/**
* Whether the component renders in mobile viewport layout.
* @default false
*/
isMobile: boolean;
}Three prefixes, three meanings: is for current state (isCollapsed), has for feature presence (hasIcons), and JSDoc @default so consumers know the baseline.
At the call site, <Navigation hasIcons isMobile /> reads like a sentence. Each prefix tells you the kind of boolean without reading the type.