Laravel Modules Explained for Beginners

A Laravel Blog module folder containing its own models, controllers, routes, views and migrations

Laravel modules are self-contained feature folders: each one groups the models, controllers, routes, views and migrations for a single feature, such as a blog or billing, in one place. Instead of sorting your code by file type, you sort it by what it does.

This guide explains why modules exist, what changes compared with Laravel's default layout, and how to build your first module in three steps with the nwidart/laravel-modules package. It also covers how a request travels through a module, where teams use this structure, and the two mistakes that undo its benefits.

In short
  • A Laravel module is one folder that holds everything a single feature needs.
  • Modules fix the clutter that builds up when every file shares the default folders.
  • Install nwidart/laravel-modules, run module:make, add your code, then enable the module.
  • Routes, controllers, models and Eloquent work exactly as they normally do.
  • Only split out features that can work and be switched off mostly on their own.
  1. 0:00Intro
  2. 0:20When every file shares one folder
  3. 1:13A module is a feature folder
  4. 1:57Default folders vs modules
  5. 2:42Install laravel-modules with Composer
  6. 3:39Generate a module with Artisan
  7. 4:26Add routes, then enable it
  8. 5:18Follow one request into a module
  9. 6:04One app, three feature modules
  10. 6:48Too small, too tangled
  11. 7:41Laravel modules in six points
  12. 8:09Split only features that truly stand alone

Why do large Laravel apps get messy?

By default, Laravel puts all models in one folder, all controllers in another and all web routes in one file. That layout works well for a small app. Now picture the same app a year after launch, with new features added every few weeks. Each feature adds a few files to every shared folder, and the folders keep growing.

The first problem is that code becomes hard to find. If you need to work on billing, you have to ask which of the many models and controllers belong to billing, because the feature is scattered across the project. You spend time searching instead of building, and new teammates feel this most of all.

The second problem is risk. When unrelated code sits side by side, it is easy to open the wrong file, and a change to one feature can quietly break another. So the mess is more than untidy. It slows the team down and makes every change more nerve-racking.

  • One feature is spread across many folders
  • One small change means opening several places
  • Unrelated code sitting together invites mistakes

What is a Laravel module?

A Laravel module groups all the code for one feature into one self-contained folder. A Blog module, for example, contains its own Models, Controllers, Routes, Views and Migrations. The rule is simple: if it belongs to the blog, it lives in the Blog folder.

Self-contained means the module carries what its feature needs. You can open one folder and understand the whole blog without digging through the rest of the app. That makes it easier to reason about a feature, review changes to it, and hand it to someone new.

A helpful comparison is a kitchen. You keep cutlery in one drawer and spices in another, so you always know where to look. Modules give your codebase the same kind of order: each feature gets its own drawer, rather than every item being sorted only by what kind of thing it is.

Default Laravel folders vs modules

Switching to modules changes where files live, not what they contain. In the default layout, models sit together in app/Models; in a modular layout, each module keeps its own. Controllers move from one shared folder into the feature's folder. Routes go from one large web.php file to a separate routes file per module.

Two everyday tasks change the most. Finding code means opening one folder instead of searching the whole app. Removing a feature means disabling one module rather than hunting down its files one by one.

Underneath, it is still the same Laravel. Eloquent, Blade and routing all work as before. You keep everything you already know and only rethink how your files are organised, which is why modules are approachable even for beginners.

  • Models: app/Models → one set per module
  • Controllers: one shared folder → inside each feature
  • Routes: one big web.php → one routes file per module

How to install laravel-modules with Composer

Laravel does not ship with modules built in, so the first step is adding a package that provides them. The popular choice is nwidart/laravel-modules, which supplies the folder structure, the loading of module code and a set of commands. Open a terminal in your project root and require it with Composer.

Composer is PHP's package manager. It downloads the package, records it in composer.json and sets up autoloading so your app can find module code. The main payoff is new Artisan commands: Laravel's command-line tool can now create modules, enable them and run their migrations.

Setup details can differ slightly between versions, so check the package's installation notes for your Laravel release before going further. Once that is done, you are ready to build your first module.

# from your project root
composer require nwidart/laravel-modules
# adds the module Artisan commands

How to create a module with module:make

With the package installed, one Artisan command creates the whole structure: module:make Blog. It creates a Modules/Blog folder, adds a BlogController, adds a routes/web.php file for the module, and writes a module.json file that tells Laravel the module exists.

A useful way to think about the result is as a mini app. The module has its own controllers, routes, views and database folders, laid out much like a small Laravel project. If you know where things go in a normal Laravel app, you already know your way around a module.

