I’m a big fan of writing module-based software, but I’m not so fond of relying on third-party packages for trivial things as they could always prevent you from upgrading. For the two years I have been writing module-based software with Laravel and I’m very happy with the result. The deciding factor that drives me towards module-based software is the possibility for continuous improvement. Imagine you setup a project structure and 6 months later you decide that you made a lot of mistakes. It’s usually not easy to just improve the architecture without affecting the 6 months of existing code. There are two major points that I’ve noticed while analyzing this subject: you either have a standard in your whole project and stick with it or you modularize it and improve module by module. Some people prefer to work with standards at all costs, even if that means being stuck with a standard that you no longer enjoy. Personally, I prefer continuous improvement. If the 20th module that I wrote is 100% different than the 1st one, I don’t mind. If I ever need to go back to Module 1 for a bugfix or refactoring, I can improve it towards the new standards being used by the latest modules. If, like me, you would like to work on a module-based Laravel Application and avoid adding unnecessary third-party dependency to your project, here is how I did it. 1- Route Service Provider Laravel Router system is kind of the entrypoint for the application. The first thing that requires changing is the default that should modularize the available routes. RouteServiceProvider.php We can get rid of the whole boilerplate that comes in that file and just setup one modules router. 2- The modules files Laravel comes with a few files on folder. We can delete them all since we are not mapping them in the RouteServiceProvider anymore. Let’s create a single router file. routes modules.php 3- The Books Module Inside folder, let’s create the . Inside of it we can define the application routes for the Books module. app Modules/Books/routes.php You may opt for Controller-based routing, which has been standard in Laravel. I personally liked the approach. Here is the implementation. Good bye controllers, hello Request Handlers ListBooks The is Laravel’s transformation layer. As the Namespace suggest, we can create it at folder. BookResource app/Modules/Books/Resources 4- The Authors Module Let’s also start the Authors module through the routes file. Notice the namespace indicating we’re now writing files into folder. The Request Handler is also pretty straight forward. app/Modules/Authors Lastly we write the Resource class to transform the response into JSON. Notice here how the Resource is going into another Module to reuse the Book Resource. This is usually a bad thing to do as modules should be completely self-sufficient and only reuse standard classes such as Eloquent Models or generic components designed for reuse on any module. The solution to this problem is to usually copy over the BookResource into the Authors Module, making it possible to change one without breaking the other or vice-versa. I decided to leave this cross-module usage as is to show that although a nice rule of thumb is to keep modules completely isolated from each other, it’s also okay to break that rule if you think that the use-case is simple enough and is unlikely to bring any problems. Always make sure to write tests to cover the features you write to avoid someone else from breaking your app unknowingly. 5- Conclusion Although this is an extremely simple example, I hope it gives the notion that it’s easy to manipulate Laravel standard structure for your own needs. You can change file’s location incredibly easy in order to build a Module-based app. Most of my projects comes with for generic classes that are reusable by any Module; to hold the Eloquent models and database relationships and the folder where we can structure any module-based feature. Here’s a folder structure of an app I’ve recently started working on: App/Components App/Eloquent Modules The notion I want everybody to take away from this is that every module have it’s own set of needs and can have it’s own set of folders/entities/classes. There’s no need to standarize all modules to be exactly the same because some modules are a lot simpler than others and require a lot less structure. This example shows that module provides an API via the Http folder while still providing Artisan commands via the Console. on the other hand is Http-only and required repositories, value-objects (bags) and service classes (paginators) in order to deliver a great value. AccountChurn AccountOverview