# File Organization Proper file and directory structure for maintainable, scalable frontend code in the the application. --- ## features/ vs components/ Distinction ### features/ Directory **Purpose**: Domain-specific features with their own logic, API, and components **When to use:** - Feature has multiple related components - Feature has its own API endpoints - Feature has domain-specific logic - Feature has custom hooks/utilities **Examples:** - `features/posts/` - Project catalog/post management - `features/blogs/` - Blog builder and rendering - `features/auth/` - Authentication flows **Structure:** ``` features/ my-feature/ api/ myFeatureApi.ts # API service layer components/ MyFeatureMain.tsx # Main component SubComponents/ # Related components hooks/ useMyFeature.ts # Custom hooks useSuspenseMyFeature.ts # Suspense hooks helpers/ myFeatureHelpers.ts # Utility functions types/ index.ts # TypeScript types index.ts # Public exports ``` ### components/ Directory **Purpose**: Truly reusable components used across multiple features **When to use:** - Component is used in 3+ places - Component is generic (no feature-specific logic) - Component is a UI primitive or pattern **Examples:** - `components/SuspenseLoader/` - Loading wrapper - `components/CustomAppBar/` - Application header - `components/ErrorBoundary/` - Error handling - `components/LoadingOverlay/` - Loading overlay **Structure:** ``` components/ SuspenseLoader/ SuspenseLoader.tsx SuspenseLoader.test.tsx CustomAppBar/ CustomAppBar.tsx CustomAppBar.test.tsx ``` --- ## Feature Directory Structure (Detailed) ### Complete Feature Example Based on `features/posts/` structure: ``` features/ posts/ api/ postApi.ts # API service layer (GET, POST, PUT, DELETE) components/ PostTable.tsx # Main container component grids/ PostDataGrid/ PostDataGrid.tsx drawers/ ProjectPostDrawer/ ProjectPostDrawer.tsx cells/ editors/ TextEditCell.tsx renderers/ DateCell.tsx toolbar/ CustomToolbar.tsx hooks/ usePostQueries.ts # Regular queries useSuspensePost.ts # Suspense queries usePostMutations.ts # Mutations useGridLayout.ts # Feature-specific hooks helpers/ postHelpers.ts # Utility functions validation.ts # Validation logic types/ index.ts # TypeScript types/interfaces queries/ postQueries.ts # Query key factories (optional) context/ PostContext.tsx # React context (if needed) index.ts # Public API exports ``` ### Subdirectory Guidelines #### api/ Directory **Purpose**: Centralized API calls for the feature **Files:** - `{feature}Api.ts` - Main API service **Pattern:** ```typescript // features/my-feature/api/myFeatureApi.ts import apiClient from '@/lib/apiClient'; export const myFeatureApi = { getItem: async (id: number) => { const { data } = await apiClient.get(`/blog/items/${id}`); return data; }, createItem: async (payload) => { const { data } = await apiClient.post('/blog/items', payload); return data; }, }; ``` #### components/ Directory **Purpose**: Feature-specific components **Organization:** - Flat structure if <5 components - Subdirectories by responsibility if >5 components **Examples:** ``` components/ MyFeatureMain.tsx # Main component MyFeatureHeader.tsx # Supporting components MyFeatureFooter.tsx # OR with subdirectories: containers/ MyFeatureContainer.tsx presentational/ MyFeatureDisplay.tsx blogs/ MyFeatureBlog.tsx ``` #### hooks/ Directory **Purpose**: Custom hooks for the feature **Naming:** - `use` prefix (camelCase) - Descriptive of what they do **Examples:** ``` hooks/ useMyFeature.ts # Main hook useSuspenseMyFeature.ts # Suspense version useMyFeatureMutations.ts # Mutations useMyFeatureFilters.ts # Filters/search ``` #### helpers/ Directory **Purpose**: Utility functions specific to the feature **Examples:** ``` helpers/ myFeatureHelpers.ts # General utilities validation.ts # Validation logic transblogers.ts # Data transblogations constants.ts # Constants ``` #### types/ Directory **Purpose**: TypeScript types and interfaces **Files:** ``` types/ index.ts # Main types, exported internal.ts # Internal types (not exported) ``` --- ## Import Aliases (Vite Configuration) ### Available Aliases From `vite.config.ts` lines 180-185: | Alias | Resolves To | Use For | |-------|-------------|---------| | `@/` | `src/` | Absolute imports from src root | | `~types` | `src/types` | Shared TypeScript types | | `~components` | `src/components` | Reusable components | | `~features` | `src/features` | Feature imports | ### Usage Examples ```typescript // ✅ PREFERRED - Use aliases for absolute imports import { apiClient } from '@/lib/apiClient'; import { SuspenseLoader } from '~components/SuspenseLoader'; import { postApi } from '~features/posts/api/postApi'; import type { User } from '~types/user'; // ❌ AVOID - Relative paths from deep nesting import { apiClient } from '../../../lib/apiClient'; import { SuspenseLoader } from '../../../components/SuspenseLoader'; ``` ### When to Use Which Alias **@/ (General)**: - Lib utilities: `@/lib/apiClient` - Hooks: `@/hooks/useAuth` - Config: `@/config/theme` - Shared services: `@/services/authService` **~types (Type Imports)**: ```typescript import type { Post } from '~types/post'; import type { User, UserRole } from '~types/user'; ``` **~components (Reusable Components)**: ```typescript import { SuspenseLoader } from '~components/SuspenseLoader'; import { CustomAppBar } from '~components/CustomAppBar'; import { ErrorBoundary } from '~components/ErrorBoundary'; ``` **~features (Feature Imports)**: ```typescript import { postApi } from '~features/posts/api/postApi'; import { useAuth } from '~features/auth/hooks/useAuth'; ``` --- ## File Naming Conventions ### Components **Pattern**: PascalCase with `.tsx` extension ``` MyComponent.tsx PostDataGrid.tsx CustomAppBar.tsx ``` **Avoid:** - camelCase: `myComponent.tsx` ❌ - kebab-case: `my-component.tsx` ❌ - All caps: `MYCOMPONENT.tsx` ❌ ### Hooks **Pattern**: camelCase with `use` prefix, `.ts` extension ``` useMyFeature.ts useSuspensePost.ts useAuth.ts useGridLayout.ts ``` ### API Services **Pattern**: camelCase with `Api` suffix, `.ts` extension ``` myFeatureApi.ts postApi.ts userApi.ts ``` ### Helpers/Utilities **Pattern**: camelCase with descriptive name, `.ts` extension ``` myFeatureHelpers.ts validation.ts transblogers.ts constants.ts ``` ### Types **Pattern**: camelCase, `index.ts` or descriptive name ``` types/index.ts types/post.ts types/user.ts ``` --- ## When to Create a New Feature ### Create New Feature When: - Multiple related components (>3) - Has own API endpoints - Domain-specific logic - Will grow over time - Reused across multiple routes **Example:** `features/posts/` - 20+ components - Own API service - Complex state management - Used in multiple routes ### Add to Existing Feature When: - Related to existing feature - Shares same API - Logically grouped - Extends existing functionality **Example:** Adding export dialog to posts feature ### Create Reusable Component When: - Used across 3+ features - Generic, no domain logic - Pure presentation - Shared pattern **Example:** `components/SuspenseLoader/` --- ## Import Organization ### Import Order (Recommended) ```typescript // 1. React and React-related import React, { useState, useCallback, useMemo } from 'react'; import { lazy } from 'react'; // 2. Third-party libraries (alphabetical) import { Box, Paper, Button, Grid } from '@mui/material'; import type { SxProps, Theme } from '@mui/material'; import { useSuspenseQuery, useQueryClient } from '@tanstack/react-query'; import { createFileRoute } from '@tanstack/react-router'; // 3. Alias imports (@ first, then ~) import { apiClient } from '@/lib/apiClient'; import { useAuth } from '@/hooks/useAuth'; import { useMuiSnackbar } from '@/hooks/useMuiSnackbar'; import { SuspenseLoader } from '~components/SuspenseLoader'; import { postApi } from '~features/posts/api/postApi'; // 4. Type imports (grouped) import type { Post } from '~types/post'; import type { User } from '~types/user'; // 5. Relative imports (same feature) import { MySubComponent } from './MySubComponent'; import { useMyFeature } from '../hooks/useMyFeature'; import { myFeatureHelpers } from '../helpers/myFeatureHelpers'; ``` **Use single quotes** for all imports (project standard) --- ## Public API Pattern ### feature/index.ts Export public API from feature for clean imports: ```typescript // features/my-feature/index.ts // Export main components export { MyFeatureMain } from './components/MyFeatureMain'; export { MyFeatureHeader } from './components/MyFeatureHeader'; // Export hooks export { useMyFeature } from './hooks/useMyFeature'; export { useSuspenseMyFeature } from './hooks/useSuspenseMyFeature'; // Export API export { myFeatureApi } from './api/myFeatureApi'; // Export types export type { MyFeatureData, MyFeatureConfig } from './types'; ``` **Usage:** ```typescript // ✅ Clean import from feature index import { MyFeatureMain, useMyFeature } from '~features/my-feature'; // ❌ Avoid deep imports (but OK if needed) import { MyFeatureMain } from '~features/my-feature/components/MyFeatureMain'; ``` --- ## Directory Structure Visualization ``` src/ ├── features/ # Domain-specific features │ ├── posts/ │ │ ├── api/ │ │ ├── components/ │ │ ├── hooks/ │ │ ├── helpers/ │ │ ├── types/ │ │ └── index.ts │ ├── blogs/ │ └── auth/ │ ├── components/ # Reusable components │ ├── SuspenseLoader/ │ ├── CustomAppBar/ │ ├── ErrorBoundary/ │ └── LoadingOverlay/ │ ├── routes/ # TanStack Router routes │ ├── __root.tsx │ ├── index.tsx │ ├── project-catalog/ │ │ ├── index.tsx │ │ └── create/ │ └── blogs/ │ ├── hooks/ # Shared hooks │ ├── useAuth.ts │ ├── useMuiSnackbar.ts │ └── useDebounce.ts │ ├── lib/ # Shared utilities │ ├── apiClient.ts │ └── utils.ts │ ├── types/ # Shared TypeScript types │ ├── user.ts │ ├── post.ts │ └── common.ts │ ├── config/ # Configuration │ └── theme.ts │ └── App.tsx # Root component ``` --- ## Summary **Key Principles:** 1. **features/** for domain-specific code 2. **components/** for truly reusable UI 3. Use subdirectories: api/, components/, hooks/, helpers/, types/ 4. Import aliases for clean imports (@/, ~types, ~components, ~features) 5. Consistent naming: PascalCase components, camelCase utilities 6. Export public API from feature index.ts **See Also:** - [component-patterns.md](component-patterns.md) - Component structure - [data-fetching.md](data-fetching.md) - API service patterns - [complete-examples.md](complete-examples.md) - Full feature example