React + TypeScript Feature-First Style Guide

A feature-first approach to building scalable, maintainable, and predictable React applications with TypeScript. Designed for clarity, consistency, and efficiency, this guide minimizes cognitive load and enforces best practices.


Core Principles

Additional Resources:


Feature-First Folder Structure

What is a Feature?

A feature is a self-contained module that represents:

Feature Structure Example

pages/guides/search  → Feature (route: `/guides/search`)
  GuideSearch.tsx  → Main component

pages/guides/:guideId  → Feature (route: `/guides/:guideId`)
  Guide.tsx  → Main component
  hooks/useGetGuideQuery.ts  → Query for getting details
  hooks/useGuideMetricShare.ts  → Handles copy-to-clipboard/sharing
  components/GuideHero.tsx  → Feature-scoped component

pages/profile/:accountHandle  → Feature (route: `/profile/:accountHandle`)
  Profile.tsx → Main component

pages/profile/:accountHandle/guides  → Feature (route: `/profile/:accountHandle/guides`)
  ProfileGuides.tsx → Main component

Component Structure

Ordering Inside a Component:

  1. Hooks (useState, useEffect, etc.)
  2. Local Variables (constants, derived values)
  3. useEffect Hooks (side effects, lifecycle logic)
  4. Event Handlers & Functions
  5. Return Statement (JSX)

Example Component:

export const Profile = () => {
  const { hasError, isLoading, profileData } = useGetProfileQuery()

  if (isLoading) return <ProfileLoading />

  if (hasError) return <ProfileEmpty />

  return (
    <section>
      <ProfileHero />
      <ProfileContent />
    </section>
  )
}

Naming Conventions

ItemNaming Convention
Variables, Functions, HookscamelCase (e.g., getUserProfile)
Components, Enums, InterfacesPascalCase (e.g., UserProfileCard)
Folderskebab-case (e.g., profile-settings/)
ConstantsDefined within feature files, not in a global folder.
GraphQL Queries/MutationscamelCase inside operations, PascalCase for file names

GraphQL Queries & Mutations

TypePlacement
Feature-based QueriesInside pages/featureName/hooks/
Sitewide QueriesInside src/hooks/

Correct Naming Examples:

query GetGuide($id: ID!) { ... }             # Fetches full guide details
query GetGuideEvents($guideId: ID!) { ... }  # Fetches related guide events
query GetGuideImages($guideId: ID!) { ... }  # Fetches guide images

Additional Resources:


Types & Interfaces

When to UseRule
Props for ComponentsUse interface (e.g., interface ProfileProps {})
Everything Else (Utilities, Hooks, GraphQL, API Responses)Use type (e.g., type UseGetProfileQueryResult = {})
Extracting Subsets of TypesUse Pick<> and Omit<>

Additional Resources:


Feature Flags

ItemRule
StorageCentralized in config/feature-flags/featureFlags.ts
UsageAccessed via useFlag hook
CleanupFeature flags should be short-lived

Additional Resources:


Comments & Documentation

Example:

/** @todo Remove this workaround when the new API version is available */
const getUserPreferences = async (userId: string) => {
  return await fetch(`/api/preferences/${userId}`)
}

Additional Resources:


Final Thoughts

This cheat sheet ensures clarity, predictability, and minimal cognitive load.

This is your definitive React + TypeScript Feature-First Style Guide, designed to reduce thinking, improve efficiency, and create scalable applications effortlessly.