Naming
Naming is the primary way developers communicate through code. Good names make code self-documenting, reduce the need for comments, and make refactoring safer and easier.
General principles
Use descriptive, meaningful names:
userList
,isAdmin
,fetchPosts
(Should convey intent clearly)Avoid abbreviations (except for common terms like
id
,URL
,API
or regularcurr
,btn
,posX
):Copied!1const usrInf = {}; 2const unrMsgs = [];
Copied!1const userInfo = {}; 2const unreadMessages = [];
Avoid context duplication:
Copied!1userService.getUserList() 2productCard.cardImage
Copied!1userService.getList() 2productCard.image
Consistent naming across layers (type → controller → service → DB → API):
Copied!1// Frontend 2type Product = { id: number; title: string }; 3 4// API (DTO) 5POST /products → { title: "..." } 6 7// Backend model/service 8createProduct({ title }: CreateProductDTO) { ... }
Avoid vague names in shared utilities:
Copied!function processData() {};
Copied!1function normalizeUserList() {}; 2function calculateDiscount() {};
Use
map*
/reduce*
/filter*
in higher-order function names:Copied!1filterVisibleItems(); 2mapUsersToOptions(); 3reduceToSum();
Use nouns for data, verbs for actions:
Copied!const getUser = { id: 1 };
Copied!1const user = { id: 1 }; 2const getUser = () => fetch('/api/user');
Use consistent pluralization. Avoid mixing pluralization styles for collections (list/array/set) — pick one style and use it consistently across similar structures:
Copied!1/* 2 Inconsistent plural naming styles: 3 users → plural noun 4 productList → indicates the structure (list) 5 commentArray → indicates the data type (array) 6*/ 7users, productList, commentArray
Copied!1// Consistent plural form 2users, products, comments
Avoid using implementation details in names:
Copied!1fetchUserFromAPI(); 2storeDataInRedux();
Copied!1fetchUser(); 2storeUserData();
Prefer terms with clear domain meaning:
Copied!1validateInput(); 2checkThing();
Copied!1validateUserCredentials(); 2checkCartTotalLimit();
Use action/result naming for async.
Even if a function name starts with a verb, you can still violate the principle of clear async naming if:
The name doesn't indicate how or from where the data is retrieved (e.g.
fetch
vsget
)The verb is too vague or abstract (
handle
,process
,run
, etc.)The name gives the impression the function is synchronous (
getUser
for an async operation)
Copied!1// async function 2async function getUser() { 3const res = await fetch('/api/user'); 4 return await res.json(); 5};
Copied!1/* 2 "process" is abstract and doesn't communicate: 3 - What exactly is being done? 4 - What resource is being processed? 5 - Is asynchronous behavior expected? 6*/ 7async function process() {};
Copied!1async function loadProductList() {}; 2async function fetchUser() {}; 3async function syncInventory() {}; 4async function submitOrder();
Disambiguate variable names in nested scopes:
Copied!1teams.forEach((team) => { 2 team.members.forEach((team) => { ... }); 3});
Copied!1teams.forEach((team) => { 2 team.members.forEach((member) => { ... }); 3});
Semantic prefixes for booleans:
is
,has
,can
,should
,was
,needs
Copied!isAdmin, hasChildren, canDelete, shouldUpdate
Event handler naming conventions:
Copied!1// on + event name 2onSubmit, onClick, onLogout 3 4// handle + action 5handleSubmit, handleLogout
Consistent suffixes for types:
DTO
– Data Transfer ObjectInput
/Payload
– input typesResponse
– response shapesProps
– for componentsConfig
– for configuration objectsOptions
– for optional settings
Copied!1type LoginPayload = { email: string; password: string } 2type ProductResponse = { title: string } 3type AuthConfig = { strategy: 'jwt' | 'oauth' }
Avoid premature abstraction naming:
Copied!1utils.js 2helpers.ts 3manager.js 4service.ts 5handler.ts
Copied!1formatPrice.ts 2createUserService.ts 3validateAuthToken.ts 4handleUserLogin.ts
Variables
Should use nouns:
user
,settings
,items
Prefer camelCase:
userName
,isOpen
(Standard naming convention)Booleans should be prefix-based:
is
,has
,should
,can
,was
Copied!1const isLoggedIn = true; 2const hasError = false;
Functions
Start with verbs:
fetchUser()
,calculateTotal()
,isFormValid()
Use camelCase:
getUserInfo()
,openSettingsPopup()
(Standard naming convention)Avoid overly generic names
Copied!function handleClick() {};
Copied!function handleLoginClick() {};
Collections and plurals
When naming variables or properties that represent collections (arrays
, sets
, lists
, etc.), use a singular noun + collection suffix (e.g. userList
, productArray
, fileSet
) or a plain plural noun (e.g. users
, products
, comments
).
Avoid redundant or inconsistent pluralization like usersList
(or mixing styles such as productArray
, commentSet
, userList
in the same scope — see General Principles):
1// Redundant plural ("users" + "List")
2const usersList = [...];
1const userList = [...];
2const products = [...];
3const orderIds = [123, 456];
4const visibleUsers = [...];
Iterated entities
When iterating over collections (especially in array methods or loops), use the prefix curr
for the current item.
This clarifies what's being iterated — especially in nested loops or when variable names could be ambiguous.
Improves readability inside the loop body
Simplifies refactoring (you don’t need to rename the item every time you change the collection name)
Makes it clear that a variable is a single item, not a collection
Works well with short loop bodies —
curr
is often enough
1users.forEach((curr) => {
2 if (curr.isAdmin) {
3 // do something
4 }
5});
6
7cartItems.map((curr) => curr.price * curr.quantity);
8
9teams.forEach((currTeam) => {
10 currTeam.members.forEach((currMember) => {
11 // ...
12 });
13});
Files and folders
Use kebab-case:
user-card.tsx
,data-loader.ts
(Common convention in many codebases)Component file name = Component name:
Copied!1// components/user-card.tsx 2function FancyItem(props) { 3 ... 4} 5 6export default FancyItem;
Copied!1// components/user-card.tsx 2function UserCard(props) { 3 ... 4} 5 6export default UserCard;
React components
Use PascalCase:
UserCard
,LoginForm
(React convention)Reflect the purpose and context:
UserCard
,ProductTile
,ModalFooter
Conditional / HOC-style:
IfAuthorized
,WithLoading
,WhenEmpty
CSS / SASS / classNames
Follow BEM:
Copied!<div class="user-card__avatar user-card__avatar--large"></div>
With CSS Modules: use camelCase class names
Copied!<div class={styles["user-card__avatar"]}></div>
Copied!<div class={styles.userCardAvatar}></div>
Type aliases
Use PascalCase
Name should reflect the semantic purpose, not the implementation
Avoid generic names like
type Data = any
1type ProductId = string;
2type ApiResponse<T> = { data: T; error?: string };
Interfaces
Use PascalCase
Avoid prefixing with
I
(likeIUser
) — legacy from C#
1interface User {
2 id: string;
3 name: string;
4 isActive: boolean;
5}
Enums
Use PascalCase for the enum name
Use UPPER_SNAKE_CASE or PascalCase for string enums
Name should represent a singular concept
1enum Status {
2 IDLE,
3 LOADING,
4 SUCCESS,
5 ERROR
6}
7
8enum ButtonVariant {
9 Primary = 'primary',
10 Secondary = 'secondary'
11}
Generics
Use single letters (
T
,K
,V
,U
,R
, etc.)Use descriptive names when multiple generics are involved
1type ApiResponse<T> = { data: T; error?: string };
2type Dictionary<K extends string, V> = Record<K, V>;
Type guards / predicates
Use prefixes like
is
,has
,can
for clarityFunction names should reflect the check’s intent
1function isUser(obj: unknown): obj is User {
2 return typeof obj === 'object' && obj !== null && 'id' in obj;
3}
SQL tables and columns
Use snake_case for tables and columns
Plural nouns for tables:
users
,order_items
Column names:
id
,user_id
,created_at
1CREATE TABLE order_items (
2 id SERIAL PRIMARY KEY,
3 order_id INTEGER NOT NULL,
4 product_id INTEGER NOT NULL,
5 quantity INTEGER
6);
NoSQL collections
Use camelCase or snake_case consistently
Always use plural names:
users
,products
,activityLogs
Common fields:
createdAt
,updatedAt
Model definitions (ORM / ODM)
Use PascalCase for model names:
User
,OrderItem
Field names match DB convention: snake_case (SQL), camelCase (Mongo)
Method names reflect business logic:
getFullName()
,isActive()
1class OrderItem extends Model {
2 public id!: number;
3 public orderId!: number;
4 public productId!: number;
5 public quantity!: number;
6}
RESTful routes
Follow REST principles by using plural nouns for resources and HTTP methods to indicate actions. Avoid embedding verbs in the URL path — actions should be inferred from the method (GET, POST, etc.).
1POST /createUser
2GET /getUserById?id=123
1POST /users
2GET /users/123
Controllers
Name by action + entity:
getUserById()
,createProduct()
Or group by entity:
UserController.getById()
Services / business logic
Named by function or domain:
UserService
,AuthService
,OrderService
Method names reflect intent:
sendResetEmail()
,validatePassword()
,calculateTax()
Request-response DTOs / schemas
Use PascalCase:
LoginRequest
,CreateUserDTO
,ProductResponse
Property names: camelCase
Middleware / handlers
Functions: authMiddleware, validateBody, errorHandler
Use verb + target:
checkAuth
,parseUserAgent
,rateLimitHandler
Error handling
Class names: Use PascalCase with a clear intent:
UserNotFoundError
,DatabaseConnectionError
Error codes: Use UPPER_SNAKE_CASE format for internal codes/logging:
E_USER_NOT_FOUND
,E_DB_CONN_FAILED
Keep class and code names aligned to help with logging & debugging
Environment variables
Always use UPPER_SNAKE_CASE
Prefix with domain/service:
DB_HOST
,JWT_SECRET
,REDIS_URL
,S3_BUCKET_NAME