Accepted - 2024-12-27
As our Frontend Recipeer project grows, we were experiencing:
- Inconsistent component organization with flat structure in
src/components/ - Difficulty finding and reusing components across the application
- Scattered Storybook structure without clear hierarchy
- AI assistants generating code that doesn't follow established patterns
- New team members struggling to understand component relationships and architecture
- Lack of clear guidelines for component complexity and composition
We have decided to adopt Atomic Design methodology combined with Component-Driven Development (CDD) principles for organizing our React component architecture.
src/
├── components/
│ ├── atoms/ # Basic building blocks (Button, Input, Typography)
│ ├── molecules/ # Simple combinations (QuantityAdjuster, SearchField)
│ ├── organisms/ # Complex sections (RecipeCard, Navigation)
│ ├── templates/ # Page layouts (RecipeLayout, DashboardLayout)
│ └── index.ts # Barrel exports
├── pages/ # Specific page instances with data
├── hooks/ # Custom React hooks
├── services/ # API and business logic
├── utils/ # Helper functions
├── types/ # TypeScript definitions
├── constants/ # App constants
└── styles/ # Global styles
- Atoms: Pure UI components, no business logic, basic building blocks
- Molecules: 2-5 atoms working together, simple interaction logic
- Organisms: Complex components with business logic, self-contained
- Templates: Data-agnostic page layouts, responsive structure
- Strict Import Hierarchy: Components can only import from lower levels
component-name/
├── component-name.tsx # Main component
├── ComponentName.stories.tsx # Storybook stories
├── ComponentName.test.tsx # Unit tests (molecules+)
└── index.ts # Clean export
-
Improved Developer Experience
- Clear guidelines for component placement and complexity
- Easier to find existing components
- Consistent naming and organization patterns
- Better onboarding for new developers
-
Enhanced Maintainability
- Enforced separation of concerns
- Prevented circular dependencies through import hierarchy
- Easier refactoring and component evolution
- Clear component composition patterns
-
Better AI Integration
- AI assistants can follow structured guidelines
- Consistent code generation patterns
- Reduced need for manual corrections
-
Scalable Architecture
- Clear patterns for adding new components
- Hierarchical organization scales with project size
- Design system foundation for future growth
-
Migration Effort
- Required moving all existing components to new structure
- Updated 25+ component imports across codebase
- Reorganized 100+ Storybook stories
-
Learning Curve
- Team needs to understand Atomic Design principles
- New mental model for component classification
- Requires discipline to maintain hierarchy rules
-
Initial Overhead
- More directories and index files to maintain
- Additional consideration needed for component placement
- Barrel exports add complexity to module resolution
- Updated AI instruction files (CLAUDE.md, .github/copilot-instructions.md)
- Created atomic directory structure
- Established barrel export pattern
- Categorized existing components by atomic level:
- Atoms: Button, Input, Label, Checkbox, Switch, Textarea, Typography
- Molecules: QuantityAdjuster, DifficultyIndicator, ThemeToggle, RadioGroup, Select, Slider
- Organisms: RecipeCard, IngredientChecklist, NutritionFacts, RecipeCollectionSaver
- Updated all import statements (25+ files)
- Moved ThemeProvider to dedicated providers directory
- Updated Storybook story titles to reflect atomic hierarchy
- Verified all tests continue to pass (247/247 tests)
- Updated Welcome story to explain atomic structure
- Verified build and lint processes work correctly
- Build Process: ✅ All builds passing
- Test Suite: ✅ 247/247 tests passing
- Linting: ✅ No new errors introduced
- Storybook: ✅ Successfully running with new organization
- Component Exports: ✅ All barrel exports working correctly
For existing code that imports components:
// Before
import { Button } from '@/components/Button';
import { QuantityAdjuster } from '@/components/QuantityAdjuster';
import { RecipeCard } from '@/components/RecipeCard';
// After
import { Button } from '@/components/atoms';
import { QuantityAdjuster } from '@/components/molecules';
import { RecipeCard } from '@/components/organisms';
// Or from the master barrel
import { Button, QuantityAdjuster, RecipeCard } from '@/components';For new component development:
- Classify component by complexity and dependencies
- Place in appropriate atomic level directory
- Follow file structure standard with stories and tests
- Add to barrel exports at appropriate level
- Update Storybook title to match atomic hierarchy
- Template Development: Create page layout templates as application grows
- UI Library Evolution: Consider extracting atoms/molecules to separate package
- Performance Monitoring: Watch for bundle size impacts from barrel exports
- Tooling Enhancement: Potentially add linting rules to enforce import hierarchy