Flutter Advanced Boilerplate
A new (almost) fully featured flutter boilerplate project by using BLoC.
📝 The Motivation
There are several reasons why this boilerplate exists, these are in short to create
maintainable projects but in long:
- to allow people to deploy
production-grade MVP products,
- to make sure that I
keep everything stupid simple(controversial but I tried my best),
- to ensure that project can
easily scale horizontallyas application grows,
save developers timeby
reducing boilerplate codeby writing less and generating more,
maintain code quality and platform standardsin team projects with strictly linting rules,
- to have
bloc and golden teststo verify everything working as intended to be,
- to ship the application quickly and efficiently by using
CI & CDto automate the development process.
🔥 Key Features
API System & AuthenticationRest and graphql api support with token renewal and socket support using Dio, GraphQL, and Fresh.
PerformancePerformance optimized for lag caused by builds, such as page switches or rapid scrolling of complex lists, through frame-splitting rendering via keframe.
State Management & ArchitectureBLoC & Hydrated Bloc helps to separate Business Logic from UI by creating persistent and powerful state management.
Advanced LintingLinting rules with detailed settings to keep the health of the code good and up to the dart standards.
Type SafetyThe boilerplate uses type-safety first approach (languages, assets, etc.) to help you avoid problems by catching null errors during development rather than at runtime.
FormsCreating and managing forms has never been so easy and fun. Reactive forms is a model-driven approach to handling forms inputs and validations.
TestingThe more features the app has, the harder it is to test manually. Automated tests help ensure that the app performs correctly before you publish it with Bloc Test, Golden Tookit, and Mocktail.
Dependency Injection & Service LocatorReduce tight coupling between classes thus achieving greater reusability of your code with Injectable and GetIt.
Code GenerationMaximize productivity and improve code quality by generating data classes with Freezed, Artemis, and Build Runner.
CI & CD IntegrationCI/CD is used to continuously deliver code into production, and ensure an ongoing flow of new features and bug fixes via the most efficient delivery method by using Codemagic.
Easy & Clean RoutingAutoRouter allows for strongly-typed arguments passing, effortless deep-linking, and code generation to simplify routes reduce code boilerplate.
Desing PatternRepository design pattern reduces the complexity of the data layer, isolates unstructured data from the rest of the app, and organizes project structure.
Exception HandlingIt is not a very ideal solution to handle exceptions using try and catch at every function, Data Channel provides utility for handling exceptions and data routing.
Encrypted StorageEncrypted storage allows you to keep token and user informations in platforms keychain securely using Secure Storage.
Dynamic ThemeWith Android 12 and Material You, wallpaper colors can be extracted to create a ColorScheme that can be used to color the app.
LocalizationEasily localize the app into other languages with the support of type-safe structured ‘slang’ language generator.
PermissionThe boilerplate also provides a cross-platform (iOS, Android) API to request permissions and check their status with permission_handler.
Env VariablesEnvironmental variables allows to define global constants shared in the app, for things like API keys, base URLs, and such.
Logging & TrackingA detailed logging and error tracking mechanism to monitor every action taking place in the application in real-time with Logging and Sentry.
Native SplashFlutter Native Splash automatically generates iOS, Android, and Web-native code for customizing this native splash screen background color and splash image.
Refresh RateSupport for high refresh rate displays with the flutter_displaymode package.
Dynamic Theme on Mobile
|iOS Light TR||Android System Dark EN|
Dynamic Theme on Web
|Web System Light TR||Web Dark EN|
📚 How To Use
# Clone this repository $ git clone https://github.com/fikretsengul/flutter_advanced_boilerplate # Go into the repository $ cd flutter_advanced_boilerplate # Install dependencies $ flutter pub get # Generate structured language files $ flutter pub run slang # Checks missing and unused translations $ flutter pub run slang analyze # Generate data classes & structured asset files $ flutter packages pub run build_runner build -d # Update goldens & Execute tests $ flutter test --update-goldens # Run the app $ flutter run # Run the app on web $ flutter run -d chrome --web-renderer html (low performance, low download size) $ flutter run -d chrome --web-renderer canvaskit (high performance, high download size) # If you update your splash screen configuration you can regenerate it via $ flutter pub run flutter_native_splash:create
Hide Generated Files
In order to hide generated files, navigate to
'Settings' and search for
'Files: Exclude' and add the following patterns by pressing the
'Add Pattern' button:
**/*.config.dart **/*.freezed.dart **/*.inject.summary **/*.inject.dart **/*.g.dart **/*.gr.dart
In Android Studio, navigate to
'Android Studio' ->
'File Types' and paste the below lines under ignore files and folders section:
📁 Folder Structure
assets folder is located above the lib folder. The assets that is used in the application, environmental settings, fonts, images, translations and more are found here.
. └── assets ├── animations -> put your animated files here eg. lottie ├── configs -> put your env files here │ ├── dev.json -> env that is used for dev │ ├── prod.json -> env that is used for prod │ └── test.json -> env that is used for tes ├── fonts -> put your custom font files here ├── images -> put your image files here └── translations -> put your translation files here ├── en.json └── tr.json
features folder, which is the backbone of the application, was designed using the feature-first structure instead of layer-first because it doesn’t scale very well as the app grows and repository design pattern. The feature-first approach demands that we create a new folder for every new feature that we add to our app. And inside that folder, we can add the repository pattern layers themselves as sub-folders.
. └── lib └── features -> stands for FEATURE FIRST STRUCTURE └── feature_x -> seperate and put your features here ├── blocs -> stands for APPLICATION LAYER │ ├── x_cubit.dart -> seperate and put your logics here │ └── x_state.dart ├── models -> stands for DOMAIN LAYER │ └── x_model.dart -> seperate and put your models here ├── networking -> stands for DATA LAYER │ └── x_repository.dart -> seperate and put your repos here └── presentation -> stands for PRESENTATION LAYER ├── widgets -> seperate and put your widgets here │ └── x_header_widget.dart └── x_screen.dart
modules folder, there are dependency injection registration and initialization processes of third-party modules to ensure that they can be easily accessed and used from within the application.
. └── lib └── modules ├── dependency_injection -> add your modules injection here │ ├── di.dart -> must initialize di first │ └── x_module_di.dart -> example module injection └── x_module -> create folder for your modules └── init_x.dart -> create initialization files here
theme folder contains the necessary theme configuration and settings.
. └── lib └── theme ├── color │ └── app_color_scheme.dart ├── text │ └── app_typography.dart └── app_theme_creator.dart -> theme creation configuration here
Apart from the above, constants, helper classes, and methods, shortcuts and many more used throughout the application are located in the
. └── lib └── utils ├── helpers -> put your helpers here │ ├── bar_helper.dart -> bar helper to show alert │ ├── logging_helper.dart -> logging helper to show fancy log in console │ └── permission_helper.dart -> permission helper to handle permission requests ├── methods -> put your methods here │ └── aliases.dart -> create alias variables here │ └── shorcuts.dart -> add shortcut methods here ├── constants.dart -> configure app constants here ├── navigation.dart -> add navigation destinations here ├── r.dart -> generated type-safe asset classes here (don't modify) └── router.dart -> add new screens here
🌟 Good To Know
Resources I Highly Recommend you to Read & Watch
- Code with Andrea Tutorials • Blog • YouTube
- Reso Coder Tutorials • Blog • YouTube
- Flutter • YouTube
- Marcus Ng • YouTube
- Flutter Mapp • YouTube
- Max on Flutter • YouTube
|Awesome Flutter Snippets||Awesome Flutter Snippets is a collection of commonly used Flutter classes and methods. It increases your speed of development by eliminating most of the boilerplate code associated with creating a widget.|
|Better Comments||The Better Comments extension will help you create more human-friendly comments in your code.|
|bloc||VSCode support for the Bloc Library and provides tools for effectively creating Blocs and Cubits for both Flutter and AngularDart apps.|
|Build Runner||Run build_runner commands conveniently using VSCode.|
|Dart||Dart Code extends VSCode with support for the Dart programming language, and provides tools for effectively editing, refactoring, running, and reloading Flutter mobile apps.|
|Error Lens||ErrorLens turbo-charges language diagnostic features by making diagnostics stand out more prominently, highlighting the entire line wherever a diagnostic is generated by the language and also prints the message inline.|
|Fluent Icons||Product icons themes allow theme authors to customize the icons used in VS Code’s built-in views: all icons except file icons (covered by file icon themes) and icons contributed by extensions.|
|Flutter||This VS Code extension adds support for effectively editing, refactoring, running, and reloading Flutter mobile apps. It depends on (and will automatically install) the Dart extension for support for the Dart programming language.|
|flutter-stylizer||Flutter Stylizer is a VSCode extension that organizes your Flutter classes in an opinionated and consistent manner.|
|GitLens — Git supercharged||GitLens supercharges Git inside VS Code and unlocks untapped knowledge within each repository. It helps you to visualize code authorship at a glance via Git blame annotations and CodeLens, seamlessly navigate and explore Git repositories, gain valuable insights via rich visualizations and powerful comparison commands, and so much more.|
|Min Theme||A minimal theme for VS Code that comes in dark and light.|
|Output Colorizer||Language extension for VSCode/Bluemix Code that adds syntax colorization for both the output/debug/extensions panel and *.log files.|
|Pubspec Assist||Pubspec Assist is a Visual Studio Code extension that allows you to easily add dependencies to your Dart and Flutter project’s pubspec.yaml, all without leaving your editor.|
|Settings Sync||Synchronize Settings, Snippets, Themes, File Icons, Launch, Keybindings, Workspaces and Extensions Across Multiple Machines Using GitHub Gist.|
|Sort lines||Sort lines of text in Visual Studio Code.|
|Terminal||Run terminal command directly in Text Editor|
|Thunder Client||Thunder Client is a lightweight Rest API Client Extension for Visual Studio Code, hand-crafted by Ranga Vadhineni with simple and clean design.|
|Version Lens||This extension shows version information when opening a package or project.|
This repository makes use of the following pub packages:
|flutter_bloc||^8.1.1||State & Architecture*|
|freezed||^2.2.0||Code Generation for Classes*|
|artemis||^7.9.0-beta||Code Generation for GraphQL*|
|build_runner||^2.3.0||Code Generation for Others*|
|json_serializable||^6.5.4||Code Generation for JSON*|
|slang_flutter||^3.3.0||Code Generation for Languages*|
|slang_build_runner||^3.3.0||Code Generation for Languages*|
|r_resources||^1.0.1||Code Generation for Assets*|
*Recommended to keep regardless of your project.
Riverpod is quite popular these days for state management. I am curious to hear your thoughts on bloc and why do you prefer it over the others?
For me, BLoC scales better and is better for larger teams. Riverpod is more like a dependency injection system that also happens to have some state management included. You can totally use blocs or cubits instead of StateNotifier. Others may be;
- If your single screen is so complicated and has so many states then bloc makes code so clean and handles every state easily (especially with the combination of freezed).
- Bloc kinda forces you to separate UI and logic.
- Bloc provides a way to encapsulate your functions with events. That allows you to use event transformers which are so cool. You could make a function concurrent, parallel, debounce, etc. All the while monitoring exactly what each event does and how the state is changed with the help of bloc observers.
- Hydrated bloc is also another cool feature. Just extend hydrated bloc instead of bloc and now you can persist your app state between restarts.
I use go_router. Any particular reason you didn’t use that?
Actually, I have just been using auto_route for several projects and it has been working for me so I stick to it because I already familiar with it. No need to jump the band wagon and do what most or everyone is doing because every day there is an alternative to a package.
If you want to say thank you you can;
Also code contributions are always welcome and appreciated.
- Report a bug If you think you have encountered a bug, and I should know about it, feel free to report it and I will take care of it.
- Request a feature You can also request for a feature, and if it will viable, it will be picked for development.
- Create a pull request It can’t get better then this, your pull request will be appreciated by the community. You can get started by picking up any open issues and make a pull request.
stageis the development branch.
masteris the production branch.
No other permanent branches should be created in the main repository, you can create feature branches but they should get merged with the master.
Steps to work with feature branch
- To start working on a new feature, create a new branch prefixed with
featand followed by feature name. (ie.
- Once you are done with your changes, you can raise PR.
Steps to create a pull request
- Make a PR to
- Comply with the best practices and guidelines e.g. where the PR concerns visual elements it should have an image showing the effect.
- It must pass all continuous integration checks and get positive reviews.
After this, changes will be merged.
Together, we can make this project better every day! 😘
MIT © Fikret Şengül