A boilerplate project created in flutter using MobX.
The Boilerplate contains the minimal implementation required to create a new library or project. The repository code is preloaded with some basic components like basic app architecture, app theme, constants and required dependencies to create a new project. By using boilerplate code as standard initializer, we can have same patterns in all the projects that will inherit it. This will also help in reducing setup & development time by allowing you to use same code pattern and avoid re-writing from scratch.
Step 1:
Download or clone this repo by using the link below:
https://github.com/NarekManukyan/flutter_boilerplate
Step 2:
Install Melos globally (if not already installed):
dart pub global activate melosStep 3:
Bootstrap the workspace to set up all dependencies and generate code:
melos bootstrapThis will:
- Install dependencies for all packages
- Generate code for all packages
- Set up the workspace
Step 4:
For development, use the development workflow:
melos run devThis will:
- Get dependencies for all packages
- Generate code for all packages
This project uses Melos to manage the monorepo structure. Melos provides powerful tools for managing multiple packages in a single repository.
Install Melos globally:
dart pub global activate melos-
Bootstrap the workspace:
melos bootstrap
This command will:
- Install dependencies for all packages
- Generate code for all packages
- Set up the workspace
-
Get dependencies for all packages:
melos run deps
melos run dev- Complete development setup (deps, generate)melos run deps- Get dependencies for all packagesmelos run generate- Generate code for all packagesmelos run build- Build all packages (generate code)melos run clean- Clean all packages
melos run analyze- Analyze all packages for issuesmelos run test- Run tests for all packagesmelos run format- Format code in all packagesmelos run lint- Apply linting fixes to all packages
melos run assets- Generate assets and translationsmelos run translations- Generate translation keys
melos run bootstrap- Complete workspace setup
melos run deploy-dev- Deploy to development environment
The monorepo contains the following packages:
flutter_boilerplate(root) - Main Flutter applicationpackages/api- API client and network layerpackages/design_system- Reusable UI components and themes
-
Run commands on specific packages:
melos exec --scope api -- "dart run build_runner build" melos exec --scope design_system -- "dart test"
-
Run commands on all packages except specific ones:
melos exec --ignore="**/test/**" -- "dart analyze"
-
Add a new package:
- Create a new directory in
packages/ - Add a
pubspec.yamlfile - Run
melos bootstrapto set up the new package
- Create a new directory in
Melos provides IDE integration for:
- VS Code - Enhanced workspace management
- IntelliJ/Android Studio - Better package navigation
If you were using derry before, here are the equivalent Melos commands:
| Old Derry Command | New Melos Command |
|---|---|
derry generate_translations |
melos run translations |
derry delete_generated_files |
melos run clean |
derry build_runner |
melos run build |
derry build_api |
melos exec --scope api -- "dart run build_runner build -d" |
derry build_design_system |
melos exec --scope design_system -- "dart run build_runner build -d" |
derry build_all |
melos run build |
derry generate |
melos run dev |
derry deploy_dev |
melos run deploy-dev |
In-order to hide generated files, navigate to Android Studio -> Preferences -> Editor -> File Types and paste the below lines under ignore files and folders section:
*.inject.summary;*.inject.dart;*.g.dart;
In Visual Studio Code, navigate to Preferences -> Settings and search for Files:Exclude. Add the following patterns:
**/*.inject.summary
**/*.inject.dart
**/*.g.dart
- Splash Screen
- Login Page
- Dashboard
- Routing with AutoRoute
- Theme Management
- SVG Support
- Dio for HTTP Requests
- Local Database Integration
- Shared Preferences
- Modal Bottom Sheet
- Freezed for Immutable Classes
- ExtendedImage for Advanced Image Handling
- MobX for State Management
- Code Generation
- Dependency Injection with GetIt
- Dark Theme Support
- Multilingual Support
- Flavor Configuration
- Environment-Based Configurations
- Monorepo Management with Melos
- Connectivity Support
- Background Fetch Support
- More Examples
- Dio
- Routing
- MobX (State Management)
- SVG support
- Modal bottom sheet
- Multilingual Support
- ExtendedImage (Official extension image)
- Shared preferences (Platform-specific persistent storage for simple data)
- Json Serialization
- Freezed (Code generation for immutable classes)
- Dependency Injection
- Melos (Monorepo Management)
- Local Libraries:
packages/api- Handles API-related logic and network requests.packages/design_system- Contains reusable UI components, themes, and design elements.
Here is the core folder structure which flutter provides.
flutter-app/
|- assets
|- build
|- lib
|- test
Here is the folder structure we have been using in this project:
lib/
|- core/
|- features/
|- gen/
|- shared/
|- app.dart
|- main.dart
|- main_dev.dart
|- main_prod.dart
|- injectable.dart
|- injectable.config.dart
packages/
|- api/
|- design_system/
Now, let's dive into the lib folder which has the main code for the application:
- core - Contains core utilities, constants, and configurations.
- features - Contains feature-specific modules and their respective UI, logic, and data layers.
- gen - Contains generated files.
- shared - Contains shared components like widgets, themes, and utilities.
- app.dart - The main app widget and configurations.
- main.dart - The entry point of the application.
- main_dev.dart - Entry point for the development environment.
- main_prod.dart - Entry point for the production environment.
- injectable.dart - Dependency injection setup.
- injectable.config.dart - Generated configuration for dependency injection.
- packages/api -Contains API client setup, endpoints, and interceptors for handling network requests.
- packages/design_system -CProvides reusable UI components and themes to maintain design consistency.
This file contains all the routes for your application.
import 'package:auto_route/auto_route.dart';
import 'features/dashboard/dashboard_page.dart';
import 'features/login/login_page.dart';
import 'features/splash/splash_screen.dart';
export 'router.gr.dart';
@AdaptiveAutoRouter(
preferRelativeImports: true,
replaceInRouteName: 'Page,Route',
routes: [
AdaptiveRoute(
page: SplashScreenPage,
initial: true,
fullscreenDialog: true,
),
AdaptiveRoute(
page: LoginPage,
fullscreenDialog: true,
),
AdaptiveRoute(
page: DashboardPage,
),
],
)
class $Router {}This is the starting point of the application. All the application level configurations are defined in this file i.e., theme, routes, title, orientation, etc.
import 'dart:async';
import 'package:easy_localization/easy_localization.dart';
import 'package:flavorbanner/flavor_config.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'app.dart';
import 'core/injection.dart';
Future<void> run({Flavor env = Flavor.DEV}) async {
WidgetsFlutterBinding.ensureInitialized();
await SystemChrome.setPreferredOrientations(<DeviceOrientation>[
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
await EasyLocalization.ensureInitialized();
registerGetIt(env);
FlavorConfig(
flavor: env,
color: Colors.grey,
values: FlavorValues(
baseUrl: 'https://dev.com/',
showBanner: env != Flavor.PROD,
),
);
runApp(
EasyLocalization(
supportedLocales: const [
Locale('en', 'US'),
],
startLocale: const Locale('en', 'US'),
fallbackLocale: const Locale('en', 'US'),
path: 'assets/translations',
child: const MyApp(),
),
);
}
Future<void> main() async {
await run();
}I will be happy to answer any questions that you may have on this approach, and if you want to lend a hand with the boilerplate then please feel free to submit an issue and/or pull request 🙂
Again to note, this example can appear as over-architected for what it is - but it is an example only. If you liked my work, don't forget to ⭐ star the repo to show your support.