MasterPHP.in
Laravel Tutorial

Laravel Folder Structure Explained (Deep Dive)


When you create a new Laravel project, the framework generates a complete set of folders and files automatically. If you are coming from Core PHP where you created your own folder structure, this can feel overwhelming at first.

But here is the thing — you do not need to understand every folder on day one. In fact, when building most Laravel applications, you will spend 90% of your time inside just three or four directories. The rest exist for specific purposes you will discover as you go deeper.

This lesson gives you a clear mental map of what each folder does and why it exists. A separate Deep Dive lesson covers the less common directories and files in more detail.


The Top-Level Structure

laravel-project/
│
├── app/
├── bootstrap/
├── config/
├── database/
├── public/
├── resources/
├── routes/
├── storage/
├── tests/
├── vendor/
│
├── .env
├── composer.json
└── artisan

At a glance, this looks like a lot. But each folder has a single, clear responsibility. Once you know what that responsibility is, you will always know where to look.


app/ — Where You Write Your Application Code

This is the most important folder in your entire project. Almost all of the code you write lives here. When you generate a controller, a model, or middleware using Artisan, the files land inside app/.

app/
├── Http/
│   ├── Controllers/    ← your controllers go here
│   └── Middleware/     ← request filters go here
├── Models/             ← your Eloquent models go here
└── Providers/          ← service providers go here

The three subdirectories you will use constantly:

app/Models/ — Each file here represents a database table. When you run php artisan make:model Product, Laravel creates app/Models/Product.php. This class lets you interact with the products table using Eloquent.

app/Http/Controllers/ — Controllers receive incoming requests, call the right model, and return a response. When a user visits /products, a controller method runs and decides what to show them. Controllers are created with php artisan make:controller ProductController.

app/Http/Middleware/ — Middleware are filters that run before a request reaches your controller. The built-in auth middleware checks if the user is logged in. You can create custom middleware for things like checking subscriptions or logging requests.


routes/ — Where You Define Your URLs

Every URL in your Laravel application is defined in the routes/ folder. This is where you tell Laravel: "when someone visits this URL, run this controller method."

routes/
├── web.php    ← routes for browser requests (pages, forms)
└── api.php    ← routes for API endpoints (JSON responses)

web.php is where your website's pages are defined. It handles sessions, cookies, and CSRF protection automatically. This is the file you will use most often when building standard web applications.

// routes/web.php
Route::get('/', [HomeController::class, 'index']);
Route::get('/products', [ProductController::class, 'index']);
Route::get('/products/{id}', [ProductController::class, 'show']);
Route::post('/products', [ProductController::class, 'store']);

api.php is for building API endpoints that return JSON — typically consumed by a mobile app or a JavaScript frontend. Routes defined here automatically get the /api/ prefix, so a route defined as /products in api.php is accessible at /api/products.


resources/ — Your Frontend Files

The resources/ folder holds everything related to what the user sees in their browser.

resources/
├── views/    ← Blade template files (.blade.php)
├── css/      ← your CSS source files
└── js/       ← your JavaScript source files

resources/views/ is where all your Blade templates live. When a controller returns view('products.index'), Laravel looks for the file at resources/views/products/index.blade.php. You will spend a lot of time in this directory building your application's pages.

It is common to organize views into subdirectories that match your application's sections:

resources/views/
├── layouts/
│   └── app.blade.php       ← master layout (header, footer, nav)
├── products/
│   ├── index.blade.php     ← product listing page
│   └── show.blade.php      ← single product page
├── auth/
│   ├── login.blade.php
│   └── register.blade.php
└── dashboard.blade.php


database/ — Your Database Definitions

Everything related to your database structure and test data lives in the database/ folder.

database/
├── migrations/    ← define table structure in PHP
├── seeders/       ← insert sample data into tables
└── factories/     ← generate fake data for testing

migrations/ is where you define your database tables as PHP code. Instead of writing SQL directly in phpMyAdmin, you create a migration file and describe the table structure in PHP. Run php artisan migrate and the table is created. Roll it back with php artisan migrate:rollback if needed.

// database/migrations/2024_01_01_create_products_table.php
Schema::create('products', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->decimal('price', 8, 2);
    $table->string('status')->default('active');
    $table->timestamps();
});

