enforce-naming
ESLint rule documentation for enforce-naming
📡 Live from GitHub — This documentation is fetched directly from enforce-naming.md and cached for 6 hours.
Keywords: naming conventions, domain-driven design, DDD, ESLint rule, ubiquitous language, business glossary, code consistency, auto-fix, LLM-optimized, code quality
Enforce domain-specific naming conventions with business context
Enforce domain-specific naming conventions with business context. This rule is part of eslint-plugin-modularity and provides LLM-optimized error messages with fix suggestions.
💡 Provides suggestions | 🔧 Automatically fixable
Quick Summary
| Aspect | Details |
|---|---|
| Severity | Warning (code quality) |
| Auto-Fix | ✅ Yes (auto-renames to domain terms) |
| Category | Modularity |
| ESLint MCP | ✅ Optimized for ESLint MCP integration |
| Best For | Domain-driven design projects, teams with business glossaries |
Rule Details
Helps maintain consistent domain-specific terminology across your codebase. Perfect for ensuring your code matches your ubiquitous language and business glossary.
Configuration
| Option | Type | Default | Description |
|---|---|---|---|
domain | string | 'general' | Domain name for context |
terms | DomainTerm[] | [] | List of domain-specific terms |
glossaryUrl | string | undefined | URL to full business glossary (optional) |
DomainTerm Object
| Property | Type | Required | Description |
|---|---|---|---|
incorrect | string | RegExp | Yes | Incorrect term or pattern to match |
correct | string | Yes | Correct domain term to use |
context | string | Yes | Business context explaining the term |
examples | string[] | No | Example usages |
Examples
❌ Incorrect
// E-commerce domain with wrong terminology
class UserOrder {
items: Product[];
buyer: Customer;
calculatePrice() {
return this.items.reduce((sum, item) => sum + item.cost, 0);
}
}✅ Correct
// E-commerce domain with correct terminology
class CustomerOrder {
lineItems: Product[];
customer: Customer;
calculateTotal() {
return this.lineItems.reduce((sum, item) => sum + item.price, 0);
}
}Configuration Examples
E-Commerce Domain
{
rules: {
'architecture/enforce-naming': ['error', {
domain: 'e-commerce',
glossaryUrl: 'https://wiki.company.com/glossary',
terms: [
{
incorrect: 'user',
correct: 'customer',
context: 'In e-commerce, users who make purchases are called customers',
examples: ['CustomerOrder', 'customerProfile', 'getCustomerById']
},
{
incorrect: /price|cost/i,
correct: 'total',
context: 'Final amount paid by customer is called total (not price or cost)',
examples: ['calculateTotal', 'orderTotal', 'getTotalAmount']
},
{
incorrect: 'items',
correct: 'lineItems',
context: 'Items in an order are formally called line items',
examples: ['orderLineItems', 'addLineItem', 'removeLineItem']
}
]
}]
}
}Financial Domain
{
rules: {
'architecture/enforce-naming': ['error', {
domain: 'finance',
glossaryUrl: 'https://internal.bank.com/glossary',
terms: [
{
incorrect: 'money',
correct: 'amount',
context: 'Use "amount" for monetary values in financial systems',
examples: ['transactionAmount', 'balanceAmount', 'getAmount']
},
{
incorrect: 'transfer',
correct: 'transaction',
context: 'All money movements are transactions, not transfers',
examples: ['createTransaction', 'TransactionHistory']
},
{
incorrect: 'account',
correct: 'bankAccount',
context: 'Be explicit: use "bankAccount" not just "account"',
examples: ['BankAccount', 'savingsBankAccount']
}
]
}]
}
}Healthcare Domain (HIPAA Compliant)
{
rules: {
'architecture/enforce-naming': ['error', {
domain: 'healthcare',
glossaryUrl: 'https://hipaa.health.gov/glossary',
terms: [
{
incorrect: 'patient',
correct: 'subject',
context: 'In clinical trials, participants are called subjects',
examples: ['SubjectRecord', 'enrollSubject', 'subjectConsent']
},
{
incorrect: 'doctor',
correct: 'provider',
context: 'Use "provider" for all healthcare professionals',
examples: ['ProviderCredentials', 'assignProvider']
},
{
incorrect: /medical.?record/i,
correct: 'healthRecord',
context: 'PHI should be referred to as health records',
examples: ['HealthRecord', 'accessHealthRecord']
}
]
}]
}
}Domain-Driven Design Example
{
rules: {
'architecture/enforce-naming': ['error', {
domain: 'shipping',
terms: [
{
incorrect: 'package',
correct: 'shipment',
context: 'Bounded context uses "shipment" for the aggregate root',
examples: ['Shipment', 'createShipment', 'trackShipment']
},
{
incorrect: 'destination',
correct: 'deliveryAddress',
context: 'Specific term for where shipment is delivered',
examples: ['shipment.deliveryAddress', 'updateDeliveryAddress']
},
{
incorrect: 'sender',
correct: 'shipper',
context: 'Entity that sends the shipment is the shipper',
examples: ['Shipper', 'shipperInformation']
}
]
}]
}
}Use Cases
1. Ubiquitous Language (DDD)
// ❌ Generic terms that don't match domain language
class User {
makePayment(amount: number) {
// ...
}
}
// ✅ Domain-specific terms from bounded context
class Subscriber {
paySubscription(fee: number) {
// ...
}
}2. Onboarding New Developers
// ❌ Confusing terminology for new team members
function processCart(order: any) {
const total = order.items.reduce((sum: number, x: any) => sum + x.cost, 0);
return total;
}
// ✅ Clear domain terms with business glossary backing
function calculateOrderTotal(order: Order) {
const total = order.lineItems.reduce((sum: number, item: LineItem) => sum + item.price, 0);
return total;
}3. Cross-Team Communication
// ❌ Team A calls it "client", Team B calls it "customer"
// ❌ Team C calls it "user" - confusion!
// ✅ Enforce consistent term across all teams
// Configuration ensures everyone uses "customer"Why This Matters
| Issue | Impact | Solution |
|---|---|---|
| 🗣️ Communication | Teams use different terms for same concept | Enforce ubiquitous language |
| 📚 Documentation | Docs don't match code terminology | Link to business glossary |
| 🆕 Onboarding | New devs confused by inconsistent naming | Auto-fix to correct terms |
| 🔄 Refactoring | Hard to search/replace inconsistent names | Consistent naming throughout |
| 🎯 Domain Clarity | Code doesn't reflect business model | DDD-aligned terminology |
Pattern Matching with RegExp
{
rules: {
'architecture/enforce-naming': ['error', {
domain: 'e-commerce',
terms: [
{
// Match variations: userId, user_id, UserID, etc.
incorrect: /user[_-]?id/i,
correct: 'customerId',
context: 'Use customerId for customer identifiers'
},
{
// Match: getPrice, setPrice, price, pricing, etc.
incorrect: /pric(e|ing)/i,
correct: 'total',
context: 'Use "total" for final amounts'
}
]
}]
}
}Integration with Business Glossary
When glossaryUrl is provided, the rule messages include a link to your business glossary:
📚 Use domain term "customer" instead of "user" | Domain: e-commerce
📖 View domain glossary: https://wiki.company.com/glossaryComparison with Alternatives
| Feature | enforce-naming | eslint-plugin-naming-convention | custom rules |
|---|---|---|---|
| Domain-Specific | ✅ Yes | ❌ No | ⚠️ Manual |
| Business Context | ✅ Yes | ❌ No | ❌ No |
| Auto-Fix | ✅ Yes | ⚠️ Limited | ❌ No |
| LLM-Optimized | ✅ Yes | ❌ No | ❌ No |
| ESLint MCP | ✅ Optimized | ❌ No | ❌ No |
| Glossary Integration | ✅ Yes | ❌ No | ❌ No |
Related Rules
no-deprecated-api- Enforces API naming migrationsno-internal-modules- Enforces module boundaries
Best Practices
- Start small: Begin with the most confusing terms
- Involve domain experts: Get input from business stakeholders
- Document context: Always provide clear business reasoning
- Use examples: Show concrete usage examples
- Link to glossary: Maintain a central glossary document
- Gradual adoption: Start with warnings, move to errors over time
Further Reading
- Ubiquitous Language - Martin Fowler - Ubiquitous language concept
- Domain-Driven Design - Eric Evans - DDD methodology
- Bounded Context - Bounded context pattern
- ESLint MCP Setup - Enable AI assistant integration
Known False Negatives
The following patterns are not detected due to static analysis limitations:
Dynamic Variable References
Why: Static analysis cannot trace values stored in variables or passed through function parameters.
// ❌ NOT DETECTED - Value from variable
const value = externalSource();
processValue(value); // Variable origin not trackedMitigation: Implement runtime validation and review code manually. Consider using TypeScript branded types for validated inputs.
Imported Values
Why: When values come from imports, the rule cannot analyze their origin or construction.
// ❌ NOT DETECTED - Value from import
import { getValue } from './helpers';
processValue(getValue()); // Cross-file not trackedMitigation: Ensure imported values follow the same constraints. Use TypeScript for type safety.