home / skills / phrazzld / claude-config / naming-conventions
This skill helps you apply universal naming principles to create intention-revealing, domain-focused names in Python code.
npx playbooks add skill phrazzld/claude-config --skill naming-conventionsReview the files below or copy the command above to add this skill to your agents.
---
name: naming-conventions
user-invocable: false
description: "Apply universal naming principles: avoid Manager/Helper/Util, use intention-revealing names, domain language, verb+noun functions. Use when naming variables, functions, classes, reviewing names, or refactoring for clarity. Language-agnostic principles."
allowed-tools:
- Read
- Grep
effort: low
---
# Naming Conventions
Universal principles for clear, intention-revealing names. Language-agnostic—applies to TypeScript, Go, Rust, Python, etc.
## Core Principle
**Names should reveal intent and domain, not implementation.**
- `users` not `userArray` (domain, not data structure)
- `calculateTax` not `doTaxCalculation` (clear verb)
- `PaymentProcessor` not `PaymentManager` (specific action, not vague)
---
## Prohibited Patterns
### NEVER Use These Names
❌ **Manager, Helper, Util**
These are Ousterhout red flags — they're vague and don't reveal what the code does.
**Bad:**
```
UserManager
PaymentHelper
StringUtil
```
**Good:**
```
UserAuthenticator
PaymentProcessor
StringFormatter
```
**Why:** Naming forces design thinking. If you can't name it specifically, you don't understand what it does.
### RARELY Use (Context-Dependent)
⚠️ **Service, Handler, Processor, Controller**
These can work when they're domain-specific or framework patterns, but prefer more specific names.
**Bad (vague):**
```
DataService // What kind of data?
RequestHandler // What kind of request?
```
**Better (specific):**
```
OrderService // Domain context: orders
HttpRequestHandler // Framework pattern: HTTP requests
PaymentProcessor // Domain action: processing payments
```
### SOMETIMES Acceptable
⚠️ **Base, Abstract (prefixes)**
Valid for framework/library code, but often hide intent in application code.
**Framework (acceptable):**
```typescript
abstract class BaseComponent { ... }
abstract class AbstractRepository { ... }
```
**Application (avoid):**
```typescript
// Better to name by domain
class Component { ... } // If it's the base, no prefix needed
class Repository<T> { ... } // Generic is clear without prefix
```
### Always Avoid
❌ **Generic containers:** Manager, Helper, Util, Misc, Common
❌ **Temporal names:** step1, phase1, doFirst, doSecond
❌ **Single letters:** x, y, temp (except loop counters i, j, k)
❌ **Vague abbreviations:** usr, msg, ctx (except well-known: id, url, api, http)
---
## Positive Patterns
### Variables
**Pattern:** Descriptive nouns
**Use domain language, not implementation:**
```
✅ activeUsers // Domain concept
✅ totalRevenue // Clear business term
✅ selectedItems // What they are
❌ userArray // Implementation detail (array)
❌ rev // Abbreviation (unclear)
❌ items // Too vague (items of what?)
❌ data // Maximally vague
```
**Guidelines:**
- Descriptive, not abbreviated
- Domain terms, not data structures (users, not userArray)
- Context matters: `count` alone is vague, `activeUserCount` is clear
- Avoid single-letter names except loop counters (i, j, k)
### Functions
**Pattern:** Verb + noun
**Describe the action:**
```
✅ calculateTotal // Clear action + target
✅ fetchUserData // Action: fetch, target: user data
✅ isValidEmail // Question: is valid?
✅ formatCurrency // Transform: format
❌ total // Missing verb (noun alone)
❌ getUserData // Vague verb "get"
❌ validateEmail // Returns boolean, use "is"
❌ currency // Missing verb
❌ process // Vague verb, no target
```
**Guidelines:**
- Start with clear verb (calculate, fetch, format, validate, parse, send, save)
- Pure functions: describe transformation (format, parse, convert)
- Side effects: verb implies action (save, send, fetch, update, delete)
- Boolean returns: use question prefix (is, has, can, should)
- Avoid vague verbs: get, do, handle, manage, process (without context)
### Classes & Types
**Pattern:** Singular nouns
**Use domain concepts:**
```
✅ User // Domain entity
✅ PaymentProcessor // Action-specific
✅ OrderRepository // Pattern adds meaning
✅ EmailNotifier // Clear purpose
❌ Users // Plural (unless collection type)
❌ PaymentManager // Manager anti-pattern
❌ OrderDB // Implementation leak
❌ EmailHelper // Helper anti-pattern
```
**Guidelines:**
- Singular nouns (User, Order, Payment, not Users, Orders)
- Domain terms, not technical terms (Invoice, not BillingDocument)
- Pattern suffixes acceptable when they add meaning (Repository, Factory, Builder, Strategy)
- Avoid generic suffixes (Manager, Helper, Util, Handler without context)
### Booleans
**Pattern:** Question prefix (is/has/can/should/will)
**Prefix reveals boolean nature:**
```
✅ isActive // State question
✅ hasPermission // Possession question
✅ canEdit // Capability question
✅ shouldRefetch // Conditional question
✅ willExpire // Future state question
❌ active // Ambiguous (could be status string)
❌ permission // Looks like object
❌ editable // Unclear (adjective, not question)
❌ enabled // Past participle (prefer isEnabled)
```
**Prefix meanings:**
- **is**: State (isActive, isLoading, isValid, isEmpty)
- **has**: Possession (hasPermission, hasChildren, hasErrors)
- **can**: Capability (canEdit, canDelete, canSubmit)
- **should**: Conditional (shouldRefetch, shouldValidate)
- **will**: Future (willExpire, willRetry)
**Why questions work:** Boolean names should read like yes/no questions.
### Collections
**Pattern:** Plural indicates multiple items
**Use plural, avoid type suffixes:**
```
✅ users // Plural indicates collection
✅ selectedItems // What they are, plural
✅ errorMessages // Clear and plural
✅ userById // Keyed collection (by what)
❌ userList // Redundant type suffix
❌ userArray // Implementation leak
❌ userCollection // Redundant suffix
❌ item // Singular for plural collection
```
**Keyed collections (maps/dictionaries):**
```
✅ userById // By key type
✅ configByEnv // By environment
✅ productsByCategory // Grouped by category
❌ userMap // Type suffix redundant
❌ users // Unclear it's keyed (ambiguous)
```
---
## Context-Aware Exceptions
Some generic names have valid domain justification:
### Framework Patterns
✅ **When acceptable:**
- `EventManager` in event-driven system (but `EventBus` is better)
- `ApiService` wrapping external API (but `ApiClient` is clearer)
- `RequestHandler` in HTTP framework (framework convention)
- `BaseComponent` in UI framework (inheritance pattern)
**Still prefer specific names when possible.**
### Repository Pattern
✅ **Acceptable:**
```
UserRepository
OrderRepository
```
This is a well-known pattern. The suffix adds meaning.
### Factory Pattern
✅ **Acceptable:**
```
UserFactory
ComponentFactory
```
Pattern name clarifies purpose.
---
## Quick Reference
### Pattern Templates
**Variables:** Descriptive nouns
```
activeUsers, totalCount, selectedItem, currentPage
```
**Functions:** Verb + noun
```
calculateTotal, fetchUser, formatDate, parseJson
```
**Booleans:** Question prefix
```
isActive, hasPermission, canEdit, shouldRefetch
```
**Classes:** Singular noun (+ pattern if meaningful)
```
User, Order, PaymentProcessor, OrderRepository
```
**Collections:** Plural nouns
```
users, items, errors, messages
```
---
## Examples: Before & After
### Example 1: Vague to Clear
❌ **Before:**
```
class DataManager
processData(data)
getData()
```
✅ **After:**
```
class OrderProcessor
calculateOrderTotal(order)
fetchActiveOrders()
```
### Example 2: Implementation to Domain
❌ **Before:**
```
userArray = fetchFromDB()
dataList = parseJsonString(response)
```
✅ **After:**
```
users = fetchUsers()
orders = parseOrderResponse(response)
```
### Example 3: Temporal to Functional
❌ **Before:**
```
function step1(data)
function step2(data)
function step3(data)
```
✅ **After:**
```
function validateData(data)
function enrichData(data)
function persistData(data)
```
---
## Philosophy
**"If you can't name it, you don't understand it."**
Naming is thinking. Bad names indicate unclear thinking. Good names indicate clear understanding.
**Naming forces design decisions:**
- Can't name a class? Maybe it's doing too much.
- Name is vague (Manager/Helper)? Unclear responsibility.
- Name is long (UserAccountPaymentProcessorManager)? Poor abstraction.
**Use domain language:**
- Domain experts should understand your names
- Names should match business concepts
- Avoid technical jargon when domain terms exist
**Names are for humans, not compilers.**
Write names for the person who reads your code in 6 months. That person is future you.
This skill codifies universal naming principles to produce clear, intention-revealing names across languages. It teaches which patterns to prefer (verb+noun for functions, domain nouns for variables, question prefixes for booleans) and which names to avoid (Manager/Helper/Util, vague abbreviations, single-letter names). Use it to improve readability, reduce ambiguity, and force better design through naming.
The skill inspects names and recommends domain-focused alternatives, flags anti-patterns (Manager, Helper, Util, vague verbs, temporal names), and suggests context-aware exceptions for common design patterns like Repository or Factory. It favors descriptive nouns for variables, verb+noun for functions, singular domain types for classes, plural names for collections, and question prefixes for booleans. Recommendations are language-agnostic and practical for reviewing, refactoring, or naming new code.
When is it acceptable to use names like Service, Handler, or Processor?
Use them when they add domain or framework context (OrderService, HttpRequestHandler, PaymentProcessor); avoid them if they remain vague without a clear target.
What if a short name seems convenient in local scope?
Short names are fine in tiny, tightly scoped contexts (loop counters, very short lambdas), but prefer descriptive names when the variable crosses function boundaries or affects readability.