Feature modules and boundaries
Feature Modules and Boundaries Deep Dive¶
Overview¶
Feature modules help scale product development when boundaries match user capability and team ownership. Good boundaries reduce coupling and release risk.
Core Concepts¶
- feature-first module slicing by business capability
- explicit inter-feature contracts
- local ownership of UI/domain behavior
- dependency direction toward shared contracts, not peer internals
Layer Responsibilities¶
- Feature module:
- feature UI orchestration
- feature-specific use cases and mappers
- Shared/core modules:
- common infra and cross-feature contracts
- App shell:
- top-level wiring and navigation composition
Data Flow¶
- Feature UI triggers feature use case.
- Use case calls local/shared contracts.
- Data is resolved by owning feature/data module.
- Result maps back into feature-local UI state.
- Cross-feature navigation/events use contract interfaces.
Internal Architecture¶
Boundary signals for healthy feature modules:
- minimal imports from peer feature modules
- API-only contract exposure
- no direct access to peer internal models
- isolated tests and build targets
Dynamic feature modules add delivery flexibility but operational complexity.
Code Examples¶
// contract module
interface ProfileEntry {
fun open(userId: String)
}
// feature implementation module
class ProfileEntryImpl(
private val nav: Navigator
) : ProfileEntry {
override fun open(userId: String) = nav.go("profile/$userId")
}
Common Interview Questions¶
- Q: How do you choose feature boundaries initially? A: Answer by defining boundaries and ownership first, then place business rules in the correct layer, and finish with testability and change-resilience tradeoffs.
- Q: How do you prevent cross-feature dependency creep? A: Answer by defining boundaries and ownership first, then place business rules in the correct layer, and finish with testability and change-resilience tradeoffs.
- Q: When are dynamic feature modules worth it? A: Answer by defining boundaries and ownership first, then place business rules in the correct layer, and finish with testability and change-resilience tradeoffs.
- Q: How do you handle shared design-system dependencies? A: Answer by defining boundaries and ownership first, then place business rules in the correct layer, and finish with testability and change-resilience tradeoffs.
Production Considerations¶
- enforce dependency rules in CI
- version and deprecate feature contracts explicitly
- assign clear module ownership and on-call accountability
- track build and integration cost per module
Scalability Tradeoffs¶
- Pros:
- team autonomy and safer parallel delivery
- more targeted releases and refactors
- Cons:
- contract coordination overhead
- increased dependency management complexity
Senior-Level Insights¶
Senior discussions should include boundary evolution. As product scope changes, feature boundaries should be revisited, not treated as permanent architecture law.