Why Naming Matters
Without Conventions
- Button.tsx
- loginBtn.tsx
- SubmitBTN.tsx
- cta-button.tsx
Nobody can find anything. Imports break. Autocomplete fails.
With Buoy
- Button.tsx
- LoginButton.tsx
- SubmitButton.tsx
- CtaButton.tsx
Predictable, searchable, and consistent everywhere.
See it in action
buoy-cli
$
âš“ Checking naming conventions...
âš Found 5 naming inconsistencies
Components:
⚠LoginBtn.tsx → Expected: LoginButton.tsx
⚠userCard.tsx → Expected: UserCard.tsx
Tokens:
⚠--primary-clr → Expected: --color-primary
⚠--txtColor → Expected: --color-text
Props:
âš isDisabled vs disabled (inconsistent across 12 components)
What We Check
Components
- • PascalCase file names (Button.tsx, not button.tsx)
- • Match file name to default export
- • Suffix patterns (Button, ButtonGroup, ButtonIcon)
Tokens
- • Consistent prefix (--color-*, --spacing-*, --font-*)
- • kebab-case naming
- • Semantic names (--color-primary, not --blue-500)
Props
- • Boolean props: is*, has*, should* prefix
- • Handler props: on* prefix
- • Consistent across similar components
Files & Folders
- • components/ for shared components
- • features/ for feature-specific code
- • Consistent index exports
Customize Your Conventions
buoy.config.mjs
export default {
naming: {
components: {
// File naming
fileCase: 'PascalCase', // PascalCase, camelCase, kebab-case
matchExport: true, // File name must match default export
// Suffixes
requiredSuffixes: {
'Button': ['Button', 'Btn'], // Allow both
'Icon': ['Icon'],
},
},
tokens: {
prefix: '--ds-', // Token prefix
categories: ['color', 'spacing', 'font', 'radius', 'shadow'],
casing: 'kebab-case',
},
props: {
booleans: 'is*', // isDisabled, isLoading
handlers: 'on*', // onClick, onChange
refs: '*Ref', // buttonRef, inputRef
}
}
}