Coding Standards Language-specific coding conventions and best practices for maintainable software
Coding standards ensure consistency, readability, and maintainability across the codebase. Consistent code reduces cognitive load during reviews and makes onboarding easier for new team members.
Benefit Description Readability Consistent formatting makes code easier to understand Maintainability Standard patterns reduce complexity Quality Enforced standards catch errors early Collaboration Shared conventions reduce friction Compliance Required for regulated industries (FDA, SOX)
Element Convention Example Classes PascalCase UserAccount, PaymentProcessorFunctions camelCase or snake_case calculateTotal, validate_inputConstants UPPER_SNAKE_CASE MAX_RETRIES, DEFAULT_TIMEOUTVariables camelCase or snake_case userName, order_countBooleans Prefix with is/has/can isValid, hasPermission
// File naming: kebab-case
// user-service.ts, payment-processor.ts
// Interfaces: PascalCase with I prefix (optional)
interface UserProfile {
id : string ;
email : string ;
createdAt : Date ;
preferences ?: UserPreferences ;
}
// Type aliases for complex types
type UserId = string ;
type OrderStatus = 'pending' | 'confirmed' | 'shipped' | 'delivered' ;
// Functions: clear, descriptive names
async function fetchUserById ( userId : UserId ) : Promise < UserProfile | null > {
// Implementation
}
// Constants at module level
const MAX_LOGIN_ATTEMPTS = 5 ;
const SESSION_TIMEOUT_MS = 30 * 60 * 1000 ;
// Avoid magic numbers
// Bad:
if (retries > 3 ) { /* ... */ }
// Good:
const MAX_RETRIES = 3 ;
if (retries > MAX_RETRIES ) { /* ... */ }
# File naming: snake_case
# user_service.py, payment_processor.py
from typing import Optional
from dataclasses import dataclass
from datetime import datetime
# Classes: PascalCase
@dataclass
class UserProfile :
"""User profile with basic information."""
user_id: str
email: str
created_at: datetime
preferences: Optional[ dict ] = None
# Functions: snake_case
def fetch_user_by_id (user_id: str ) -> Optional[UserProfile]:
"""
Fetch a user profile by ID.
Args:
user_id: The unique identifier of the user
Returns:
UserProfile if found, None otherwise
"""
pass
# Constants: UPPER_SNAKE_CASE
MAX_LOGIN_ATTEMPTS = 5
SESSION_TIMEOUT_SECONDS = 30 * 60
# Private functions: prefix with underscore
def _validate_email (email: str ) -> bool :
"""Internal validation helper."""
pass
// File naming: snake_case
// user_service.go, payment_processor.go
package user
import (
" context "
" time "
)
// Exported types: PascalCase
type UserProfile struct {
ID string
Email string
CreatedAt time . Time
Preferences * UserPreferences
}
// Exported functions: PascalCase
func FetchUserByID ( ctx context . Context , userID string ) ( * UserProfile , error ) {
// Implementation
}
// Unexported (private): camelCase
func validateEmail ( email string ) bool {
// Implementation
}
// Constants
const (
MaxLoginAttempts = 5
SessionTimeoutSec = 30 * 60
)
// Interfaces: describe behavior
type UserRepository interface {
FindByID ( ctx context . Context , id string ) ( * UserProfile , error )
Save ( ctx context . Context , user * UserProfile ) error
}
Aspect Standard/Tool Style Guide Google Java Style Guide Code Quality Checkstyle, PMD, SpotBugs Unit Testing JUnit 5, TestNG Code Coverage JaCoCo
// File naming: PascalCase matching class name
// UserService.java, PaymentProcessor.java
package com.example.service;
import java.util.Optional;
// Classes: PascalCase
public class UserService {
// Constants: UPPER_SNAKE_CASE
private static final int MAX_LOGIN_ATTEMPTS = 5 ;
private static final long SESSION_TIMEOUT_MS = 30 * 60 * 1000 ;
private final UserRepository userRepository;
public UserService (UserRepository userRepository ) {
this .userRepository = userRepository;
}
// Methods: camelCase, descriptive names
public Optional< UserProfile > fetchUserById (String userId ) {
return userRepository. findById (userId);
}
// Private methods: camelCase with underscore prefix optional
private boolean validateEmail (String email ) {
return email != null && email. contains ( "@" );
}
}
Aspect Standard/Tool Style Guide PSR-12 Code Quality PHP_CodeSniffer, PHP Mess Detector, PHPStan Unit Testing PHPUnit Code Coverage Xdebug, PCOV
<? php
// File naming: PascalCase for classes
// UserService.php, PaymentProcessor.php
declare ( strict_types = 1 );
namespace App\Service ;
use App\Repository\UserRepository ;
use App\Entity\UserProfile ;
// Classes: PascalCase
class UserService
{
// Constants: UPPER_SNAKE_CASE
private const MAX_LOGIN_ATTEMPTS = 5 ;
private const SESSION_TIMEOUT_SECONDS = 1800 ;
private UserRepository $userRepository;
public function __construct ( UserRepository $userRepository)
{
$this -> userRepository = $userRepository;
}
// Methods: camelCase
public function fetchUserById ( string $userId) : ? UserProfile
{
return $this -> userRepository -> find ($userId);
}
// Private methods: camelCase
private function validateEmail ( string $email) : bool
{
return filter_var ($email, FILTER_VALIDATE_EMAIL ) !== false ;
}
}
Aspect Standard/Tool Style Guide Drupal Coding Standards Code Quality PHP_CodeSniffer + Coder module Unit Testing PHPUnit (Drupal Test Traits) Code Coverage Xdebug
<? php
// Drupal follows PSR-4 with specific conventions
// modules/custom/my_module/src/Service/UserService.php
namespace Drupal\my_module\Service ;
use Drupal\Core\Entity\EntityTypeManagerInterface ;
/**
* Service for user-related operations.
*/
class UserService {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Constructs a UserService object.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
*/
public function __construct ( EntityTypeManagerInterface $entity_type_manager) {
$this -> entityTypeManager = $entity_type_manager;
}
/**
* Loads a user by ID.
*
* @param int $uid
* The user ID.
*
* @return \Drupal\user\UserInterface | null
* The user entity or NULL if not found.
*/
public function loadUser ( int $uid) {
return $this -> entityTypeManager -> getStorage ( 'user' ) -> load ($uid);
}
}
Aspect Standard/Tool Style Guide WordPress Coding Standards Code Quality PHP_CodeSniffer + WPCS Unit Testing PHPUnit, WP_UnitTestCase Code Coverage Xdebug
<? php
// WordPress uses specific naming conventions
// File naming: lowercase with hyphens for includes
// class-user-service.php
/**
* User service class.
*
* @package MyPlugin
*/
class My_Plugin_User_Service {
/**
* Maximum login attempts.
*
* @var int
*/
const MAX_LOGIN_ATTEMPTS = 5 ;
/**
* Fetch user by ID.
*
* @param int $user_id User ID.
* @return WP_User | false User object or false.
*/
public function fetch_user_by_id ( $user_id ) {
return get_user_by ( 'id' , $user_id );
}
/**
* Validate email address.
*
* @param string $email Email address.
* @return bool True if valid.
*/
private function validate_email ( $email ) {
return is_email ( $email );
}
}
Aspect Standard/Tool Style Guide Angular Style Guide Code Quality ESLint + @angular-eslint Unit Testing Jasmine, Karma E2E Testing Protractor, Cypress Code Coverage Istanbul
// File naming: kebab-case with type suffix
// user.service.ts, user-profile.component.ts
import { Injectable } from '@angular/core' ;
import { HttpClient } from '@angular/common/http' ;
import { Observable } from 'rxjs' ;
// Interfaces: PascalCase
export interface UserProfile {
id : string ;
email : string ;
displayName : string ;
}
// Services: PascalCase with Service suffix
@ Injectable ({
providedIn: 'root'
})
export class UserService {
private readonly apiUrl = '/api/users' ;
constructor ( private http : HttpClient ) {}
// Methods: camelCase
getUserById ( userId : string ) : Observable < UserProfile > {
return this .http. get < UserProfile >( `${ this . apiUrl }/${ userId }` );
}
// Private methods: camelCase
private validateUserId ( userId : string ) : boolean {
return userId. length > 0 ;
}
}
<!-- HTML: lowercase elements, kebab-case attributes -->
<! DOCTYPE html >
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title >User Profile</ title >
< link rel = "stylesheet" href = "styles/main.css" >
</ head >
< body >
<!-- Use semantic elements -->
< main class = "user-profile" data-user-id = "123" >
< header class = "user-profile__header" >
< h1 class = "user-profile__title" >User Profile</ h1 >
</ header >
< section class = "user-profile__content" >
<!-- Content here -->
</ section >
</ main >
</ body >
</ html >
/* CSS: BEM naming convention recommended */
/* File naming: kebab-case (main.css, user-profile.css) */
/* Component block */
.user-profile {
display : flex ;
flex-direction : column ;
padding : 1 rem ;
}
/* Element */
.user-profile__header {
margin-bottom : 1 rem ;
}
.user-profile__title {
font-size : 1.5 rem ;
font-weight : 600 ;
}
/* Modifier */
.user-profile--compact {
padding : 0.5 rem ;
}
/* Variables */
:root {
--color-primary : #007bff ;
--spacing-unit : 8 px ;
}
Aspect Standard/Tool Style Guide Kotlin Coding Conventions Code Quality Android Lint, ktlint, detekt Unit Testing JUnit 5, MockK UI Testing Espresso Code Coverage JaCoCo
// File naming: PascalCase matching class name
// UserService.kt, UserProfileViewModel.kt
package com.example.app.service
import kotlinx.coroutines.flow.Flow
// Classes: PascalCase
class UserService (
private val userRepository: UserRepository
) {
// Constants: UPPER_SNAKE_CASE in companion object
companion object {
const val MAX_LOGIN_ATTEMPTS = 5
private const val SESSION_TIMEOUT_MS = 30 * 60 * 1000L
}
// Functions: camelCase
suspend fun fetchUserById (userId: String ): UserProfile ? {
return userRepository. findById (userId)
}
// Flow for reactive patterns
fun observeUser (userId: String ): Flow < UserProfile > {
return userRepository. observeUser (userId)
}
// Private functions: camelCase
private fun validateEmail (email: String ): Boolean {
return email. contains ( "@" ) && email. contains ( "." )
}
}
// Data classes for models
data class UserProfile (
val id: String ,
val email: String ,
val displayName: String ,
val createdAt: Long
)
Aspect Standard/Tool Style Guide Swift API Design Guidelines Code Quality SwiftLint Unit Testing XCTest UI Testing XCUITest Code Coverage Xcode Coverage
// File naming: PascalCase matching type name
// UserService.swift, UserProfileViewController.swift
import Foundation
// Protocols: PascalCase, often with -able, -ing suffix
protocol UserFetching {
func fetchUser ( byId id: String ) async throws -> UserProfile ?
}
// Classes/Structs: PascalCase
final class UserService : UserFetching {
// Constants: camelCase for instance, UPPER_SNAKE_CASE less common
private let maxLoginAttempts = 5
private let sessionTimeoutSeconds: TimeInterval = 30 * 60
private let userRepository: UserRepository
init ( userRepository : UserRepository) {
self .userRepository = userRepository
}
// Functions: camelCase, clear parameter labels
func fetchUser ( byId id: String ) async throws -> UserProfile ? {
return try await userRepository. find ( byId : id)
}
// Private functions: camelCase
private func validateEmail ( _ email: String ) -> Bool {
return email. contains ( "@" ) && email. contains ( "." )
}
}
// Structs for data models (value types)
struct UserProfile : Codable , Identifiable {
let id: String
let email: String
let displayName: String
let createdAt: Date
}
Aspect Standard/Tool Style Guide .NET Coding Conventions Code Quality StyleCop, Roslyn Analyzers, SonarQube Unit Testing xUnit, NUnit, MSTest Code Coverage Coverlet, dotCover
// File naming: PascalCase matching class name
// UserService.cs, UserProfileController.cs
using System ;
using System . Threading . Tasks ;
namespace MyApp . Services
{
// Interfaces: PascalCase with I prefix
public interface IUserService
{
Task < UserProfile ?> GetUserByIdAsync ( string userId );
}
// Classes: PascalCase
public class UserService : IUserService
{
// Constants: PascalCase
private const int MaxLoginAttempts = 5 ;
private static readonly TimeSpan SessionTimeout = TimeSpan. FromMinutes ( 30 );
private readonly IUserRepository _userRepository ;
// Constructor injection
public UserService ( IUserRepository userRepository )
{
_userRepository = userRepository;
}
// Methods: PascalCase, async suffix for async methods
public async Task < UserProfile ?> GetUserByIdAsync ( string userId )
{
return await _userRepository. FindByIdAsync (userId);
}
// Private methods: PascalCase
private bool ValidateEmail ( string email )
{
return ! string . IsNullOrEmpty (email) && email. Contains ( "@" );
}
}
// Records for immutable data (C# 9+)
public record UserProfile (
string Id ,
string Email ,
string DisplayName ,
DateTime CreatedAt
);
}
src/
├── components/ # UI components
│ ├── common/ # Shared components
│ └── features/ # Feature-specific
├── services/ # Business logic
├── repositories/ # Data access
├── models/ # Data models
├── utils/ # Utility functions
├── constants/ # Application constants
└── types/ # Type definitions
// Each module should have clear boundaries
// user/index.ts - Public API
export { UserService } from './user-service' ;
export { UserRepository } from './user-repository' ;
export type { User, UserProfile } from './types' ;
// user/user-service.ts - Business logic
import { UserRepository } from './user-repository' ;
import { User } from './types' ;
export class UserService {
constructor ( private repository : UserRepository ) {}
async getUser ( id : string ) : Promise < User | null > {
return this .repository. findById (id);
}
}
// Define custom error types
class ValidationError extends Error {
constructor (
message : string ,
public readonly field : string ,
public readonly code : string
) {
super (message);
this .name = 'ValidationError' ;
}
}
class NotFoundError extends Error {
constructor (
public readonly resource : string ,
public readonly id : string
) {
super ( `${ resource } with id ${ id } not found` );
this .name = 'NotFoundError' ;
}
}
// Use consistent error handling
async function processOrder ( orderId : string ) : Promise < Order > {
const order = await orderRepository. findById (orderId);
if ( ! order) {
throw new NotFoundError ( 'Order' , orderId);
}
if ( ! order. isValid ()) {
throw new ValidationError (
'Order validation failed' ,
'status' ,
'INVALID_ORDER_STATUS'
);
}
return order;
}
// Bad: Silently swallowing errors
try {
await processPayment (order);
} catch (error) {
// Error is lost
}
// Good: Log and handle appropriately
try {
await processPayment (order);
} catch (error) {
logger. error ( 'Payment processing failed' , { orderId: order.id, error });
throw new PaymentError ( 'Payment processing failed' , { cause: error });
}
For life-critical systems, additional requirements apply:
Requirement Purpose Traceability Code links to requirements and tests Code Reviews Documented review with sign-off Static Analysis Automated code quality checks Complexity Limits Cyclomatic complexity thresholds Coverage Requirements Minimum test coverage (often 80%+)
// .eslintrc.json (TypeScript/JavaScript)
{
"extends" : [
"eslint:recommended" ,
"plugin:@typescript-eslint/recommended" ,
"prettier"
],
"rules" : {
"@typescript-eslint/explicit-function-return-type" : "error" ,
"@typescript-eslint/no-explicit-any" : "error" ,
"no-console" : "warn" ,
"complexity" : [ "error" , 10 ],
"max-lines-per-function" : [ "warn" , 50 ]
}
}
# .pre-commit-config.yaml
repos :
- repo : local
hooks :
- id : eslint
name : ESLint
entry : npx eslint --fix
language : system
files : \.(ts|tsx|js|jsx)$
- id : prettier
name : Prettier
entry : npx prettier --write
language : system
files : \.(ts|tsx|js|jsx|json|md)$
Write self-documenting code with clear names
Keep functions small and focused
Use consistent formatting (automated via tools)
Handle all error cases explicitly
Write tests alongside code
Review code before merging
Use abbreviations that aren't universally understood
Write functions longer than 50 lines
Nest more than 3 levels deep
Leave TODO comments without tickets
Copy-paste code (extract to shared functions)
Ignore linter warnings
This section fulfills ISO 13485 requirements for design and development procedures (7.3.1) and product identification (7.5.3), and ISO 27001 requirements for secure coding practices (A.8.28), secure development lifecycle (A.8.25), and configuration management (A.8.9).
View full compliance matrix
How is this guide?
Good Bad