Your project structure plays an important part in the application’s development. It helps you and your team mates to navigate and find the piece of code they are searching for, quickly. It also sets the foundation for your applications architecture. People can see a rough overview of your application’s architecture by looking at how the folder hierarchy is structured and how each folder and file is named. It will also help people joining your project to find their way around quickly and know where new files should be added and how they should be named. For example when all your services are under the folder services and their suffix is ‘Service’ they will add new services under that folder and name them accordingly.
With all these benefits of getting your project structure right, the question now is: “What is the right mobx react project structure?”
But sadly the answer is: “Well, it depends”
In the following, I will show you three commonly used mobx react project structures, that will help you make a decision or serve as blueprint.
The projects architecture is based on the best practices from my other article.
The project structure by type
So now we have our stores, services, components and containers. The most simple approach is to structure them by type. So all stores are under stores, services are under services and so on. This leads to the following example structure: The stores reference the services or each other, each container consists of one or more components and each component consists of zero or more other components. One point against this structure is that is doesn’t scale well. When your project grows bigger, implementing a new functionality requires a lot of searching in the project’s structure. Lets say we want to implement a button to remove a todo from the todo list. Now we need the TodoListItem, the TodoStore and the TodoService. In this example it is easy to find those classes, but in a larger project it becomes a tedious task.
- You can quickly find your services, stores or other types, as they lie directly under the root folder.
- Improves reusability. You know exactly what other stores are available. Same for the other types.
- Very easy to learn/understand and to add new classes.
- Because of the very flat structure, your folders (especially the components folder) can grow very large, very quickly.
- Dependencies between components, containers and stores aren’t really visible.
- When the project grows bigger, makes it very hard to find the the stores, services and controllers/components needed to implement a specific feature.
A mixture of type and functionality
In most cases your containers and components folder will grow very quickly. So how can we improve the structure to counteract this? What we did here is take the problematic folders (containers and components) and structure it by function. We add a folder ui that describes the function of its children. Then we structured the ui folder by the components’/containers’ function. We created a folder for all ui components/containers for the login, todos and one for the login. This solution is a mixture of a typed structure (services, stores) and a functional structure (ui subfolders).
- Containers and components now have a better structure and are easier to find.
- Dependencies between components and containers are now more clear (it is forbidden to reference from one functionality (login) to other containers/ components from another functionality (todos, users).
- The dependencies between the ui code and the stores are not clear by looking at the structure.
The project structure by function/modules
So now lets go fully functional. What we did here is put every functionality with all its dependencies in one module folder. So for the login functionality, all containers, components and the store and service are under the same folder. This leads to a clear structure that helps to unterstand which components belong to which store and vise versa.
We can even improve the modularity by adding index.js files to each module, that export only the files, that are allowed to be used outside of the module.
- Now all dependencies are visible.
- Control over the exported files for each bundle (via index.js).
- It is now harder to reuse the business logic in other apps (stores and services), because they are not in a single folder anymore.
- Requires the strongest discipline (only use exported files in other modules, keep dependencies to other modules low)
To sum up, there are many ways to structure your app. There is no right or wrong way. Take the structure you need for your project or let this article inspire you and create your own. I hope this article helps you to improve your project structure for your current or future projects.