/fab

A new advanced flutter boilerplate project uses BLoC.

Primary LanguageDartMIT LicenseMIT

Flutter Advanced Boilerplate

A new (almost) fully featured flutter boilerplate project by using BLoC.

The MotivationKey FeaturesScreenshotsHow To UseFolder StructureChangelog
Good To KnowFAQCommunityPackagesLicense

📝 The Motivation

There are several reasons why this boilerplate exists, these are in short to create clear, readable, reusable, scalable, testable, performant and maintainable projects but in long:

  1. to allow people to deploy production-grade MVP products,
  2. to make sure that I keep everything stupid simple (controversial but I tried my best),
  3. to ensure that project can easily scale horizontally as application grows,
  4. to save developers time by reducing boilerplate code by writing less and generating more,
  5. to maintain code quality and platform standards in team projects with strictly linting rules,
  6. to have bloc and golden tests to verify everything working as intended to be,
  7. to ship the application quickly and efficiently by using CI & CD to automate the development process.

🔥 Key Features

  • API System & Authentication
    Rest and graphql api support with token renewal and socket support using Dio, GraphQL, and Fresh.
  • Performance
    Performance optimized for lag caused by builds, such as page switches or rapid scrolling of complex lists, through frame-splitting rendering via keframe.
  • State Management & Architecture
    BLoC & Hydrated Bloc helps to separate Business Logic from UI by creating persistent and powerful state management.
  • Advanced Linting
    Linting rules with detailed settings to keep the health of the code good and up to the dart standards.
  • Type Safety
    The boilerplate uses type-safety first approach (languages, assets, etc.) to help you avoid problems by catching null errors during development rather than at runtime.
  • Forms
    Creating and managing forms has never been so easy and fun. Reactive forms is a model-driven approach to handling forms inputs and validations.
  • Testing
    The 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 Locator
    Reduce tight coupling between classes thus achieving greater reusability of your code with Injectable and GetIt.
  • Code Generation
    Maximize productivity and improve code quality by generating data classes with Freezed, Artemis, and Build Runner.
  • CI & CD Integration
    CI/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 Routing
    AutoRouter allows for strongly-typed arguments passing, effortless deep-linking, and code generation to simplify routes reduce code boilerplate.
  • Desing Pattern
    Repository design pattern reduces the complexity of the data layer, isolates unstructured data from the rest of the app, and organizes project structure.
  • Exception Handling
    It 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 Storage
    Encrypted storage allows you to keep token and user informations in platforms keychain securely using Secure Storage.
  • Dynamic Theme
    With Android 12 and Material You, wallpaper colors can be extracted to create a ColorScheme that can be used to color the app.
  • Localization
    Easily localize the app into other languages with the support of type-safe structured 'slang' language generator.
  • Permission
    The boilerplate also provides a cross-platform (iOS, Android) API to request permissions and check their status with permission_handler.
  • Env Variables
    Environmental variables allows to define global constants shared in the app, for things like API keys, base URLs, and such.
  • Logging & Tracking
    A detailed logging and error tracking mechanism to monitor every action taking place in the application in real-time with Logging and Sentry.
  • Native Splash
    Flutter Native Splash automatically generates iOS, Android, and Web-native code for customizing this native splash screen background color and splash image.
  • Refresh Rate
    Support for high refresh rate displays with the flutter_displaymode package.

📷 Screenshots

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

🔨 Build

To clone and run this boilerplate, you'll need Git and Flutter installed on your computer. From your command line:

# 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 'VSCode' -> 'Preferences' -> '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' -> 'Preferences' -> 'Editor' -> 'File Types' and paste the below lines under ignore files and folders section:

*.config.dart;*.freezed.dart;*.inject.summary;*.inject.dart;*.g.dart;*.gr.dart;

📁 Folder Structure

Assets Folder

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

The 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

In the 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

The 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

Utils Folder

