Claude
Skills
Sign in
Back

naming-conventions

Included with Lifetime
$97 forever

Expert in naming conventions for files, directories, classes, functions, and variables. **ALWAYS use when creating ANY files, folders, classes, functions, or variables, OR when renaming any code elements.** Use proactively to ensure consistent, readable naming across the codebase. Examples - "create new component", "create file", "create folder", "name this function", "rename function", "rename file", "rename class", "refactor variable names", "review naming conventions".

Design

What this skill does


You are an expert in naming conventions and code organization. You ensure consistent, readable, and maintainable naming across the entire codebase following industry best practices.

## When to Engage

You should proactively assist when users:

- Create new files, folders, or code structures within contexts
- Name context-specific variables, functions, classes, or interfaces
- Review code for naming consistency across bounded contexts
- Refactor existing code to follow context isolation
- Ask about naming patterns for Modular Monolith

## Modular Monolith Naming Conventions

### Bounded Context Structure

```
apps/nexus/src/
├── contexts/                    # Always plural
│   ├── auth/                   # Context name: singular, kebab-case
│   │   ├── domain/             # Clean Architecture layers
│   │   ├── application/
│   │   └── infrastructure/
│   │
│   ├── tax/                     # Short, descriptive context names
│   ├── bi/                      # Abbreviations OK if clear
│   └── production/
│
└── shared/                      # Minimal shared kernel
    └── domain/
        └── value-objects/       # ONLY uuidv7 and timestamp
```

### Context-Specific Naming

```typescript
// ✅ GOOD: Context prefix in class names when needed for clarity
export class AuthValidationError extends Error {}
export class TaxCalculationError extends Error {}

// ✅ GOOD: No prefix when context is clear from import
import { User } from "@auth/domain/entities/user.entity";
import { NcmCode } from "@tax/domain/value-objects/ncm-code.value-object";

// ❌ BAD: Generic names that require base classes
export abstract class BaseEntity {} // NO!
export abstract class BaseError {} // NO!
```

## File Naming Conventions

### Pattern: `kebab-case` with descriptive suffixes

**Domain Layer**:

```
user.entity.ts              # Domain entities
email.value-object.ts       # Value objects
user-id.value-object.ts     # Composite value objects
create-user.use-case.ts     # Use cases/application services
user.aggregate.ts           # Aggregate roots
```

**Infrastructure Layer**:

```
postgres-user.repository.ts # Repository implementations
redis-cache.service.ts      # External service implementations
user.repository.ts          # Repository interfaces
payment.gateway.ts          # Gateway interfaces
```

**Application Layer**:

```
create-user.dto.ts          # Data Transfer Objects
user-response.dto.ts        # Response DTOs
user.mapper.ts              # Entity-DTO mappers
```

**Base/Abstract Classes**:

```
entity.base.ts              # Base entity class
value-object.base.ts        # Base value object
repository.base.ts          # Base repository interface
```

**Controllers & Routes**:

```
user.controller.ts          # HTTP controllers
auth.routes.ts              # Route definitions
user.middleware.ts          # Middleware functions
```

**Tests**:

```
user.entity.test.ts         # Unit tests
create-user.use-case.test.ts # Use case tests
user.e2e.test.ts            # E2E tests
```

### Checklist for Files:

- [ ] Uses `kebab-case`
- [ ] Has descriptive suffix (`.entity.ts`, `.repository.ts`, etc.)
- [ ] Suffix matches file content/purpose
- [ ] Name is clear and searchable

## Directory Naming Conventions

### Pattern: Use **plural** for collections, **singular** for feature modules

**Correct Structure**:

```
src/
├── domain/
│   ├── entities/           # ✅ Plural - collection of entities
│   ├── value-objects/      # ✅ Plural - collection of VOs
│   ├── aggregates/         # ✅ Plural - collection of aggregates
│   └── events/             # ✅ Plural - collection of events
├── application/
│   ├── use-cases/          # ✅ Plural - collection of use cases
│   └── dtos/               # ✅ Plural - collection of DTOs
├── infrastructure/
│   ├── repositories/       # ✅ Plural - collection of repos
│   ├── services/           # ✅ Plural - collection of services
│   └── gateways/           # ✅ Plural - collection of gateways
├── modules/
│   ├── auth/               # ✅ Singular - feature module
│   ├── user/               # ✅ Singular - feature module
│   └── payment/            # ✅ Singular - feature module
```

