The reason I started mods-framework was specific. After years of Magento and then time in Laravel, I kept noticing a gap between two useful ideas. Magento treats modules as a first-class part of the application model. Laravel treats packages as extensions, but not quite as plug-in application modules. Those are related but different, and the difference kept bothering me in ways I could not resolve by reaching for an existing tool.
This is not a story about Laravel being bad. Laravel is genuinely good. It is a story about one application architecture pattern that Laravel’s defaults do not naturally support and what I learned from trying to build it.
What Magento taught me about modules
Magento teaches you to think in modules very early.
A Magento module is not just a library or a folder. It is a named unit of application behavior. It can participate in routing, configuration, observers, layout, admin behavior, and domain logic in a way that feels native to the system. The module has a defined place in the application lifecycle. It declares its own configuration. It can be enabled or disabled. It has extension points. When you add a module, you are genuinely extending the application model.
Laravel is more elegant in most ways. But its default application structure still feels more centralized than I wanted for internal platform work. Packages exist and are powerful, but they solve a slightly different problem. Packages are great for building reusable units that install independently across projects. They are less satisfying when what I wanted was an internal application architecture where modules are first-class inside one app, closely integrated with the application bootstrapping, and still structured as clear independent units.
You can force packages into that role — write internal Composer packages, register them with path repositories. But it often feels like optimizing for distribution when the actual need is application modularity. The developer experience bends around the wrong problem.
What I wanted from mods-framework
The core idea was simple: an application should be able to grow as a set of modules, not as an increasingly crowded collection of folders under one app namespace.
A useful module needed to feel complete. It should own its routes, views, configuration, and service provider bootstrapping. It should have a clear place in the application lifecycle. And it should be something you can reason about as a coherent unit — develop, test, and understand it without holding the whole application in your head.
That makes modules more than a code organization strategy. It makes them architectural boundaries. That kind of boundary becomes especially useful when an application grows across several business domains. A module can become the home for a real area of responsibility rather than a loose collection of controllers and models that happen to relate to the same feature.
Importantly, I did not want that modularity only for reuse. I wanted it for clarity. Being able to reuse a module across projects is nice. Being able to understand one part of an application without understanding all of it is what actually matters at scale.
The design decisions
The main design decision in mods was making modules feel native to Laravel while preserving their own structure.
That meant leaning on familiar concepts — service providers, config merging, view namespacing — but giving them a more module-oriented home. A module in mods is not magic. It is a directory with a discoverable structure: routes in one place, views in another, config where the module expects it, a provider that wires everything together. The application knows where to look because the module followed the convention.
The other decision was to keep the work grounded in Laravel rather than building something underneath it. I was not trying to replace what Laravel does well. I was trying to add one architectural style that Laravel’s defaults do not naturally support. Framework work for its own sake holds no appeal. Solving a real application-structure problem that I kept running into does.
What building it taught me
The biggest lesson was that “modular” is much easier to say than to implement well.
The core discovery and registration mechanics were not the hard part. The hard part was everything that follows: how modules get discovered, how they register themselves without creating load-order problems, how they can override or extend behavior in other modules without creating brittle coupling between them, and how the system handles the case where two modules try to own the same thing. Those are the questions that make a module system a framework rather than a folder convention.
I also learned something about developer experience that Laravel had already figured out. If the module system is theoretically clean but awkward to use daily — adding a route requires touching three files, views are hard to locate, the mental overhead of “is this module-level or app-level” slows you down — people will avoid it or work around it. Elegant defaults are genuinely hard to build. Experiencing how hard they are gave me a much stronger appreciation for what Laravel had gotten right.
Honest assessment
mods-framework succeeded in making the problem visible and giving me a concrete place to explore it. It confirmed that the architectural shape I was looking for was real and useful, not just something that sounded appealing in theory.
Where it fell short was also informative. Modular systems are not hard only because of discovery and registration. Every secondary concern becomes part of the architecture: theming, view resolution, asset publishing, inter-module dependencies, upgrade paths, and what happens when a module needs something from another module that has not loaded yet. Building a framework means building the edges as carefully as the core, and the edges are where the complexity lives.
I do not see this as “I built something better than Laravel.” I see it as: I understood a missing architectural pattern deeply enough that I needed to try building it. The experiment sharpened my thinking about modularity, application structure, and the difference between reusable packages and first-class modules more than any amount of reading about it would have.
That directly influenced how I designed things in Laravel afterward — reaching for module-like boundaries even inside conventional app structures, being more deliberate about where service providers lived, treating internal packages with more respect than they usually get.
The mods-framework work also planted the seed for the EAV and application framework work I would do later in Laravel. Once you have built an architectural primitive from scratch, you understand its tradeoffs in a way that makes every future use of it more considered.