What this is
Launch treats major optional capabilities (payments, AI, uploads, etc.) as features that can be enabled/disabled and composed centrally. Auth/session is core infrastructure and is not modeled as a removable feature. You can disable specific auth providers, but the session layer stays. The goal is to make it easy for engineers to:- delete a feature without hunting through the app
- swap a provider implementation (e.g., payments) without rewriting UI
- understand what a feature contributes (providers, screens, env requirements)
Prerequisites
- Familiarity with
apps/mobile/features - Optional features enabled via flags
Steps
The registry (source of truth)
The feature registry lives in:apps/mobile/features/feature-registry.tsx
It defines:
- which features exist
- whether they are enabled
- the order of provider composition
- optional docs links and dependencies
- required env vars and permissions
- removal checklists for clean deletion
How provider composition works
Some optional features require React providers (payments, uploads, etc.). Core infrastructure (like auth session, query client, theming) is mounted outside the registry. In Launch, the root layout mounts a singleFeatureProviders component, and it wraps the app with the enabled feature providers in order.
This keeps app/_layout.tsx clean and makes provider wiring a “one place” concern.
Enable/disable a feature
EditfeatureFlags inside:
apps/mobile/features/feature-registry.tsx
Example:
Production guidance: delete features you won’t ship
For real production apps, the best practice is usually:- Use the registry to explore and learn
- Then delete features you won’t ship, instead of leaving them disabled
- Disabled features still add maintenance surface (dependencies, upgrades, security review, bundle size, more routes to reason about).
- “Disabled” is great for template exploration, but deletion is cleaner for long-lived products.
Minimal removal checklist
When removing a feature (example: payments), aim for these outcomes:- No entry points in UI (tiles, buttons, menus)
- No reachable routes/screens
- No providers mounted in
FeatureProviders - No feature-specific env vars required
- No unused dependencies left behind
- No backend tables/endpoints running if they’re not needed
When feature flags still make sense
- Build-time flags (recommended): dev/staging/prod builds differ by enabled features (cleanest, predictable).
- Runtime flags (advanced): UX experiments and gradual rollouts (never rely on runtime flags for security boundaries; enforce entitlements server-side).
Add a new feature
- Create the feature code (recommended home:
apps/mobile/features/<feature-name>/) - Add a new
FeatureId - Add a new entry in
featureRegistry - If it needs a provider, add
provider+order - Document:
- required env vars
- screens/routes it adds
- how to remove it cleanly
Remove a feature
World-class removal should be boring and predictable:- Disable it in
featureFlags - Remove its routes/screens (or guard them behind the flag)
- Remove its API wiring and env vars
- Remove docs + navigation links
Next step
As the template evolves, each feature should declare its contract in one place:- screens/routes it contributes
- required env vars and permissions
- removal steps (disable vs delete)
Troubleshooting
- Feature not visible: verify
featureFlagsand entry points - Provider not mounted: check
FeatureProvidersorder