I was recently exploring flutter and built a very minimal app in a day to try out the framework. I built a minimal app which takes take few inputs from user, add validations, number formatting and show an alert box when user presses submit.
I was amazed by framework itself so I decided to give a try for a medium size application in which we should be able to do following:-
This is basically a mini version of an e-commerce application.
Now, before finalising a folder structure we need to understand a simple thing about scalability; a scalable structure should be so modular that even if that module is removed or changed the application should not break.
I decided to use the similar project structure which I was using for my react-native applications.
So lets get started.
Here is the core folder structure which flutter provides.
flutter-app/|- android|- build|- ios|- lib|- test
Now, lets dive into the lib
folder which has the main code for the application.
screens
— Contains the screens of your application. All files from here get imported into routes.dart
util
— Contains the utilities/common functions of your applicationwidgets
— Contains the common widgets for your applications. For example, Button
, TextField
etc.routes.dart
— Contains the routes of your application and imports all screens.
lib/|- main.dart|- routes.dart|- screens/|- util/|- widgets/|- data/|- services/
SCREENS-
screens/|- auth|- auth.dart|- index.dart|- widgets|- googleButton|- google_button.dart|- google_button_container.dart|- index.dart|- facebookButton|- facebook_button.dart|- facebook_button_container.dart|- index.dart
This screen contains 2 buttons giving user an option to login from Google
or Facebook
.
So, now we know that these 2 buttons are not going to get used anywhere else in the application so we nest them inside this screen.
Widgets
which would be used only inside a particular screen should be placed inside that screen and not inside the common widgets folder.
If you see this nesting really helps in case I wanted to following later on in my code:-
Now, if we go a bit further we see that the button being used in googleButton
and facebookButton
is common and is being used from widgets
folder with only styles being overrided. This makes the button size uniform across the entire application.
widgets/|- button.dart // Common button
UTIL-
util|- date_utils.dart|- format_utils.dart
Util folder contains the business logic of your application. For example, if you are working on an e-commerce application few of them could be:-
WIDGETS-
As I mentioned above widgets would contain the common used across the application.
We follow the same nesting pattern here as we did for screens. The widgets required only by a single widget should be nested inside that widget and should be only accessible to immediate parent.
widgets/|- app_button/|- app_button.dart|- index.dart
DATA-
This folder would come into the picture once you integrate redux(or other) store into the application. Here you would put your reducers, actions etc.
data/|- auth|- access_token|- actions.dart|- reducer.dart|- refresh_token|- actions.dart|- reducer.dart|- reducer.dart
SERVICES-
This would handle all network and business logic of your application. For example, once you are authenticated with facebook/google you need to update backend with access tokens you can place that authentication
in this folder.
services/|- authentication.dart
Well, that is how I structure my mobile applications with flutter.
I would love to here how you guys do it.
I have also created a repository where you can see the actual structure.