Name each module by feature: Blog, Billing or Users. A name that says what the module does, rather than how it works, tells everyone what belongs inside. That clarity is what keeps a module organised as it grows.

  • Modules/Blog — the feature folder
  • BlogController — a starting controller
  • routes/web.php — the module's own routes
  • module.json — registers the module

Adding routes and migrations, then enabling the module

Step three is filling the empty module with real code. You write the same code you normally would; it just lives inside the module folder. In the Blog module's routes file, a resource route for posts points to PostController, so the blog's URLs and the logic behind them stay inside Blog and your main routes file stays short.

Migrations follow the same idea. The posts table is defined inside the module, so the feature and its data structure travel together. In the terminal, module:enable Blog switches the module on, and module:migrate Blog runs its migrations.

Enabling matters because Laravel only loads enabled modules. That means you can switch a feature off without deleting a single file, which is handy when a feature is unfinished, paused or being retired.

# Modules/Blog/routes/web.php
Route::resource('posts', PostController::class);
# then switch the module on
php artisan module:enable Blog
php artisan module:migrate Blog

How does a request reach a Laravel module?

Follow one visit to /posts. The browser sends the request, Laravel checks the Blog module's routes and finds a match, and the request goes to PostController. The controller asks the Post model for data, and the model reads the posts table in the database. The path is the familiar Laravel one; the files it passes through simply live in one folder.

You do not wire this up by hand. The package registers each enabled module's routes, views and migrations automatically. Routes, controllers and models behave exactly as usual, so for a beginner, modules are mostly about where you put things rather than new concepts to learn.

Where are Laravel modules used?

Modules are most common in larger apps with clearly separate features. Imagine an online service with user accounts, paid plans and a company blog. A customer's request reaches the app, and the router hands it to the right module: Users handles login and profiles, Billing handles invoices and payments, and Blog handles posts and comments. Each module keeps its own tables in the database.

The biggest benefit for teams is clear ownership. Someone working on payments stays in Billing, and someone writing blog features stays in Blog. Because fewer people edit the same files, there are fewer clashes and it is easier to see who is responsible for what.

  • Users: login and profiles
  • Billing: invoices and payments
  • Blog: posts and comments

Common mistakes with Laravel modules

Modules can make a codebase worse if used badly, and two mistakes come up again and again. The first is making modules too small. If you find yourself creating a whole module for one button, stop. Every tiny module adds folders and configuration, and soon your code is scattered across many places again, which is the very problem modules were meant to solve.

The second mistake is tight coupling. If Blog reaches into Billing's models and classes everywhere, the two are not really separate. You cannot change or disable one without breaking the other, and the neat folder boundaries become misleading.

Both mistakes come from splitting code without asking whether the feature truly stands alone. The fix is one question: could this feature work, and be switched off, mostly on its own? If yes, make it a module. If not, leave it where it is.

  • Too small: tiny modules recreate the scattering problem
  • Too tangled: modules depending on each other's internals
  • Test: could it work and be disabled mostly on its own?

Key takeaways

  • Modules group code by feature, so each feature sits in one folder.
  • Shared default folders get crowded and risky as an app grows.
  • Install nwidart/laravel-modules with Composer to get module support.
  • Generate with module:make, add routes and migrations, then enable the module.
  • Laravel itself works the same; only file locations change.
  • Split only features that truly stand alone.

Frequently asked questions

Does Laravel have modules built in?

No. Laravel does not ship with modules, so you add them with a package. The widely used option is nwidart/laravel-modules, installed with Composer.

Do I need to learn new concepts to use Laravel modules?

Not really. Routes, controllers, models, Eloquent and Blade behave exactly as usual. The main change is that each feature's files live together in one module folder.

What does enabling a module do?

Laravel only loads modules that are enabled. Enabling a module, for example with module:enable Blog, switches it on, and disabling it turns the feature off without deleting any files.

Can each module have its own database tables?

Yes. A module can contain its own migrations, so its tables are defined alongside the feature. You run them with a command such as module:migrate Blog.

When should I not use a module?

Skip it for tiny pieces of functionality or for code that depends heavily on another feature's internals. If a feature could not work and be switched off mostly on its own, keep it in the main app.

Are Laravel modules worth it for a small app?

Often not at first. Laravel's default folders work well for small apps; modules start to pay off when the app grows and has clearly separate features.

Watch the full video on YouTube →

Souy Soeng

Souy Soeng

Hi there 👋, I’m Soeng Souy (StarCode Kh)
-------------------------------------------
🌱 I’m currently creating a sample Laravel and React Vue Livewire
👯 I’m looking to collaborate on open-source PHP & JavaScript projects
💬 Ask me about Laravel, MySQL, or Flutter
⚡ Fun fact: I love turning ☕️ into code!

Post a Comment

CAN FEEDBACK
Ad