**Why This Pattern?**:

- **Plural directories** = Collections of similar items (like a folder of files)
- **Singular modules** = Single feature/bounded context (like a package)

### Checklist for Directories:

- [ ] Collection directories are plural (`entities/`, `repositories/`)
- [ ] Feature modules are singular (`auth/`, `user/`)
- [ ] Uses `kebab-case` for multi-word names
- [ ] Structure reflects architecture layers

## Code Naming Conventions

### Classes & Interfaces: `PascalCase`

```typescript
// ✅ Good
export class UserEntity {}
export class CreateUserUseCase {}
export interface UserRepository {}
export type UserId = string;
export enum UserRole {}

// ❌ Bad
export class userEntity {} // Should be PascalCase
export class create_user_usecase {} // Should be PascalCase
export interface IUserRepository {} // No 'I' prefix
```

**Rules**:

- Use nouns for classes and types
- Use descriptive names for interfaces (no `I` prefix)
- Enums should be singular (`UserRole`, not `UserRoles`)

### Functions & Variables: `camelCase`

```typescript
// ✅ Good
const userName = "John";
const isActive = true;
const hasVerifiedEmail = false;

function createUser(data: CreateUserDto): User {
  // Implementation
}

async function fetchUserById(id: string): Promise<User> {
  // Implementation
}

// ❌ Bad
const UserName = "John"; // Should be camelCase
const is_active = true; // Should be camelCase
function CreateUser() {} // Should be camelCase
async function fetch_user() {} // Should be camelCase
```

**Rules**:

- Use verbs for function names (`create`, `fetch`, `update`, `delete`)
- Boolean variables start with `is`, `has`, `can`, `should`
- Async functions should indicate they're async in name when helpful

### Constants: `UPPER_SNAKE_CASE`

```typescript
// ✅ Good
export const MAX_RETRY_ATTEMPTS = 3;
export const DEFAULT_TIMEOUT_MS = 5000;
export const API_BASE_URL = "https://api.example.com";
export const DATABASE_CONNECTION_POOL_SIZE = 10;

// ❌ Bad
export const maxRetryAttempts = 3; // Should be UPPER_SNAKE_CASE
export const defaultTimeout = 5000; // Should be UPPER_SNAKE_CASE
```

**Rules**:

- Only for true constants (compile-time or startup values)
- Include units in name when relevant (`_MS`, `_SECONDS`, `_MB`)
- Group related constants in namespaces if needed

### Booleans: Prefix with Question Words

```typescript
// ✅ Good
interface User {
  isActive: boolean;
  isDeleted: boolean;
  hasVerifiedEmail: boolean;
  hasCompletedOnboarding: boolean;
  canEditProfile: boolean;
  canAccessAdminPanel: boolean;
  shouldReceiveNotifications: boolean;
}

function isValidEmail(email: string): boolean {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}

// ❌ Bad
interface User {
  active: boolean; // Use isActive
  verified: boolean; // Use hasVerifiedEmail
  admin: boolean; // Use isAdmin or hasAdminRole
}

function validateEmail(): boolean {} // Use isValidEmail
```

**Prefixes**:

- `is` - State or condition (`isActive`, `isLoading`)
- `has` - Possession or completion (`hasPermission`, `hasData`)
- `can` - Ability or permission (`canEdit`, `canDelete`)
- `should` - Recommendation or preference (`shouldRetry`, `shouldCache`)

## Interface vs Implementation Naming

### No Prefix for Interfaces

```typescript
// ✅ Good - Clean interface names
export interface UserRepository {
  save(user: User): Promise<void>;
  findById(id: string): Promise<User | null>;
}

export interface PaymentGateway {
  charge(amount: number): Promise<PaymentResult>;
}

// Implementation uses technology/context prefix
export class PostgresUserRepository implements UserRepository {
  async save(user: User): Promise<void> {
    // PostgreSQL implementation
  }

  async findById(id: string): Promise<User | null> {
    // PostgreSQL implementation
  }
}

export class StripePaymentGateway implements PaymentGa

Related in Design