skip to content

Directory Layout

The folders of a Laravel app: app/, bootstrap/, config/, routes/, storage/, and public/ as the only web root, slimmed down in Laravel 11. Interviewers ask where code goes and what is exposed.

on this pageshow

explore

questions

5

In a fresh Laravel 13 application, what belongs in app, bootstrap, config, database, public, resources, routes and storage?

level: juniorimportance: must knowfreq 60%

answer

  1. source code vs framework-generated files
  2. app/ starts with Http, Models, Providers
  3. bootstrap/app.php and bootstrap/cache
  4. public/index.php is the only entry point
  5. storage/app, framework, logs

basics

~20 s

app holds your classes, bootstrap boots the framework and keeps its caches, config holds settings arrays, database holds migrations, factories and seeders, public is the web root, resources holds views and raw assets, routes the route files, storage runtime files and logs.

solid answer

~40 s

`app/` is the `App\` namespace and holds almost all of your classes; a new Laravel 13 app has only `Http/Controllers`, `Models` and `Providers`. `bootstrap/` holds `app.php`, which configures and creates the application, `providers.php`, the list of your service providers, and `cache/` for framework-generated files. `config/` holds PHP files that return settings arrays. `database/` holds migrations, factories, seeders and the default `database.sqlite`. `public/` is the web root, with the `index.php` front controller and compiled assets. `resources/` holds Blade views and un-compiled CSS and JavaScript. `routes/` holds `web.php` and `console.php`. `storage/` holds what the app writes at runtime: `app/` for your files, `framework/` for compiled views, file sessions and caches, and `logs/`. Beside them sit `tests/` and `vendor/`.

go deeper

for a junior

Name each top-level folder and what goes in it, and remember that app/ starts with only Http, Models and Providers.

for a middle

Explain which folders hold source and which hold generated output, and how bootstrap/app.php and bootstrap/providers.php replace the old kernel files.

for a senior

Use the split between source, generated and public folders to decide what is committed, what must be writable and what the web server may expose.

for a principal

Decide how far a large codebase may depart from the default layout, and write the convention down so new modules land in predictable places.

## Why the layout matters A Laravel application is a Composer project with a fixed set of top-level folders. Knowing which folder holds **source code you edit**, which holds **files the framework generates**, and which is **exposed to the web** answers most "where does this go?" questions on a team building, for example, a school-timetable app. ## The folders one by one | Folder | Holds | Edited by | |---|---|---| | `app/` | Your classes, namespaced `App\` | You | | `bootstrap/` | `app.php`, `providers.php`, `cache/` | You (the two files); the framework (`cache/`) | | `config/` | One PHP file per settings group, each returning an array | You | | `database/` | `migrations/`, `factories/`, `seeders/`, `database.sqlite` | You | | `public/` | `index.php`, `.htaccess`, favicon, built assets | You and the build | | `resources/` | `views/`, `css/`, `js/` | You | | `routes/` | `web.php`, `console.php` | You | | `storage/` | `app/`, `framework/`, `logs/` | The running app | | `tests/` | Feature and unit tests | You | | `vendor/` | Composer dependencies | Composer | ## `app/`: small at first, grown on demand A fresh Laravel 13 app ships only three folders inside `app/`: - `Http/Controllers/` with an empty abstract base `Controller`; - `Models/` with the `User` model; - `Providers/` with `AppServiceProvider`. Everything else (`Console/Commands`, `Jobs`, `Events`, `Listeners`, `Mail`, `Notifications`, `Policies`, `Rules`, `Exceptions` and more) **does not exist until you create a class there**, usually with a `make:*` generator. The folder is PSR-4 autoloaded as `App\`, so you may also add folders of your own. ## `bootstrap/` and `config/` - `bootstrap/app.php` builds the application with `Application::configure()` and chained `with*` calls, replacing the kernel classes older apps kept in `app/`. - `bootstrap/providers.php` returns the array of your service providers. - `bootstrap/cache/` is written by the framework (for example the package and services manifests); its `.gitignore` keeps the folder in Git but ignores the files. - `config/` ships ten files (`app`, `auth`, `cache`, `database`, `filesystems`, `logging`, `mail`, `queue`, `services`, `session`); others are published when you need them. ## `public/`, `resources/` and `routes/` 1. `public/` is the **only** folder a web server should expose. `public/index.php` loads the autoloader, requires `bootstrap/app.php` and hands the request to the application. 2. `resources/views/` holds Blade templates (the skeleton has `welcome.blade.php`), and `resources/css` and `resources/js` hold the un-compiled sources that the front-end build turns into files under `public/build`. 3. `routes/web.php` holds browser routes and `routes/console.php` holds closure commands and schedules; API and broadcasting route files are added only when you opt in. ## `storage/`: what the app writes - `storage/app/` for files your code stores, split into `private/` and `public/`. - `storage/framework/` for framework output: `cache/data` (file cache), `sessions` (file sessions), `views` (compiled Blade), `testing`, plus maintenance-mode files. - `storage/logs/` for `laravel.log` with the default channels. Every one of these is ignored by Git except its placeholder `.gitignore`, and all of `storage/` must be writable by the PHP process. ## Worked example: one feature across the folders Adding a "publish the weekly timetable" feature to the school-timetable app touches most of the tree: - `app/Models/Lesson.php` and `app/Http/Controllers/TimetableController.php` hold the classes; - `database/migrations/` gains a `create_lessons_table` migration, `database/factories/` a factory and `database/seeders/` demo data; - `routes/web.php` gets `GET /timetable`, and `resources/views/timetable/week.blade.php` renders it; - `resources/css/app.css` gains styles that the build writes into `public/build`; - at runtime the compiled view appears in `storage/framework/views` and any errors in `storage/logs/laravel.log`. Nothing in `bootstrap/`, `config/` or `vendor/` needs to change for an ordinary feature, which is a quick sanity check when reviewing a pull request. ## Common misreadings - `resources/` is not public; browsers only reach what ends up in `public/`. - `config/` is not the place for secrets; the files read them from the environment. - `app/Http/Kernel.php` is not missing by accident; Laravel 11 and later skeletons do not have it.

  • Why does a fresh Laravel 13 app have no app/Console or app/Jobs folder?
    The skeleton ships only the folders its own classes need: `Http/Controllers`, `Models` and `Providers`. Other folders appear when you create a class in them, typically through a `make:*` command, so `app/Jobs` exists after your first job class. Because `app/` is autoloaded as `App\`, a folder you create by hand works the same way.
  • What is the difference between resources/js and public/build in a Laravel 13 app?
    `resources/js` (and `resources/css`) hold the source files you edit; they are never served directly. The front-end build compiles them into hashed files under `public/build`, which the web server can serve. The skeleton's `.gitignore` excludes `public/build`, so built assets are produced by the build step, not committed.

saying these in an interview costs you the question

  • Blade views live in public/ so the browser can load them
  • storage/ is for source code you want to keep private
  • A new app already has folders for jobs, events and policies
  • config/ files should hold the production passwords directly
  • bootstrap/cache files belong in version control
open as a page

In Laravel 13, where do you configure what app/Http/Kernel.php, app/Console/Kernel.php and app/Exceptions/Handler.php used to hold?

level: middleimportance: must knowfreq 50%

basics

~10 s

Since Laravel 11 the skeleton has no kernel or handler classes. Middleware and exception handling are configured in bootstrap/app.php, schedules and closure commands go in routes/console.php, command classes in app/Console/Commands, and providers in bootstrap/providers.php.

open as a page

Why must a Laravel 13 app's web server document root point at public/, and what leaks if it points at the project root instead?

level: juniorimportance: should knowfreq 45%

basics

~20 s

public/ holds only the front controller index.php and assets, so every request goes through Laravel. Serving the project root lets browsers request files like .env with credentials and APP_KEY, storage/logs/laravel.log, composer.json and vendor code directly.

open as a page

In a Laravel 13 school-timetable app, where should a stray helper file of timetable functions live, and what does Laravel need to find it?

level: middleimportance: should knowfreq 36%

basics

~20 s

Turn it into a class under app/, for example app/Support/TimetableFormatter.php in the App\Support namespace; PSR-4 autoloading of App\ finds it with no registration. Global functions need Composer files autoloading, and config/, routes/, bootstrap/ and public/ are the wrong places.

open as a page

Why would a Laravel 13 app deployed from an image that dropped empty folders fail every page with 'Please provide a valid cache path', and what is missing?

level: seniorimportance: should knowfreq 28%

basics

~10 s

storage/framework/views is missing. The view config sets the compiled path to realpath(storage_path('framework/views')), which is false for a missing folder, so the Blade compiler throws. Recreate the storage and bootstrap/cache tree, writable by PHP.

open as a page