UTA DevHub
Coding Standards

File Naming Conventions

Comprehensive guidelines for file and folder naming conventions in the React Native project.

File Naming Conventions

Overview

This document establishes the official file and folder naming conventions for our React Native project. These conventions ensure consistency, readability, and maintainability across the codebase while aligning with React community best practices.

Purpose & Scope

These conventions apply to all files and folders in the project, covering:

  • React components
  • Custom hooks
  • Domain files
  • Utility functions
  • Test files
  • Configuration files

Following these conventions is mandatory for all team members to maintain code consistency.

General Principles

  1. Consistency: Apply conventions uniformly across the project
  2. Clarity: Names should be self-documenting
  3. Tool-friendly: Compatible with IDEs, linters, and build tools
  4. Community alignment: Follow React ecosystem standards

Component Files

Convention

Use PascalCase for React component files and folders.

Examples

ui/Button/Button.tsx
features/product-catalog/components/ProductCard/ProductCard.tsx
features/shopping-cart/components/CartItem/CartItem.tsx

Rules

  • Component filename must match the component name
  • Main component file should have the same name as its folder
  • Always use .tsx extension for components

Structure

ComponentName/
├── ComponentName.tsx    # Main component
├── styles.ts           # Component styles
├── types.ts            # Component types (optional)
├── index.ts            # Barrel export
└── ComponentName.test.tsx # Component tests

Hook Files

Convention

Use camelCase starting with "use" for custom hooks.

Examples

core/shared/hooks/useDebounce.ts
core/shared/hooks/useLocalStorage.ts
core/domains/products/hooks.ts  # Contains multiple hooks

Rules

  • Hook names must start with "use"
  • Single hook per file in shared hooks
  • Multiple related hooks can be in domain hooks.ts
  • Use .ts extension (not .tsx) for hooks

Examples in Code

// core/shared/hooks/useDebounce.ts
export function useDebounce<T>(value: T, delay: number): T { }
 
// core/domains/products/hooks.ts
export function useProducts() { }
export function useProduct(id: string) { }
export function useCreateProduct() { }

Domain Files

Convention

Use lowercase descriptive names for domain-specific files.

Standard Domain Files

core/domains/products/
├── api.ts          # API service methods
├── types.ts        # Type definitions
├── hooks.ts        # Query/mutation hooks
├── queryKeys.ts    # Query key factory
├── store.ts        # Client state (if needed)
├── events.ts       # Event definitions (if needed)
├── utils.ts        # Domain utilities (if needed)
└── index.ts        # Barrel exports

Rules

  • Keep names simple and descriptive
  • Don't prefix with domain name (already in folder)
  • Use consistent names across all domains
  • Optional files only when needed

Utility Files

Convention

Use category-based lowercase names for utility functions.

Examples

core/shared/utils/
├── date.ts         # Date formatting utilities
├── string.ts       # String manipulation
├── number.ts       # Number formatting
├── validation.ts   # Generic validators
├── array.ts        # Array utilities
└── index.ts        # Barrel exports

Rules

  • Group utilities by function type
  • Keep names generic and descriptive
  • Use plural for collection utilities
  • No prefixes or suffixes

Feature Folders

Convention

Use kebab-case for feature folders.

Examples

features/
├── product-catalog/
├── shopping-cart/
├── user-profile/
├── checkout-flow/
└── order-history/

Rules

  • Use hyphens to separate words
  • Keep names descriptive but concise
  • Reflect user-facing functionality
  • Avoid technical terms

Test Files

Convention

Use .test.ts or .test.tsx suffix for test files.

Examples

Button.test.tsx
useAuth.test.ts
api.test.ts
ProductCard.test.tsx

Rules

  • Place tests next to the file being tested
  • Or in __tests__ folder for organization
  • Match the name of the file being tested
  • Use .test.tsx for component tests
  • Use .test.ts for non-component tests

Test Folder Structure

ComponentName/
├── ComponentName.tsx
├── ComponentName.test.tsx
└── __tests__/
    ├── ComponentName.integration.test.tsx
    └── ComponentName.snapshot.test.tsx

Index Files

Convention

Use index.ts for barrel exports.

Examples

core/domains/products/index.ts
ui/Button/index.ts
core/shared/hooks/index.ts
features/product-catalog/components/index.ts

Purpose

  • Simplify imports
  • Create public API for modules
  • Re-export relevant items

Example Content

// core/domains/products/index.ts
export * from './api';
export * from './types';
export * from './hooks';
export { productQueryKeys } from './queryKeys';

