The Scope Rule for Components
The rule is simple and absolute:The Scope Rule
Code used by 2+ features → MUST go in global/shared directoriesCode used by 1 feature → MUST stay local in that featureNO EXCEPTIONS
Identifying Shared Components
Before moving a component to shared, ask:- Is it used by 2+ features? Count actual usage, not hypothetical future use
- Does it cross feature boundaries? Same feature doesn’t count as “shared”
- Is it truly generic? Or is it feature-specific logic in disguise?
Examples from Real Projects
Example 1: ProductCard Component
Scenario: E-commerce application with product listings, shopping cart, and wishlist. Analysis:- Used in:
/shop(product listing),/cart(cart items),/wishlist(saved items) - Count: 3 different features
- Generic: Yes, displays product information consistently
- Next.js
- Angular
- Astro
Example 2: Comment Section
Scenario: Blog with post pages and a community forum. Analysis:- Used in:
/blog/[slug](blog posts),/forum/[topic](forum topics) - Count: 2 different features
- Generic: Yes, handles user comments the same way
Example 3: Login Form
Scenario: Application with authentication feature. Analysis:- Used in:
/loginpage only - Count: 1 feature (authentication)
- Specific: Contains authentication-specific logic
Example 4: Social Login Buttons
Scenario: Used in both login and register pages. Analysis:- Used in:
/loginand/register - Count: 2 pages, but same feature (auth)
- Specific: Authentication-specific
- Next.js
- Angular
Common Shared Component Categories
UI Primitives
Button, Input, Card, Modal - Generic, unstyled or lightly styled components used everywhere.
Layout Components
Header, Footer, Sidebar - Used across multiple feature groups or pages.
Data Display
Tables, Charts, Lists - When multiple features need to display data the same way.
Feedback
Toasts, Alerts, Loading Spinners - Global UI feedback mechanisms.
Anti-patterns to Avoid
❌ Premature Sharing
❌ Feature Logic in Shared Components
❌ Everything in Shared
Extraction Process
When you realize a component is now used by a 2nd feature:- Move the component to shared directory
- Update imports in both features
- Remove feature-specific logic - make it generic
- Add prop-based customization for feature-specific behavior
- Update tests to cover both use cases
