Melos on pub.dev
Melos is a powerful tool for managing monorepos in Flutter and Dart. It helps you organize, bootstrap, and automate tasks across multiple packages and apps in a single repository.
Why is this SOLID? This architecture helps you follow SOLID principles, especially the Dependency Inversion and Single Responsibility principles. Each module is independent and does not rely on external implementations or other modules directly. Communication happens only through well-defined events, making your codebase more maintainable, testable, and robust.
π§© Micro Frontend (Monorepo) β The Simple Way
A micro frontend architecture lets you split your app into independent modules, so each team or developer can work without interfering with others. The best way to organize this in Flutter is with a monorepo using Melos.
π¦ Recommended Monorepo Structureβ
π apps/
β βββ π main_app/ # Your main Flutter app
β βββ ...
π features/
β βββ π cart/ # Cart feature module
β βββ π product/ # Product feature module
β βββ π payment/ # Payment feature module
π packages/
β βββ π shared_utils/ # Shared code, events, services, etc.
βββ melos.yaml # Melos workspace config
- apps/: Where your main app(s) live
- features/: Each feature is a Dart/Flutter package (independent)
- packages/: Shared code, events, services, UI, etc.
π Why Use Melos?β
- Manages dependencies and scripts for all packages
- Makes it easy to run tests, analyze, or publish for the whole repo
- Standard for Flutter monorepos
To get started:
flutter pub global activate melos
melos init
π οΈ How to Create a Feature Packageβ
- Create a new package:
melos create feature_cart --template=package --path=features/cart
- Add your code:
- Place your module, pages, controllers, etc. inside
features/cart/lib/
- Place your module, pages, controllers, etc. inside
- Export your module:
- In
features/cart/lib/cart_module.dart
, export your main module class.
- In
- Add to your app:
- In
apps/main_app/pubspec.yaml
, add:dependencies:
feature_cart:
path: ../../features/cart
- In
- Import and use in your app:
import 'package:feature_cart/cart_module.dart';
β‘οΈ Advantages & Disadvantagesβ
β Advantagesβ
- Team independence: Each team works on their own module, no merge conflicts
- Scalability: Add new features as new packages
- Isolation: Bugs and changes in one module donβt break others
- Reusability: Shared code in
packages/
is easy to maintain - Faster CI: Test/build only what changed
β οΈ Disadvantagesβ
- Initial setup: Monorepo and Melos require some configuration
- Versioning: Need to manage versions for shared packages
- Learning curve: Teams must understand package boundaries
π Module Communication with EventModuleβ
Modules should never import each other directly. Instead, use the EventModule
system for communication:
// In features/auth/lib/auth_module.dart
class AuthModule extends EventModule {
void listen() {
on<LoginSuccessEvent>((event, context) {
if (context != null) context.go('/dashboard');
});
}
}
// In features/cart/lib/cart_module.dart
// Fire an event to notify other modules
ModularEvent.fire(LoginSuccessEvent());
- Events are defined in a shared package (e.g.,
packages/shared_utils/lib/events.dart
) - Any module can listen or fire events, keeping everything decoupled
π§βπ» Example: Adding a New Featureβ
melos create feature_orders --template=package --path=features/orders
- Add your module code in
features/orders/
- Export your module and add it to your appβs dependencies
- Communicate with other modules only via events
π Related Topicsβ
- π Event System - Module communication
- ποΈ Project Structure - Team organization
- π Dependency Injection - Module dependencies