Multi-word Files

Rules by Type

  • Components: PascalCase (ProductCard.tsx)
  • Hooks: camelCase (useLocalStorage.ts)
  • Domains: lowercase (queryKeys.ts)
  • Features: kebab-case (product-catalog/)
  • Utils: lowercase (dateHelpers.ts or date.ts)

Examples

ProductListScreen.tsx       # Component
useShoppingCart.ts         # Hook
product-catalog/           # Feature
formatCurrency.ts         # Utility

Platform-specific Files

Convention

Use platform suffixes when needed.

Examples

Button.ios.tsx
Button.android.tsx
styles.ios.ts
styles.android.ts
useNativeFeature.ios.ts
useNativeFeature.android.ts

Rules

  • Only use when platform differences exist
  • Default file without suffix for shared code
  • Platform files override default

Configuration Files

Convention

Follow tool-specific conventions.

Examples

.eslintrc.js           # ESLint config
.prettierrc            # Prettier config
babel.config.js        # Babel config
jest.config.js         # Jest config
tsconfig.json          # TypeScript config
metro.config.js        # Metro config
app.config.js          # Expo config

Rules

  • Use the format required by the tool
  • Include tool name in filename when possible
  • Place in project root by default

Special Cases

Private Files

Use underscore prefix for internal files:

_helpers.ts            # Internal helpers
_constants.ts          # Internal constants

Temporary Files

Use .temp suffix:

data.temp.json         # Temporary data
backup.temp.ts         # Temporary backup

Generated Files

Use .generated suffix:

schema.generated.ts    # Generated from GraphQL
types.generated.ts     # Generated types

Do's and Don'ts

Component Naming

  • (Do ✅) ProductCard.tsx - PascalCase
  • (Don't ❌) productCard.tsx - Wrong case
  • (Don't ❌) product-card.tsx - Wrong convention

Hook Naming

  • (Do ✅) useAuth.ts - Starts with "use"
  • (Don't ❌) authHook.ts - Missing "use" prefix
  • (Don't ❌) UseAuth.ts - Wrong case

Feature Naming

  • (Do ✅) shopping-cart/ - Kebab-case
  • (Don't ❌) shoppingCart/ - Wrong case
  • (Don't ❌) shopping_cart/ - Wrong separator

Test Naming

  • (Do ✅) Button.test.tsx - Clear test file
  • (Don't ❌) Button.spec.tsx - Use .test instead
  • (Don't ❌) ButtonTests.tsx - Use standard suffix

Directory Examples

Complete Feature Structure

features/product-catalog/
├── components/
│   ├── ProductCard/
│   │   ├── ProductCard.tsx
│   │   ├── ProductCard.test.tsx
│   │   ├── styles.ts
│   │   └── index.ts
│   └── ProductFilters/
│       ├── ProductFilters.tsx
│       └── index.ts
├── screens/
│   └── ProductListScreen/
│       ├── ProductListScreen.tsx
│       ├── ProductListScreen.test.tsx
│       └── index.ts
├── navigation.tsx
└── state/
    └── filtersStore.ts

Complete Domain Structure

core/domains/products/
├── api.ts
├── types.ts
├── hooks.ts
├── queryKeys.ts
├── store.ts
├── events.ts
├── utils.ts
├── index.ts
└── __tests__/
    ├── api.test.ts
    ├── hooks.test.ts
    └── utils.test.ts

Enforcement

ESLint Rules

Configure ESLint to enforce naming conventions:

// .eslintrc.js
module.exports = {
  rules: {
    'filename-rules/match': [2, {
      '**/*.tsx': 'PascalCase',
      '**/use*.ts': 'camelCase',
      '**/features/*': 'kebab-case',
    }],
  },
};

Pre-commit Hooks

Use tools like lint-staged to check naming:

// package.json
{
  "lint-staged": {
    "**/*.{ts,tsx}": [
      "eslint --fix",
      "prettier --write"
    ]
  }
}

Migration Guide

When updating existing files:

  1. Identify non-conforming files

    find src -type f -name "*.tsx" | grep -v "[A-Z]"
  2. Update imports

    • Use IDE refactoring tools
    • Update all import statements
    • Update barrel exports
  3. Update tests

    • Rename test files
    • Update test imports
  4. Verify build

    • Run full build
    • Run all tests
    • Check for broken imports

Summary

These naming conventions ensure:

  • Consistency across the codebase
  • Clarity in file purpose
  • Compatibility with tools
  • Scalability as project grows

All team members must follow these conventions for new files and when refactoring existing code.