Purpose
To define a unified set of clean code guidelines that ensure codebases are readable, maintainable, and testable, regardless of stack or team.
Scope
- Applies to all developers, reviewers, and tech leads.
- Covers naming, formatting, structure, testing, error handling, and documentation.
- Language-agnostic (applies to JS/TS, Python, Java, etc., with stack-specific linters enforcing rules).
Principles
- Readability Over Cleverness – Code should be clear to humans first.
- Consistency Over Preference – Follow agreed style, even if personal habits differ.
- Single Responsibility – Functions, classes, and modules should do one thing.
- Fail Fast & Loud – Errors should surface early and predictably.
- Self-Documenting Code – Code should explain itself with names and structure; comments only when needed.
Standards by Area
1. Naming Conventions
| Type | Rule | Example |
| Variables | Descriptive, not abbreviated | userEmail ✅ vs ue ❌ |
| Functions | Verb + object/action | sendInvoiceEmail() |
| Classes | PascalCase | UserService |
| Constants | UPPER_CASE with underscores | MAX_RETRY_LIMIT |
| Database Tables | Singular nouns | user, booking |
2. Code Structure
| Area | Rule |
| File Size | ≤ 500 LOC per file; split otherwise |
| Function Size | ≤ 30 LOC; extract helpers if larger |
| Modules | Group by domain, not technical type (e.g., booking/BookingService.ts) |
| Imports | No unused imports; sorted logically (core → libs → local) |
3. Formatting & Style
- Use linters & formatters (ESLint, Prettier, Black, Checkstyle).
- Indentation = 2 or 4 spaces (project-specific, must be enforced).
- No trailing whitespace or commented-out code.
- Keep line length ≤ 100–120 chars.
4. Error Handling
| Rule | Example |
| Always handle exceptions at boundaries | try { … } catch { log.error } |
| Never swallow errors silently | catch(e) {} |
| Provide meaningful error messages | "Booking not found for ID: 123" |
5. Testing Standards
| Level | Rule |
| Unit Tests | Mandatory for all business logic (≥70% coverage) |
| Integration Tests | Mandatory for APIs & DB interactions |
| Test Naming | should<doSomething>When<condition> |
| Flaky Tests | Must be fixed immediately; not skipped |
| CI | All tests must pass before merge |
6. Comments & Documentation
| Rule | Example |
| Code should be self-explanatory | Prefer getActiveUsers() over getUsers() with a comment |
| Use JSDoc/Docstring only for complex logic | /** Filters active users from list */ |
| No redundant comments | // increment i for i++ |
7. Security Practices
- Never commit secrets/tokens.
- Sanitize all inputs (API & UI).
- Use parameterized queries to avoid SQL injection.
- Follow RBAC & least privilege access.
- Validate dependencies with scanners (e.g., Dependabot, Snyk).
Do’s & Don’ts
Do’s
- Write small, composable functions.
- Use descriptive names, even if longer.
- Write tests alongside features.
- Keep logs structured and contextual.
- Refactor when touching legacy code (“boy scout rule”).
Don’ts
- Don’t leave TODOs unresolved in production code.
- Don’t duplicate code — extract common utilities.
- Don’t push console logs/debug prints into main branches.
- Don’t rely on implicit type coercion or language quirks.
Reusable Clean Code Checklist
| Area | Check | Status |
| Naming | Variables/functions/classes follow conventions | ⬜ |
| Structure | File & function sizes within limits | ⬜ |
| Style | Linter/formatter runs clean | ⬜ |
| Errors | No silent error handling | ⬜ |
| Tests | Unit/integration tests present & passing | ⬜ |
| Docs | Only meaningful comments; self-documenting code | ⬜ |
| Security | No secrets, validated inputs, safe queries | ⬜ |