{"id":15033793,"url":"https://github.com/flutterando/modular","last_synced_at":"2025-05-13T21:11:34.947Z","repository":{"id":36470155,"uuid":"226731208","full_name":"Flutterando/modular","owner":"Flutterando","description":"A smart project structure","archived":false,"fork":false,"pushed_at":"2025-04-16T15:34:11.000Z","size":8959,"stargazers_count":1331,"open_issues_count":97,"forks_count":260,"subscribers_count":38,"default_branch":"master","last_synced_at":"2025-04-28T17:05:37.032Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/flutter_modular","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Flutterando.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-12-08T21:03:46.000Z","updated_at":"2025-04-27T14:18:49.000Z","dependencies_parsed_at":"2023-02-18T13:31:02.846Z","dependency_job_id":"aff999da-bd20-483c-ae58-41eccd157313","html_url":"https://github.com/Flutterando/modular","commit_stats":{"total_commits":1022,"total_committers":97,"mean_commits":"10.536082474226804","dds":0.4882583170254403,"last_synced_commit":"07d7e8baa2faa0f7b5611c00656cfeeb9d4b0b4e"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flutterando%2Fmodular","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flutterando%2Fmodular/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flutterando%2Fmodular/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flutterando%2Fmodular/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Flutterando","download_url":"https://codeload.github.com/Flutterando/modular/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254029004,"owners_count":22002283,"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":[],"created_at":"2024-09-24T20:22:47.406Z","updated_at":"2025-05-13T21:11:29.933Z","avatar_url":"https://github.com/Flutterando.png","language":"Dart","readme":"\u003ca name=\"readme-top\"\u003e\u003c/a\u003e\n\n\u003c!--\n*** This template was base on othneildrew's Best-README-Template. If you have a suggestion that would make this better, please fork the repo and create a pull request if it's for the template as whole. \n\nIf it's for the Flutterando version of the template just send a message to us (our contacts are below)\n\n*** Don't forget to give his project a star, he deserves it!\n*** Thanks for your support! \n--\u003e\n\n\n  \u003ch1 align=\"center\"\u003eFlutter Modular\u003c/h1\u003e\n\n\n\u003c!-- PROJECT LOGO --\u003e\n\u003cbr /\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://github.com/othneildrew/Best-README-Template\"\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/Flutterando/modular/master/flutter_modular.png\" alt=\"Logo\" width=\"170\" style=\" padding-right: 30px;\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/Flutterando/README-Template/\"\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/Flutterando/README-Template/master/readme_assets/logo-flutterando.png\" alt=\"Logo\" width=\"95\"\u003e\n  \u003c/a\u003e\n\n  \u003cbr /\u003e\n  \u003cp align=\"center\"\u003e\n    Welcome to Flutter Modular!\n    A smart project structure.\n    \u003cbr\u003e\n    \u003cbr\u003e\n    \u003ca href=\"https://modular.flutterando.com.br/docs/intro\"\u003eView Example\u003c/a\u003e\n    ·\n    \u003ca href=\"https://github.com/Flutterando/modular/issues\"\u003eReport Bug\u003c/a\u003e\n    ·\n    \u003ca href=\"https://github.com/Flutterando/modular/issues\"\u003eRequest Feature\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\n\u003cbr\u003e\n\n---\n\n\n\u003c!-- TABLE OF CONTENTS --\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003eTable of Contents\u003c/summary\u003e\n  \u003col\u003e\n    \u003cli\u003e\u003ca href=\"#about-the-project\"\u003eAbout The Project\u003c/a\u003e\u003c/li\u003e\n    \u003col\u003e\n      \u003cli\u003e\u003ca href=\"#what-is-modular?\"\u003eWhat is Modular?\u003c/a\u003e\u003c/li\u003e\n      \u003cli\u003e\u003ca href=\"#ready-to-get-started\"\u003eReady to get started?\u003c/a\u003e\u003c/li\u003e\n      \u003cli\u003e\u003ca href=\"#common-questions\"\u003eCommon questions\u003c/a\u003e\u003c/li\u003e\n    \u003c/ol\u003e\n  \u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#usage\"\u003eUsage\u003c/a\u003e\u003c/li\u003e     \n    \u003col\u003e\n      \u003cli\u003e\u003ca href=\"#starting-a-project\"\u003eStarting a project\u003c/a\u003e\u003c/li\u003e\n      \u003cli\u003e\u003ca href=\"#the-modularApp\"\u003eThe ModularApp\u003c/a\u003e\u003c/li\u003e\n      \u003cli\u003e\u003ca href=\"#creating-the-main-module\"\u003eCreating the Main Module\u003c/a\u003e\u003c/li\u003e\n    \u003c/ol\u003e\n  \u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#contributing\"\u003eContributing\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#contact\"\u003eContact\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#contributors\"\u003eContributors\u003c/a\u003e\u003c/li\u003e\n  \u003c/ol\u003e\n\u003c/details\u003e\n\n---\n\n\u003cbr\u003e\n\n\u003c!-- ABOUT THE PROJECT --\u003e\n## \u003cdiv id=\"about-the-project\"\u003e:memo: About The Project\u003c/div\u003e\n\n\nLet's find out how to implement a Modular structure in your project.\n\n## \u003cdiv id=\"what-is-modular?\"\u003eWhat is Modular?\u003c/div\u003e\n\nModular proposes to solve two problems:\n- Modularized routes.\n- Modularized Dependency Injection.\n\nIn a monolithic architecture, where we have our entire application as a single module, we design our software in a quick and\nelegant way, taking advantage of all the amazing features of Flutter💙. However, producing a larger app in a \"monolithic\" way\ncan generate technical debt in both maintanance and scalability. With this in mind, developers adopted architectural strategies to better divide the code, minimizing the negative impacts on the project's maintainability and scalability..\n\nBy better dividing the scope of features, we gain:\n\n- Improved understanding of features.\n- Less breaking changes.\n- Add new non-conflicting features.\n- Less blind spots in the project's main business rule.\n- Improved developer turnover.\n\nWith a more readable code, we extend the life of the project. See example of a standard MVC with 3 features(Auth, Home, Product):\n\n### A typical MVC\n\n    .\n    ├── models                                  # All models      \n    │   ├── auth_model.dart                     \n    │   ├── home_model.dart                     \n    │   └── product_model.dart         \n    ├── controller                              # All controllers\n    │   ├── auth_controller.dart                     \n    │   ├── home_controller.dart                     \n    │   └── product_controller.dart             \n    ├── views                                   # All views\n    │   ├── auth_page.dart                     \n    │   ├── home_page.dart                     \n    │   └── product_page.dart                   \n    ├── core                                    # Tools and utilities\n    ├── app_widget.dart                         # Main Widget containing MaterialApp \n    └── main.dart                               # runApp \n\n\nHere we have a default structure using MVC. This is incredibly useful in almost every application.\n\nLet's see how the structure looks when we divide by scope: \n\n\n### Structure divided by scope\n\n    .                  \n    ├── features                                 # All features or Modules \n    │   ├─ auth                                  # Auth's MVC       \n    │   │  ├── auth_model.dart   \n    │   │  ├── auth_controller.dart  \n    │   │  └── auth_page.dart                      \n    │   ├─ home                                  # Home's MVC       \n    │   │  ├── home_model.dart   \n    │   │  ├── home_controller.dart  \n    │   │  └── home_page.dart                        \n    │   └─ product                               # Product's MVC     \n    │      ├── product_model.dart   \n    │      ├── product_controller.dart\n    │      └── product_page.dart                    \n    ├── core                                     # Tools and utilities\n    ├── app_widget.dart                          # Main Widget containing MaterialApp \n    └── main.dart                                # runApp \n\n\n\nWhat we did in this structure was to continue using MVC, but this time in scope. This means that\neach feature has its own MVC, and this simple approach solves many scalability and maintainability issues.\nWe call this approach \"Smart Structure\". But two things were still Global and clashed with the structure itself, so we created Modular to solve this impasse.\n\nIn short: Modular is a solution to modularize the route and dependency injection system, making each scope have\nits own routes and injections independent of any other factor in the structure.\nWe create objects to group the Routes and Injections and call them **Modules**.\n\n\n## Ready to get started?\n\nModular is not only ingenious for doing something amazing like componentizing Routes and Dependency Injections, it's amazing\nfor being able to do all this simply!\n\nGo to the next topic and start your journey towards an intelligent structure.\n\n## Common questions\n\n- Does Modular work with any state management approach?\n    - Yes, the dependency injection system is agnostic to any kind of class\n     including the reactivity that makes up state management.\n\n- Can I use dynamic routes or Wildcards?\n    - Yes! The entire route tree responds as on the Web. Therefore, you can use dynamic parameters,\n     query, fragments or simply include a wildcard to enable a redirect\n     to a 404 page for example.\n\n- Do I need to create a Module for all features?\n    - No. You can create a module only when you think it's necessary or when the feature is no longer a part of\n    the scope in which it is being worked on.\n\n\n## \u003cdiv id=\"usage\"\u003e✨ Usage\u003c/div\u003e\n\n**flutter_modular** was built using the engine of **modular_core** that's responsible for the dependency injection system and route management. The routing system emulates a tree of modules, just like Flutter does in it's widget trees. Therefore we can add one module inside another one by creating links to the parent module.\n\n## \u003cdiv id=\"starting-a-project\"\u003eStarting a project\u003c/div\u003e\n\nOur first goal will be the creation of a simple app with no defined structure or architecture yet, so that we can study the initial components of **flutter_modular**\n\nCreate a new Flutter project:\n```\nflutter create my_smart_app\n```\n\nNow add the **flutter_modular** to pubspec.yaml:\n```yaml\n\ndependencies:\n  flutter_modular: any\n\n```\n\nIf that succeeded, we are ready to move on!\n\n\u003e**💡 TIP:** Flutter's CLI has a tool that makes package installation easier in the project. Use the command: \n\u003e`(flutter pub add flutter_modular)`\n\n## \u003cdiv id=\"the-modularApp\"\u003eThe ModularApp\u003c/div\u003e\n\nWe need to add a **ModularApp** Widget in the root of our project. MainModule and MainWidget will be created in the next steps, but for now let's change our **main.dart** file:\n\n```dart title=\"lib/main.dart\"\n\nimport 'package:flutter/material.dart';\n\nvoid main(){\n  return runApp(ModularApp(module: /*\u003cMainModule\u003e*/, child: /*\u003cMainWidget\u003e*/));\n}\n\n```\n\n**ModularApp** forces us to add a main Module and main Widget. What are we going to do next?\nThis Widget does the initial setup so everything can work as expected. For more details go to **ModularApp** doc.\n\n\u003e**💡 TIP:** It's important that **ModularApp** is the first widget in your app!\n\n\n## \u003cdiv id=\"creating-the-main-module\"\u003eCreating the Main Module\u003c/div\u003e\n\nA module represents a set of Routes and Binds.\n- **ROUTE**: Page setup eligible for navigation.\n- **BIND**: Represents an object that will be available for injection to other dependencies.\n\nWe'll see more info about these topics further below.\n\nWe can have several modules, but for now, let's just create a main module called **AppModule**:\n\n```dart title=\"lib/main.dart\" {8-16}\nimport 'package:flutter/material.dart';\nimport 'package:flutter_modular/flutter_modular.dart';\n\nvoid main(){\n  return runApp(ModularApp(module: AppModule(), child: \u003cMainWidget\u003e));\n}\n\nclass AppModule extends Module {\n  @override\n  List\u003cBind\u003e get binds =\u003e [];\n\n  @override\n  List\u003cModularRoute\u003e get routes =\u003e [];\n}\n```\n\nNote that the module is just a class that inherits from the **Module** class, overriding the **binds** and **routes** properties.\nWith this we have a route and injection mechanism separate from the application and can be both applied in a global context (as we are doing) or in a local context, for example, creating a module that contains only binds and routes only for a specific feature!\n\nWe've added **AppModule** to ModularApp. Now we need an initial route, so let's create a StatelessWidget to serve as the home page.\n\n```dart title=\"lib/main.dart\" {14,18-27}\nimport 'package:flutter/material.dart';\nimport 'package:flutter_modular/flutter_modular.dart';\n\nvoid main(){\n  return runApp(ModularApp(module: AppModule(), child: \u003cMainWidget\u003e));\n}\n\nclass AppModule extends Module {\n  @override\n  List\u003cBind\u003e get binds =\u003e [];\n\n  @override\n  List\u003cModularRoute\u003e get routes =\u003e [\n    ChildRoute('/', child: (context, args) =\u003e HomePage()),\n  ];\n}\n\nclass HomePage extends StatelessWidget {\n  Widget build(BuildContext context){\n    return Scaffold(\n      appBar: AppBar(title: Text('Home Page')),\n      body: Center(\n        child: Text('This is initial page'),\n      ),\n    );\n  }\n}\n```\n\nWe've created a Widget called **HomePage** and added its instances in a route called **ChildRoute**.\n\n\u003e**💡 TIP:** There are two ModularRoute types: **ChildRoute** and **ModuleRoute**.\n \u003e- **ChildRoute**: Serves to build a Widget.\n \u003e- **ModuleRoute**: Concatenates another module.\n\n\u003c!-- CONTRIBUTING --\u003e\n## \u003cdiv id=\"contributing\"\u003e🧑‍💻 Contributing\u003c/div\u003e\n\nContributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.\n\nIf you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the appropriate tag.\nDon't forget to give the project a star! Thanks again!\n\n1. Fork the Project\n2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)\n3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)\n4. Push to the Branch (`git push origin feature/AmazingFeature`)\n5. Open a Pull Request\n\nRemember to include a tag, and to follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) and [Semantic Versioning](https://semver.org/) when uploading your commit and/or creating the issue.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\u003c!-- CONTACT --\u003e\n## \u003cdiv id=\"contact\"\u003e💬 Contact\u003c/div\u003e\n\nFlutterando Community\n- [Discord](https://discord.gg/MKPZmtrRb4)\n- [Telegram](https://t.me/flutterando)\n- [Website](https://www.flutterando.com.br)\n- [Youtube Channel](https://www.youtube.com.br/flutterando)\n- [Other useful links](https://linktr.ee/flutterando)\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\n\u003cbr\u003e\n\n\u003c!-- CONTRIBUTORS --\u003e\n## \u003cdiv id=\"contributors\"\u003e👥 Contributors\u003c/div\u003e\n\n\u003ca href=\"https://github.com/Flutterando/modular/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=flutterando/modular\" /\u003e\n\u003c/a\u003e\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\u003c!-- MANTAINED BY --\u003e\n## 🛠️ Maintaned by\n\n\u003cbr\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.flutterando.com.br\"\u003e\n    \u003cimg width=\"110px\" src=\"https://raw.githubusercontent.com/Flutterando/README-Template/master/readme_assets/logo-flutterando.png\"\u003e\n  \u003c/a\u003e\n  \u003cp align=\"center\"\u003e\n    This fork version is maintained by \u003ca href=\"https://www.flutterando.com.br\"\u003eFlutterando\u003c/a\u003e.\n  \u003c/p\u003e\n\u003c/p\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflutterando%2Fmodular","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflutterando%2Fmodular","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflutterando%2Fmodular/lists"}