Apart from the above, constants, helper classes, and methods, shortcuts and many more used throughout the application are located in the utils folder.

.
└── 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

  1. Code with Andrea Tutorials • BlogYouTube
  2. Reso Coder Tutorials • BlogYouTube
  3. Flutter • YouTube
  4. Marcus Ng • YouTube
  5. Flutter Mapp • YouTube
  6. Max on Flutter • YouTube

VSCode Extensions

Extension Usage
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.
Rainbow Brackets Provide rainbow colors for the round brackets, the square brackets and the squiggly brackets. This is particularly useful for Lisp or Clojure programmers, and of course, JavaScript, and other programmers.
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.

📦 Packages

This repository makes use of the following pub packages:

Package Version Usage
dio ^4.0.6 API*
graphql_flutter ^5.1.0 API*
web_socket_channel ^2.2.0 API
internet_connection_checker_plus ^1.0.1 Network
fresh_dio ^0.3.2 Auth*
fresh_graphql ^0.5.2 Auth*
keframe ^3.0.0 Performance*
flutter_bloc ^8.1.1 State & Architecture*
hydrated_bloc ^8.1.0 State Persistance*
very_good_analysis ^3.1.0 Linting*
dart_code_metrics ^4.19.1 Linting*
reactive_forms ^14.1.0 Forms*
injectable ^1.5.4 Dependency Injection*
get_it ^7.2.0 Service Locator*
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*
auto_route ^5.0.2 Routing*
data_channel ^2.0.0+1 Exceptions*
hive_flutter ^1.1.0 Storage*
flutter_secure_storage ^6.0.0 Storage*
slang ^3.3.1 Localization*
permission_handler ^10.2.0 Permission
logger ^1.1.0 Logging*
pretty_dio_logger ^1.2.0-beta-1 Logging*
sentry_flutter ^6.13.1 Tracking*
sentry_dart_plugin ^1.0.0-beta.4 Tracking*
sentry_dio ^6.13.1 Tracking*
statsfl ^2.3.0 Tracking
flutter_displaymode ^0.4.0 Refresh Rate
animations ^2.0.7 Animations
golden_toolkit ^0.13.0 Testing
bloc_test ^9.1.0 Testing
mocktail ^0.3.0 Testing
mocktail_image_network ^0.3.1 Testing
universal_platform ^1.0.0+1 Tool*
json_theme ^4.0.2+2 Tool*
ionicons ^0.2.1 Icons
flutter_staggered_grid_view ^0.6.2 Others
custom_sliding_segmented_control ^1.7.3 Others
url_launcher ^6.1.6 Others
path_provider ^2.0.11 Others*
intl ^0.17.0 Others
http ^0.13.5 Others
infinite_scroll_pagination ^3.2.0 Others
spring_button ^2.0.0 Others
rounded_loading_button ^2.1.0 Others
auto_size_text ^3.0.0 Others*
styled_text ^6.0.0 Others*
shimmer ^2.0.0 Others
url_strategy ^0.2.0 Others
image_picker ^0.8.6 Others

*Recommended to keep regardless of your project.

❓ FAQ

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.

🌸 Community

🔥 Contribution

If you want to say thank you you can;

Also code contributions are always welcome and appreciated.

  1. 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.
  2. Request a feature
    You can also request for a feature, and if it will viable, it will be picked for development.
  3. 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.

If you are new to open-source, make sure to check read more about it here and learn more about creating a pull request here.

🌵 Branches

  1. stage is the development branch.

  2. master is the production branch.

  3. 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

  1. To start working on a new feature, create a new branch prefixed with feat and followed by feature name. (ie. feat-FEATURE-NAME)
  2. Once you are done with your changes, you can raise PR.

Steps to create a pull request

  1. Make a PR to stage branch.
  2. Comply with the best practices and guidelines e.g. where the PR concerns visual elements it should have an image showing the effect.
  3. 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! 😘

🔒 License

MIT © Fikret Şengül