๐Ÿ’ Code Style Guidelines

September 8, 2026 ยท View on GitHub

Principles

  • Rely on automation/IDE
  • Strive for pragmatism
  • Donโ€™t add bells and whistles (newlines, spaces for โ€œbeautyโ€, ordering imports etc.)
  • Avoid unnecessary stylistic changes
    • They increase the chance of git conflicts (esp. in imports)
    • They make it harder to review the PR
    • Ultimately, a waste of time

Functional code style

  • Write small functions that do one thing with no side-effects
  • Compose small functions to do more things
  • Same with components: donโ€™t write giant components, write small composable components
  • Prefer map/filter over reduce/forEach
  • Watch out when using destructive methods like pop or sort (yes, sort is destructive!)
  • Avoid initializing things on the module level, prefer to export an init function instead

Reactive programming

  • Keep in mind the React component life-cycle, avoid excessive re-renders
  • Glue regular JS functions and events with React using hooks
  • Write small useEffect hooks that do just one thing and have only necessary dependencies

Variable/function naming

Infamously, the hardest problem in computer science.

  • Components are classes, so their names should be in PascalCase
  • Config-like constants should be in UPPER_CASE, e.g. INFURA_URL
  • Regular const variables should be in camelCase
  • Avoid prepositions in variable names:
    • restoreFromLocalStorage ๐Ÿ™…
    • restoreStoredValue ๐Ÿ‘
  • Try to name boolean vars with is, e.g. isLoading vs loading
  • If something needs to be exported just for unit tests, export it with a _ prefix, e.g. _getOnboardConfig

Code Complexity

When writing utility scripts or complex logic, follow these patterns to keep cyclomatic complexity low. These guidelines apply to both the web and mobile codebases.

Prevent High Complexity

  1. Use lookup tables instead of conditional chains

    // โŒ Bad: 5+ if-else conditions
    if (type === 'a') doA()
    else if (type === 'b') doB()
    else if (type === 'c') doC()
    
    // โœ… Good: Lookup table
    const handlers = { a: doA, b: doB, c: doC }
    handlers[type]?.()
    
  2. Extract helper functions for nested conditions

    // โŒ Bad: 3+ levels of nesting
    if (condition1) {
      if (condition2) {
        if (condition3) {
          /* ... */
        }
      }
    }
    
    // โœ… Good: Early returns + helpers
    if (!condition1) return
    if (!condition2) return
    handleCondition3()
    
  3. Use switch for type discrimination

    // โŒ Bad: Multiple type checks
    if (obj.type === 'a') { ... }
    else if (obj.type === 'b') { ... }
    
    // โœ… Good: Switch statement
    switch (obj.type) {
      case 'a': return handleA()
      case 'b': return handleB()
    }
    
  4. Long functions are a smell, not a trigger โ€“ past ~20 lines, look for a responsibility to isolate (see docs/ai/when-to-extract-a-function.md); never split by line count alone

  5. Maximum 3 levels of nesting โ€“ Refactor if deeper

  6. Single responsibility โ€“ One function, one job