{"id":13547912,"url":"https://github.com/md-siam/scalable_app_architecture","last_synced_at":"2025-04-02T20:31:11.254Z","repository":{"id":53834051,"uuid":"516851726","full_name":"md-siam/scalable_app_architecture","owner":"md-siam","description":"This is a modular app architecture that can be scalable as the time passes. I will be using the BLoC state-management package. ","archived":false,"fork":false,"pushed_at":"2023-09-19T11:37:17.000Z","size":1820,"stargazers_count":132,"open_issues_count":0,"forks_count":38,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-11-03T16:37:57.336Z","etag":null,"topics":["architecture","bloc","dart","flutter"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/md-siam.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2022-07-22T18:31:38.000Z","updated_at":"2024-07-03T07:30:06.000Z","dependencies_parsed_at":"2024-03-16T17:37:48.807Z","dependency_job_id":"df93a360-2069-4a32-868f-d4d020f54b29","html_url":"https://github.com/md-siam/scalable_app_architecture","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/md-siam%2Fscalable_app_architecture","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/md-siam%2Fscalable_app_architecture/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/md-siam%2Fscalable_app_architecture/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/md-siam%2Fscalable_app_architecture/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/md-siam","download_url":"https://codeload.github.com/md-siam/scalable_app_architecture/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246887935,"owners_count":20850168,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["architecture","bloc","dart","flutter"],"created_at":"2024-08-01T12:01:03.077Z","updated_at":"2025-04-02T20:31:06.245Z","avatar_url":"https://github.com/md-siam.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"\u003cimg src=\"screenshots/badges/built-with-love.svg\" height=\"28px\"/\u003e\u0026nbsp;\u0026nbsp;\n\u003cimg src=\"screenshots/badges/flutter-dart.svg\" height=\"28px\" /\u003e\u0026nbsp;\u0026nbsp;\n\u003ca href=\"https://choosealicense.com/licenses/mit/\" target=\"_blank\"\u003e\u003cimg src=\"screenshots/badges/license-MIT.svg\" height=\"28px\" /\u003e\u003c/a\u003e\u0026nbsp;\u0026nbsp;\n\u003cimg src=\"screenshots/badges/Flutter-3.svg\" height=\"28px\" /\u003e\u0026nbsp;\u0026nbsp;\n\u003cimg src=\"screenshots/badges/dart-null_safety-blue.svg\" height=\"28px\"/\u003e\n\n# Scalable App Architecture - [CodeWithAndrea](https://codewithandrea.com/articles/flutter-project-structure/)\n\n\u003cimg align=\"right\" src=\"screenshots/store_icons/playstore.png\" height=\"200\"\u003e\u003c/img\u003e\n\nThis scalable app architecture design is inspired by [Andrea Bizzotto](https://github.com/bizz84). Full documentation of this design can be found [here](https://codewithandrea.com/articles/flutter-project-structure/). In addition to that, you can use a VSCode extension called [Flutter Feature Scaffolding](https://marketplace.visualstudio.com/items?itemName=KiritchoukC.flutter-clean-architecture) for easily generating the features' folders. This design is using BLoC state-management solution, and for more information on BLoC library, I would strongly suggest you to follow their official [documentation](https://bloclibrary.dev).\n\nThis project contains everything that you will need in order to immediately start developing your highly scaled application. You can also call this folder structure as \u003cb\u003e Feature-first (layers inside features) \u003c/b\u003e design.\n\n\u003cb\u003e\u003ch2\u003e About the folder structure \u003c/h2\u003e\u003c/b\u003e\n\n\u003cimg align=\"left\" src=\"screenshots/folder_structure.png\"\u003e\u003c/img\u003e\n\n```\n    lib/\n    ├── src/\n    │   ├── common_widgets/\n    │   │   └── common_button.dart\n    │   ├── constants/\n    │   │   └── colors.dart\n    │   ├── exceptions/\n    │   │   └── routing_exception.dart\n    │   ├── features/\n    │   │   ├── address/\n    │   │   │   ├── data/\n    │   │   │   │   ├── datasources/\n    │   │   │   │   │   └── address_datasources.dart\n    │   │   │   │   ├── models/\n    │   │   │   │   │   └── address_model.dart\n    │   │   │   │   └── repositories/\n    │   │   │   │       └── address_repositories.dart\n    │   │   │   ├── domain/\n    │   │   │   │   ├── entities/\n    │   │   │   │   │   └── address_entities.dart\n    │   │   │   │   ├── repositories/\n    │   │   │   │   │   └── address_repositories.dart\n    │   │   │   │   └── usecases/\n    │   │   │   │       └── address_usecases.dart\n    │   │   │   └── presentation/\n    │   │   │       ├── bloc/\n    │   │   │       │   ├── address_bloc.dart\n    │   │   │       │   ├── address_event.dart\n    │   │   │       │   └── address_state.dart\n    │   │   │       ├── pages/\n    │   │   │       │   └── address_page.dart\n    │   │   │       └── widgets/\n    │   │   │           └── address_widgets.dart\n    │   │   ├── authentication/\n    │   │   │   └── (...)\n    │   │   ├── cart/\n    │   │   │   └── (...)\n    │   │   ├── checkout/\n    │   │   │   └── (...)\n    │   │   ├── orders/\n    │   │   │   └── (...)\n    │   │   └── products/\n    │   │       └── (...)\n    │   ├── localization/\n    │   │   ├── app_bn.arb\n    │   │   ├── app_en.arb\n    │   │   └── localization.dart\n    │   ├── routing/\n    │   │   └── routing.dart\n    │   └── utils/\n    │       └── utils.dart\n    └── main.dart\n```\n\nYou might notice that some files are just dummy (like api.dart, model.dart).\nThey are placed there just for git to take the folder structure into consideration.\nLeaving those folders empty won't let git to take them into consideration. Since this is mostly a startup project, I was thinking of offering you the standard folder structure from the start. Of course, this may change multiple times, improving every time more and more.\n\n## Why this design pattern?\n\n\u003cimg align=\"right\" src=\"screenshots/layers_design.png\" width=\"350\" \u003e\u003c/img\u003e\n\nThis architecture is made of four distinct layers, each containing the components that our app needs: \u003cbr\u003e\n\n```\n➮ presentation: widgets, states, and controllers\n➮ application: services\n➮ domain: models\n➮ data: repositories, data sources,\n        and DTOs (data transfer objects)\n```\n\nOf course, if we're building just a single-page app, we can put all files in one folder and call it a day. 😎\n\nBut as soon as we start adding more pages and have various data models to deal with, how can we organize all our files in a consistent way?\n\nIn practice, a \u003cb\u003e feature-first \u003c/b\u003e or \u003cb\u003e layer-first \u003c/b\u003e approach is often used.\n\n\u003cb\u003e\u003ch2\u003e Layer-first: Drawbacks \u003c/h2\u003e\u003c/b\u003e\n\nThis approach is easy to use in practice, but \u003cb\u003e doesn't scale very well \u003c/b\u003e as the app grows.\n\nFor any given feature, files that belong to different layers are far away from each other. And this makes it harder to work on individual features because we have to keep jumping to different parts of the project.\n\nAnd if we decide that we want to delete a feature, it's far too easy to forget certain files, because they are all organized by layer.\n\nFor these reasons, the \u003cb\u003e feature-first \u003c/b\u003e approach is often a better choice when building medium/large apps.\n\n\u003cb\u003e\u003ch2\u003e What about shared code? \u003c/h2\u003e\u003c/b\u003e\n\nOf course, when building real apps you'll find that your code doesn't always fit neatly into specific folders as you intended.\n\nWhat if two or more separate features need to share some widgets or model classes?\n\nIn these cases, it's easy to end up with folders called `shared` or `common`, or `utils`.\n\nBut how should these folders themselves be organized? And how do you prevent them from becoming a dumping ground for all sorts of files?\n\nIf your app has 20 features and has some code that needs to be shared by only two of them, should it really belong to a top-level `shared` folder?\n\nWhat if it's shared among 5 features? Or 10?\n\nIn this scenario, there is no right or wrong answer, and you have to use your best judgement on a case-by-case basis.\n\n## What is a `feature`?\n\n\u003cimg align=\"right\" src=\"screenshots/sample_design2.png\"\u003e\u003c/img\u003e\n\n`Feature-first is not about the UI!`\n\nFeature is not about what the user \u003cb\u003esees\u003c/b\u003e, but what the user \u003cb\u003edoes\u003c/b\u003e:\n\n```\n➮ authenticate\n➮ manage the shopping cart\n➮ checkout\n➮ view all past orders\n➮ leave a review\n```\n\nIn other words, a feature is a \u003cb\u003efunctional requirement\u003c/b\u003e that helps the user \u003cb\u003ecomplete a given task\u003c/b\u003e.\n\nAnd using some hints from \u003cb\u003edomain-driven design\u003c/b\u003e, I decided to organize the project structure around the domain layer.\n\nOnce I figured that out, everything fell into place. And I ended up with seven functional areas that you can see on the right.\n\nNote that with this approach is still possible for code inside a given feature to depend on code from a different feature. For example:\n\n```\n➮ the product page shows a list of reviews\n➮ the orders page shows some product information\n➮ the checkout flow requires the user to authenticate first\n```\n\nBut we end up with far fewer files that are shared \u003cb\u003eacross all features\u003c/b\u003e, and the entire structure is much more \u003cb\u003ebalanced\u003c/b\u003e.\n\n## How to do `feature-first`, the right way?\n\nIn summary, the feature-first approach lets us structure our project around the \u003cb\u003efunctional requirements\u003c/b\u003e of our app.\n\nSo here's how to use this correctly in your own apps:\n\n☞ start from the domain layer and identify the model classes and business logic for manipulating them\u003cbr\u003e\n☞ create a folder for each model (or group of models) that belong together\u003cbr\u003e\n☞ within that folder, create the `presentation`, `application`, `domain`, `data` sub-folders as needed\u003cbr\u003e\n☞ inside each sub-folder, add all the files you need\u003cbr\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmd-siam%2Fscalable_app_architecture","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmd-siam%2Fscalable_app_architecture","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmd-siam%2Fscalable_app_architecture/lists"}