DEV Community

Andriy Ovcharov
Andriy Ovcharov

Posted on

Naming Conventions in JavaScript (Classes, Components, Events, APIs)

knight with a sword

When you first look at this code, what do you think?

const x = fetch('/getData', { id: d });  
Enter fullscreen mode Exit fullscreen mode

Questions flood your mind:

  • What’s x? An array? An object?

  • Is d a user ID, a timestamp, or something else?

  • Why getData instead of user-profiles?

And indeed. What did the author want to write?

In a series of publications about naming in JavaScript, I will try to propose what I believe to be the correct approach to naming language entities.

Bad naming costs time. A study found developers spend 60% of their time reading code. Poor names make this even harder.

In this guide, we’ll focus on naming conventions for:

  • Classes & Components (UserService vs userService)

  • Events (onClick vs handleClick)

  • API Endpoints (/orders vs /getOrders)

  • Tests (describe('User') vs describe('Test User'))

// 👍 Clear  
class PaymentGateway {  
  processTransaction() { ... }  
}  

// 👎 Confusing  
class pg {  
  pt() { ... }  // "pt" = ?  
}  
Enter fullscreen mode Exit fullscreen mode

This isn’t just about style. It’s about:

  • Onboarding (new devs understand your code faster).

  • Maintainability (you’ll thank yourself later).

  • Communication (names should "document" the code).

In a series of publications, we will talk about:

  1. "Naming Conventions in JavaScript (Classes, Components, Events, APIs)"
  2. "JavaScript Variable Naming: Rules You Can’t Ignore"
  3. "How to Name Functions in JavaScript: A Practical Guide"

Ready to name like a pro? Let’s dive in!


📌 1. Class Names (PascalCase)
Classes should be nouns representing entities (objects, services, models) and always start with a capital letter and use PascalCase:

// 👍 Good  
class User { ... }  
class PaymentService { ... }  
class HttpClient { ... }  

// 👎 Bad  
class user { ... }       // Lowercase  
class makePayment { ... } // Verb (a class is not a function) 
Enter fullscreen mode Exit fullscreen mode

📌 2. Specificity instead of general terms in classes
Avoid names like Manager, Helper, Processor:

/* 👍 Good */  
class UserRepository {}  // Clear: works with user data 
class EmailValidator {}  // Specific goal 

/* 👎 Bad */  
class DataManager {}     // What exactly is "managing"?  
class ApiHelper {}       // Too vague
Enter fullscreen mode Exit fullscreen mode

📌 3. Components (React/Vue/Svelte)
Component names use PascalCase, like classes:

// 👍 Good  
function UserProfile() { ... }  
class CartItem extends React.Component { ... }  

// 👎 Bad  
function userProfile() { ... } // camelCase for components is confusing  
Enter fullscreen mode Exit fullscreen mode

📌 4. Events (Event Naming)

  • Handlers: on{Event} (e.g., onClick).

  • Custom events: kebab-case (e.g., user-registered).

// 👍 Good  
button.addEventListener('click', onClick);  
emitter.emit('user-registered', data);  

// 👎 Bad  
button.addEventListener('click', handleClick); // Non-standard prefix  
emitter.emit('userRegistered', data); // camelCase for events is non-standard  
Enter fullscreen mode Exit fullscreen mode

📌 5. API Endpoints (kebab-case or snake_case)

// 👍 Good  
fetch('/api/user-profiles/123');  
fetch('/api/orders?status=completed');  

// 👎 Bad  
fetch('/api/getUserProfile/123'); // Redundant verbs  
fetch('/api/userProfiles');       // camelCase in URLs  
Enter fullscreen mode Exit fullscreen mode

📌 6. Tests (describe/it Style)
Test names should describe what is being tested:

// 👍 Good  
describe('UserService', () => {  
  it('should create a new user', () => { ... });  
});  

// 👎 Bad  
describe('Test User', () => {  // Vague  
  it('test #1', () => { ... }); // Meaningless  
});  
Enter fullscreen mode Exit fullscreen mode

📌 7. Imports (Readability & Context)
Module names should reflect their purpose:

// 👍 Good  
import UserService from './services/UserService'; // Service  
import { formatDate } from './utils/date';       // Utility  

// 👎 Bad  
import Service from './Service';    // Too generic  
import foo from './helpers/foo';    // Unclear  
Enter fullscreen mode Exit fullscreen mode

📌 8. Configuration Files (env, config)

// 👍 Good (clear prefixes)  
const DB_HOST = 'localhost';  
const MAX_UPLOAD_SIZE_MB = 10;  

// 👎 Bad  
const host = 'localhost'; // No context  
const maxSize = 10;       // Units unclear  
Enter fullscreen mode Exit fullscreen mode

📌 9. Types (TypeScript)

  • Interfaces: PascalCase + I (if project convention).

  • Union types: Descriptive names.

// 👍 Good  
interface IUser { ... }  
type PaymentStatus = 'pending' | 'completed';  

// 👎 Bad  
interface user { ... }  
type status = 'pending' | 'completed';  
Enter fullscreen mode Exit fullscreen mode

📌 10. Async Operations (Prefixes: fetch, load, sync)

// 👍 Good  
async function fetchPosts() { ... }  
const isLoading = false;  

// 👎 Bad  
async function getData() { ... }  // Unclear if HTTP request  
const loading = false;            // Could be component state  
Enter fullscreen mode Exit fullscreen mode

Key Takeaways: Where Else Is Naming Important?

  • State management (Redux, Pinia): userSlice, useCartStore.

  • Error classes: ValidationError, NetworkError.

  • Project files: user.controller.js, date.utils.js.

  • Git commits: feat: add user login, fix: button click handler.

💰 Golden Rule:
A name should reflect what it is and where it’s used.


Read more:

"JavaScript Variable Naming: Rules You Can’t Ignore" (second part)
"How to Name Functions in JavaScript: A Practical Guide" (third part)

Top comments (0)