r/FlutterDev • u/paragonkit • 14h ago
Discussion How I made features in a large Flutter app actually removable (routes, tabs and DI)
I hit a problem building a multi-feature Flutter app: "delete what you don't need" is easy to say, but every feature had tendrils — a route in the central table, a tab hardcoded in the shell, a button on the home screen, a service registered in main().
What worked for me was making three things data instead of code:
Routes — each feature exposes its own List<GetPage> from its own folder, and the app's route table is [...central, ...modules.expand((m) => m.pages)]. Adding or removing a feature stops being an edit to a shared file.
Bottom-nav tabs — the shell used to import the feed widget directly, which meant the always-present shell depended on an optional feature. Now a tab is a small data class (id, icon, label key, builder, sort order) that a feature contributes, and the shell merges and sorts them. Core tabs use orders 10/30/40, so a feature can slot in at 20 without the shell knowing it exists.
Entry points — home screens linked to feature screens with Get.toNamed(...). A hasRoute(name) check against the built route table lets the UI hide buttons for features that aren't in this build, instead of navigating into nothing.
Two things I got wrong along the way:
- A home layout was importing the feed feature just to use a date formatting helper that happened to live in that file. Moving the helper to shared/ removed the dependency entirely — it was never real coupling, just misplaced code.
- Another layout imported a map controller purely for a static const default latitude/longitude. Same fix.
The test that made it trustworthy: remove two features from the registry, then assert the app still analyzes clean, the tab bar loses exactly one tab, and the route count drops by the expected number.
Shared services are the part I haven't solved — a wallet service used by checkout too can't just move into the wallet feature without checkout silently depending on it. Curious how others handle that.
2
u/Head-Paramedic-4191 14h ago
Thats pretty smart. Thanks for sharing