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.