Appearance
Reuse and Data Flow
This page defines how to build reusable features in Favn without blurring ownership boundaries.
Core model
Favn supports two feature shapes:
featureType: "domain": route-mounted feature that owns a URL surface.featureType: "facet": reusable CSR feature loaded by another feature through@favn/feature-sdk.
Legacy aliases are still accepted for compatibility:
application->domainmodule->facet
Important: both are still "features". The difference is role, not product maturity.
Terminology
- Domain feature: a
featureType: "domain"feature that owns URL, page flow, and composition for a route. - Facet module: a
featureType: "facet"feature that is embedded and reused by domain features. - Data owner: the feature that decides what data to fetch, normalize, and pass into composed modules.
Recommended default for reuse:
- Keep data ownership in the consuming domain feature.
- Keep facet modules UI-focused and prop-driven.
- Let each team decide business authorization in its own backend and server functions.
Ownership boundaries
Host owns
- Manifest discovery, signature/integrity verification, and runtime loading.
- Routing for domain features.
- Transport/authentication plumbing for RPC (
/rpc/:feature/:fn). - Capability-scoped runtime APIs (event bus, host store, lifecycle wrappers).
Feature team owns
- Business rules and authorization semantics.
- Data contracts and backend integrations.
- Redaction policy and domain-level security behavior.
- UI composition inside each feature.
Reuse-first data pattern
Use this when you want strong reuse across applications.
- Domain feature fetches and normalizes data.
- Domain feature mounts one or more facet modules.
- Domain feature passes required input via props.
- Facet module emits user intent back to the domain feature (callbacks or event bus).
- Domain feature decides what to persist/call next.
Benefits:
- Reusable facet modules stay independent from domain-specific data services.
- Reuse across multiple domain features is straightforward.
- Data/security policy remains explicit and domain-feature-owned.
Feature-owned data pattern
Use this when the feature is a full vertical slice.
- Route-mounted domain feature renders.
- Feature calls its own server functions through host RPC transport.
- Feature server logic enforces business authorization and data policy.
Benefits:
- Strong team autonomy.
- Clear end-to-end ownership for a domain slice.
- Works well for independently deployed product areas.
Choosing between the two
Choose domain-feature-owned data with facet modules when:
- Multiple domain features need the same UI behavior.
- Data shape differs per domain context.
- You want a clean separation between presentation and orchestration.
Choose feature-owned data when:
- One team owns both UI and backend for a full domain slice.
- The feature is primarily route-based, not embedded.
- Reuse pressure is low.
Implementation checklist
- Decide feature shape early (
domainorfacet). - For facet modules, expose a stable mount contract (
mount/unmountor custom names). - Keep facet props explicit and versioned.
- Avoid hidden data access in facet modules unless intentionally domain-coupled.
- Keep business authorization in feature-owned services/server functions.
- Document data contracts between domain features and facet modules.
Practical APIs
- Module discovery/mounting:
listModules(),mountModule(),unmountModule() - Runtime host APIs:
createFeatureHostApi() - Manifest contract details: Manifest Contract
- SDK details: Feature SDK