seeders/ let you insert default or sample data into your database. Useful for populating your application with test data during development, or for inserting essential data (like admin user accounts or default categories) when deploying to a new server.

factories/ define how to generate fake but realistic-looking data using the Faker library. Used in combination with seeders or automated tests.


public/ — The Web Server's Entry Point

The public/ folder is the only directory that should be publicly accessible from the internet. Your web server (Nginx or Apache) should point to this directory, not to the root of your project.

public/
├── index.php    ← all requests pass through this file
├── css/         ← compiled CSS (after running npm build)
├── js/          ← compiled JavaScript (after running npm build)
└── images/      ← public images

public/index.php is the entry point for every single request. When a user visits your website, the browser hits this file first. It bootstraps the Laravel framework and hands the request off to the router. You never edit this file directly.

Keeping everything else outside of public/ is a security measure. Your .env file with database credentials, your application code in app/, and your configuration files in config/ are all outside the web root and cannot be accessed directly by a browser.


config/ — Application Configuration

The config/ folder contains PHP files that control how different parts of Laravel behave. Each file covers one area of the application.

config/
├── app.php        ← app name, timezone, locale, debug mode
├── database.php   ← database driver and connection settings
├── mail.php       ← email service configuration
├── cache.php      ← cache driver settings
├── filesystems.php← local and cloud storage configuration
└── queue.php      ← queue driver settings

You rarely edit these files directly. Instead, they read values from your .env file using the env() helper. This keeps sensitive values (passwords, API keys) out of your codebase and in your environment file which is never committed to version control.


storage/ — Generated Files and Logs

The storage/ folder is where Laravel writes files at runtime — things the application generates rather than things you write yourself.

This includes application logs (errors and debug information written to storage/logs/laravel.log), cached Blade templates that Laravel compiles for performance, file uploads from users, and cached configuration and route files generated by Artisan commands.

You will check storage/logs/laravel.log frequently when debugging — it records every error and exception your application encounters.


The .env File — Environment Configuration

The .env file sits at the root of your project and stores environment-specific configuration values — things that differ between your local development machine and your production server.

APP_NAME=MasterPHP
APP_ENV=production
APP_DEBUG=false
APP_URL=https://masterphp.in

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_DATABASE=masterphp
DB_USERNAME=root
DB_PASSWORD=your_password

MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=587

This file is never committed to Git. Each environment (local, staging, production) has its own .env with the right values for that server. This is how the same Laravel codebase can connect to a local database in development and a production database on your server without any code changes.


vendor/ — Third-Party Packages

The vendor/ folder contains all packages installed via Composer — including Laravel itself, and any third-party packages you add to your project. You never edit files in this directory. Composer manages it entirely. When you run composer install on a new server, this folder is regenerated from the composer.json file.


The Three Folders You Will Use Every Day

To summarize where you will actually spend your time as a Laravel developer:

  • app/ — Writing your models, controllers, and middleware
  • resources/views/ — Building your Blade templates
  • routes/web.php — Defining your application's URLs

The other directories — database/, config/, storage/ — come into play for specific tasks like setting up tables, adjusting settings, or checking logs. With time, navigating all of them becomes second nature.

In the next lesson, you will go deeper into the app/ directory and explore the additional folders and files that Laravel adds as your application grows.

Frequently Asked Questions

Yes. As your application grows, you will often add custom folders inside app/ to organize your code — for example, app/Services/ for business logic classes, app/Traits/ for reusable traits, or app/Enums/ for PHP enums. Laravel's autoloading through Composer handles any folder you create inside app/ automatically.
Security. If your web server pointed to the project root, anyone on the internet could potentially access your .env file (which contains your database password), your config/ files, and your application source code. Pointing to public/ means only the files inside that directory are web-accessible — everything else is hidden from browsers.
Never. The .env file contains sensitive credentials — database passwords, API keys, and mail server passwords. Committing it to a public or even private repository is a serious security risk. Laravel includes .env in the default .gitignore file precisely for this reason. Instead, you commit a .env.example file with the same keys but empty values, so other developers know what variables they need to configure.
The artisan file is the entry point for all Artisan commands. When you run php artisan make:controller, PHP executes this file, which bootstraps the framework and runs the requested command. You never edit this file — you only call it from the terminal.

Share this tutorial