React Fractal Compoundnents

Fractals and compounding are useful metaphors for how I like to structure React apps: the same shape at every scale, and small pieces that get more valuable as you reuse them. The finance version is familiar—earnings on reinvested earnings. Applied to a codebase, that means a consistent, layered design so extensions don't pile on debt.

Fractals: self-similarity

Fractals keep the same shape at every scale. A fern leaflet looks like the frond. In a codebase I want that too: a route folder should look like a feature folder, and a component folder should look like both.

Compounding in finance and code

In finance, compounding refers to generating earnings on reinvested earnings over time. Small, regular contributions snowball into substantial growth. Applied to software, this idea means designing systems where small improvements or extensions compound value without introducing technical debt. Fractal components create reusable building blocks that share the same shape, so you can extend the system without inventing a new pattern each time.

React fractal components

In React, fractal design combines self-similarity with modularity. Here's how this approach applies:

  1. Uniform Folder Structures: Each folder mirrors the same structure—organized by routes, features, or components.

  2. Consistent Tech Stack: All components follow the same standards:

    • tanstack/react-query: Standardized data fetching and caching, following a predictable query model.
    • viem: Low-level Ethereum interactions with a modern TypeScript API.
    • wagmi: React hooks for Ethereum, built on top of react-query and viem for consistent data fetching patterns.
    • nuqs: URL-based state management decouples components from internal logic.
    • Supabase: A backend with API logic abstracted into dedicated folders, making backend and frontend portable and reusable.
  3. Scalable Design Systems: Shadcn/UI and Tailwind CSS ensure a consistent and portable UI, adaptable even for generative design workflows (GenerativeUI). This approach is essential for modern UI development.

  4. Collocation with AHA Workflow: Components are refactored only when they naturally reveal the need for reusability (Avoid Hasty Abstractions).

Folder Structure

The project uses a consistent, self-similar folder hierarchy, promoting predictability and reusability:

repo/
  - supabase/
    - src/
        - market/
           - index.ts
           - types.ts
        - account/
          - index.ts
          - types.ts
  - hooks/
    - src/
      - market/
        - index.ts
        - types.ts
        - use-markets.ts
      - account/
        - index.ts
        - types.ts
        - use-account.ts
  - app/
    - src/
      - market/
        - list/
          - index.tsx
          - types.ts
        - detail/
          - use-market-collateral.ts
          - index.tsx
          - types.ts
      - account/
        - index.tsx
        - hooks/
          - use-account-health.ts
          - use-account-positions.ts
          - types.ts
        - health.tsx
        - positions.tsx
        - types.ts    

Concrete Implementation

1. Data Fetching with React Query

Here's how data fetching logic is standardized and portable, ensuring reuse on the frontend and backend:

// repo/hooks/useMarkets.ts
 
import { useQuery } from '@tanstack/react-query'
import { createSupabaseClient } from '@repo/db'
import { getMarkets } from '@/api/market'
 
export function useMarkets() {
  return useQuery({
    queryKey: ['markets'],
    queryFn: async () => {
      const supabase = await createSupabaseClient()
      return getMarkets({ supabase })
    }
  })
}

Related writing