Yevhen Klymentiev
dark
light
console
darkness
y.klymentiev@gmail.com
Coding Standards|Rules, conventions, and best practices I follow and recommend to teams

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 regular curr, btn, posX):

    JavaScript
    Copied!
    1const usrInf = {};
    2const unrMsgs = [];
    JavaScript
    Copied!
    1const userInfo = {};
    2const unreadMessages = [];
  • Avoid context duplication:

    JavaScript
    Copied!
    1userService.getUserList()
    2productCard.cardImage
    JavaScript
    Copied!
    1userService.getList()
    2productCard.image
  • Consistent naming across layers (type → controller → service → DB → API):

    TypeScript
    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:

    JavaScript
    Copied!
    function processData() {};
    JavaScript
    Copied!
    1function normalizeUserList() {};
    2function calculateDiscount() {};
  • Use map* / reduce* / filter* in higher-order function names:

    JavaScript
    Copied!
    1filterVisibleItems();
    2mapUsersToOptions();
    3reduceToSum();
  • Use nouns for data, verbs for actions:

    JavaScript
    Copied!
    const getUser = { id: 1 };
    JavaScript
    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:

    JavaScript
    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
    JavaScript
    Copied!
    1// Consistent plural form
    2users, products, comments
  • Avoid using implementation details in names:

    JavaScript
    Copied!
    1fetchUserFromAPI();
    2storeDataInRedux();
    JavaScript
    Copied!
    1fetchUser();
    2storeUserData();
  • Prefer terms with clear domain meaning:

    JavaScript
    Copied!
    1validateInput();
    2checkThing();
    JavaScript
    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 vs get)

    • 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)

    JavaScript
    Copied!
    1// async function
    2async function getUser() {
    3const res = await fetch('/api/user');
    4  return await res.json();
    5};
    JavaScript
    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() {};
    JavaScript
    Copied!
    1async function loadProductList() {};
    2async function fetchUser() {};
    3async function syncInventory() {};
    4async function submitOrder();
  • Disambiguate variable names in nested scopes:

    JavaScript
    Copied!
    1teams.forEach((team) => {
    2  team.members.forEach((team) => { ... });
    3});
    JavaScript
    Copied!
    1teams.forEach((team) => {
    2  team.members.forEach((member) => { ... });
    3});
  • Semantic prefixes for booleans: is, has, can, should, was, needs

    JavaScript
    Copied!
    isAdmin, hasChildren, canDelete, shouldUpdate
  • Event handler naming conventions:

    JavaScript
    Copied!
    1// on + event name
    2onSubmit, onClick, onLogout
    3
    4// handle + action
    5handleSubmit, handleLogout
  • Consistent suffixes for types:

    • DTO – Data Transfer Object

    • Input / Payload – input types

    • Response – response shapes

    • Props – for components

    • Config – for configuration objects

    • Options – for optional settings

    JavaScript
    Copied!
    1type LoginPayload = { email: string; password: string }
    2type ProductResponse = { title: string }
    3type AuthConfig = { strategy: 'jwt' | 'oauth' }
  • Avoid premature abstraction naming:

    JavaScript
    Copied!
    1utils.js
    2helpers.ts
    3manager.js
    4service.ts
    5handler.ts
    JavaScript
    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

    JavaScript
    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

    JavaScript
    Copied!
    function handleClick() {};
    JavaScript
    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):

JavaScript
Copied!
1// Redundant plural ("users" + "List")
2const usersList = [...];
JavaScript
Copied!
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

JavaScript
Copied!
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:

    JavaScript
    Copied!
    1// components/user-card.tsx
    2function FancyItem(props) {
    3  ...
    4}
    5
    6export default FancyItem;
    JavaScript
    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

Constants

Use UPPER_SNAKE_CASE:

JavaScript
Copied!
const MAX_ATTEMPTS = 3;

CSS / SASS / classNames

  • Follow BEM:

    HTML
    Copied!
    <div class="user-card__avatar user-card__avatar--large"></div>
  • With CSS Modules: use camelCase class names

    JSX
    Copied!
    <div class={styles["user-card__avatar"]}></div>
    JSX
    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

TypeScript
Copied!
1type ProductId = string;
2type ApiResponse<T> = { data: T; error?: string };

Interfaces

  • Use PascalCase

  • Avoid prefixing with I (like IUser) — legacy from C#

TypeScript
Copied!
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

TypeScript
Copied!
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

TypeScript
Copied!
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 clarity

  • Function names should reflect the check’s intent

TypeScript
Copied!
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

TypeScript
Copied!
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()

TypeScript
Copied!
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.).

File
Copied!
1POST /createUser
2GET /getUserById?id=123
File
Copied!
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

Styleguide: Naming | Yevhen Klymentiev