ESLint InterlaceESLint Interlace
Plugin: modularityRules

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

AspectDetails
SeverityWarning (code quality)
Auto-Fix✅ Yes (auto-renames to domain terms)
CategoryModularity
ESLint MCP✅ Optimized for ESLint MCP integration
Best ForDomain-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

OptionTypeDefaultDescription
domainstring'general'Domain name for context
termsDomainTerm[][]List of domain-specific terms
glossaryUrlstringundefinedURL to full business glossary (optional)

DomainTerm Object

PropertyTypeRequiredDescription
incorrectstring | RegExpYesIncorrect term or pattern to match
correctstringYesCorrect domain term to use
contextstringYesBusiness context explaining the term
examplesstring[]NoExample 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

IssueImpactSolution
🗣️ CommunicationTeams use different terms for same conceptEnforce ubiquitous language
📚 DocumentationDocs don't match code terminologyLink to business glossary
🆕 OnboardingNew devs confused by inconsistent namingAuto-fix to correct terms
🔄 RefactoringHard to search/replace inconsistent namesConsistent naming throughout
🎯 Domain ClarityCode doesn't reflect business modelDDD-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/glossary

Comparison with Alternatives

Featureenforce-namingeslint-plugin-naming-conventioncustom 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

Best Practices

  1. Start small: Begin with the most confusing terms
  2. Involve domain experts: Get input from business stakeholders
  3. Document context: Always provide clear business reasoning
  4. Use examples: Show concrete usage examples
  5. Link to glossary: Maintain a central glossary document
  6. Gradual adoption: Start with warnings, move to errors over time

Further Reading

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 tracked

Mitigation: 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 tracked

Mitigation: Ensure imported values follow the same constraints. Use TypeScript for type safety.

On this page

No Headings