Laravel File Structure


When working on applications and websites, we usually follow some type of convention for organizing files and assets that support the site. You might be familiar with how Codeigniter, CakePHP, or your own home grown solutions work. The MVC architecture has been the de facto design standard for some time now. Of course MVC is our Model, View, Controller design pattern that separates Data, Presentation, and Routing apart to make things easier to control. In the past, we would focus on building Fat Models, while keeping the Controllers and Views very skinny. In other words, most of our processing logic got stuffed into a Model, and at times, this can become hard to manage. So how does Laravel handle this? Well, we still have Models, Views, and Controllers in Laravel, but there is a huge degree of flexibility as to how you can organize your projects. The idea is to break apart long rambling logic into small, focused, components and use php namespace and composer autoload to handle the rest. Let’s take a look at an example of how many developers are structuring their projects now.

Start With A Folder in the App Directory

Let’s imagine we are creating a new web application. Where do we begin? We can start by creating a new project in Laravel like so: php laravel.phar new lfs and this will simply create a new Laravel project for us. We chose lfs for Laravel File Structure, but feel free to name yours whatever you like. This will give us a familiar starting point for the project containing
our app, bootstrap, public, and vendor folders. Navigate into the app folder and you’ll see the commands, config, controllers, database, lang, models, start, storage, tests, and views, folders. It is within this app folder where we can place a root directory so to speak, or a domain level container for everything related to your site. This folder would usually be named after your domain, website, or application name. I’ll use Vegibit for this example.

Populate Your Domain Folder

At this point, you have a dedicated folder to hold all of your files that will help power your application. We can think of all the logic you might need for your app and group these things together within their own sub folders here. What we are doing is laying the groundwork for a clean namespace so that autoloading will be easy. For this example we can add folders like Billing, Exceptions, Handlers, Mailers, Repositories, Services, and Utilities. That is a good starting point.

Move Your Models

Optional! This step is optional, but it does seem to be popular at the moment. When we create a new Laravel Application, a model folder is generated to hold all of our Eloquent models. We also get a nice User.php model to get us started with the Laravel Authentication System. What we can do here is take any models that exist in the model folder, and move them to the root of our new domain level folder. So in our case we’ll move User.php into the Vegibit folder. You can even delete the old models folder once this is complete if you like.

Add Your Interfaces and Implementations

Laravel likes to make use of SOLID design principles. The full scope of that is for another episode, but suffice to say, we’ll make use of interfaces and their implementations here. Following this process, we can then create any piece of the application we need. We can start with creating something that can handle our billing. Since these files deal with billing, place them in the Billing folder that we just created above.

  1. Create Your Interface
    The Laravel Interface is a contract that specifies the methods to be used in the implementation of that Interface. Don’t forget to include your namespace! We can create a billing interface just like this:


    namespace VegibitBilling;
    interface BillingInterface {
    	public function bill();
  2. Create Your Implementation
    The interface doesn’t actually do anything, it just sets the contract. Now we have to create some code that will actually do the work for us. We’ll imagine we are using Paypal to handle the billing in this app. Again, don’t forget to include your namespace at the top of the file!


    namespace VegibitBilling;
    class PaypalBilling implements BillingInterface {
        public function bill()
            return 'Billing the user with Paypal';
  3. Update Composer to Autoload
    We need to update our composer.json so that these new classes will load automatically. We’ll use psr-4 in this case. Here is our updated composer.json

        "name": "laravel/laravel",
        "description": "The Laravel Framework.",
        "keywords": ["framework", "laravel"],
        "license": "MIT",
        "require": {
            "laravel/framework": "4.2.*"
        "autoload": {
            "classmap": [
            "psr-4": {
                "Vegibit\": "app/Vegibit"
        "scripts": {
            "post-install-cmd": [
       "php artisan clear-compiled",
       "php artisan optimize"
            "post-update-cmd": [
       "php artisan clear-compiled",
       "php artisan optimize"
            "post-create-project-cmd": [
       "php artisan key:generate"
        "config": {
            "preferred-install": "dist"
        "minimum-stability": "stable"

    Alert! Note the convention of how psr-4 differs from psr-0. With psr-4 we must include the trailing double backslashes after the Vegibit namespace, in addition to specifying the Vegibit namespace as part of the app folder like so "Vegibit\": "app/Vegibit" You’ll also note that we deleted models from the classmap. Run composer dump at the command line.

  4. Test the New Code
    We can now add a simple snippet to our routes.php file to test out our new software!

    Route::get('/billuser', function()
    	$ppb = new VegibitBillingPaypalBilling;
    	echo $ppb->bill();

    When we now visit http://localhost/lfs/public/billuser, we can see that our Billing code is working correctly and outputs, “Billing the user with Paypal”

The Laraway

I see what you did there, Laraway instead of Takeaway. With Laravel, instead of trying to force everything into your models, you can create your own dedicated namespace within your app folder. Once you have that in place you can create as many folders as you need to handle all of the various things that your app will need to do. As long as you keep your namespace declarations and the composer.json file configured properly, it will all just work for you. Very cool indeed!