At some point, your code will grow beyond just a few files.
You can be a savage and keep them in the root directory, but realistically, you will need to create some folders and organize the files.
But how many folders do you need? Where should each folder go? Should you structure folders by type or by feature? What does that even mean?
In this article, we will cover the three main ways of organizing your code and our recommendation from a decade of experience:
- Folder by type
- Folder by layer
- Folder by feature
Folder by type
Here is an example of a folder-by-type structure for a very small application.
We’re talking about folder structure. But you can’t have a folder structure if you don’t know how and when to separate the logic of your application into different files.
Folder-by-type and actually all the folder structures we will cover work no matter how you separate your logic into files.
Let’s go through each file type starting with the view.
Views
Views are straightforward. This is the UI that you see on the screen.
ViewModels
Each view is tied one-to-one with a ViewModel. The ViewModel contains the business logic for that specific view.
Services
Services are similar to ViewModels because they contain business logic as well. However, the business logic here is used throughout your entire app and not tied to a single view.
Abstractions
Abstractions abstract away external APIs from within our application.
Repositories
Repositories simplify the abstractions into easy-to-use functions throughout our application.
Models
Models are the data classes.
Folder by layer
Folder-by-type is a very simple folder structure and has its place. The issue with this approach is that as the project grows, it is common to have hundreds of files in a single folder, making traversing your codebase a lot harder than it needs to be.
The second option is folder-by-layer, which is similar to folder-by-type, but instead of separating by a “type” of file, you separate it based on the responsibility of that file.
For example, you might have folders for presentation, domain, application, and data layers.
This approach is a little less chaotic than folder-by-type because, within each of those layers, you can separate more.
For example, in the Presentation layer, you might separate it by feature type, such as a login and a counter feature.
This mostly solves the problem of having hundreds of files inside a single folder, but there is another problem.
There are more problems though
Imagine you are working on an authentication feature. Oftentimes, you will be working within multiple files for that feature. If you want to update the ViewModel to include a new function that retrieves data,
Then you need to update the repository to retrieve that data.
Using folder-by-layer, you will have to traverse back up the folder structure, out of the feature within the presentation layer,
out of the presentation layer, into the data layer, and into the feature within the data layer.
Again, for a smaller project, this is not a big deal. But as your codebase grows, it becomes annoying.
So what is the solution? It’s called folder-by-feature.
Folder by feature
Folder by feature is the approach that we teach in the Best Flutter course, but let’s cover it here as well.
In folder by feature, try to keep the folder structure as flat as possible. The root-level folder is focused on the features within the application.
If you have a view, a repository, and a ViewModel specifically for authentication, that goes into an authentication folder.
But not everything can always fit into a feature bucket. For example, utility classes, common widgets, and abstractions can be used throughout your codebase and don’t really belong to a single feature.
To solve this, we’re bringing in some folder-by-type elements that are not part of our folder feature. These things that don’t really fit into a feature go into a folder called core.
The core folder is the only folder that is not a feature, and files within this core folder are separated by the type of file they are.
Now it’s important to know the different structures because the more knowledge you have, the more you can apply and understand for your own circumstances.
Now that you understand folder structure, why not learn how you can handle your entire application without a state management solution using our MVVM architecture?