Directory Structure

Open a freshly generated Laravel project and you'll see a couple dozen top-level folders and files. None of it is arbitrary — every folder has one clear responsibility, and knowing what lives where means you'll always know exactly which file to open for a given change. This page is a complete reference to that layout, a closer look inside the app/ folder specifically, and a quick walk through how a request actually flows through all of it.

1. Top-Level Folder Reference

FolderPurpose
app/Your application's own code: Models, Http/Controllers, Providers, and more. This is where you'll spend most of your time.
bootstrap/The bootstrapping/startup logic that wires up the framework on every request, plus a cache/ subfolder for framework-generated cache files. You'll rarely need to touch this directly.
config/Every configuration file for the application, one per subsystem — app.php, database.php, mail.php, queue.php, and so on. Most values here simply read from .env.
database/Database migrations/ (version-controlled schema changes), factories/ (fake model data for testing/seeding), and seeders/ (scripts that populate the database with initial data).
public/The web server's document root. Only index.php (the single entry point for every request) and built/compiled front-end assets live here — nothing else in the project is web-accessible.
resources/Blade view templates, raw uncompiled CSS/JS/Sass before a build step processes them, and language/localization files.
routes/All route definitions, split by context: web.php, api.php, console.php, and channels.php.
storage/Framework-generated logs, compiled Blade views, cache files, sessions, and any files your application stores (uploads, generated PDFs, etc.). Needs to be writable by the web server.
tests/PHPUnit (or Pest) tests, typically split into Feature/ and Unit/ subfolders — covered in depth in the Testing lesson later in this track.

2. Routes, Split by Purpose

The four files inside routes/ aren't just an arbitrary split — each one is loaded under different default settings:

// routes/web.php   - browser-facing routes, session + CSRF protection enabled
// routes/api.php   - stateless routes, prefixed with /api automatically
// routes/console.php - closure-based Artisan commands
// routes/channels.php - broadcasting/WebSocket channel authorization

The Routing lessons that follow focus almost entirely on web.php, since that's where the vast majority of a typical application's routes live.

3. A Closer Look Inside app/

app/ is where nearly all of your own code lives, and it's organized by role rather than by feature:

SubfolderContains
app/Http/Controllers/Controller classes — the entry point that receives a routed request and decides what response to send back. Covered fully in the Controllers lesson.
app/Models/Eloquent model classes, one per database table (typically) — User.php, Article.php, etc. Covered starting in the Eloquent ORM Basics lesson.
app/Providers/Service provider classes, the central place where the framework and your own services get bootstrapped and registered. Covered in the Service Providers lesson.
Tip: As an app grows, it's common to add more folders under app/ yourself — app/Services/, app/Http/Requests/, app/Policies/, and similar. Laravel doesn't force a single "correct" structure beyond the defaults it ships with.

4. The Request Lifecycle, at a High Level

Every single request to a Laravel application — whether it's a browser loading a page or an API client hitting an endpoint — passes through the same basic pipeline:

StepWhat happens
1public/index.php receives the request — this is the single, universal entry point for the entire application.
2The framework bootstraps itself: the service container is built, service providers are registered and booted (config, routing, database connections, etc. all become available).
3The router matches the incoming URL and HTTP verb against the definitions in routes/web.php or routes/api.php.
4Any middleware assigned to that route runs — authentication checks, CSRF verification, and so on (covered fully in the Middleware lesson).
5The matched route's closure or controller method executes and builds a response — often by returning a Blade view or JSON data.
6The response travels back out through the middleware, and is finally sent to the browser/client.

5. Why public/ Being the Only Web Root Matters

It's worth calling out explicitly: your web server (Apache, Nginx, or Laravel's own dev server) should only ever be configured to serve files from public/. Every other folder — app/, config/, routes/, storage/, even your .env file — sits outside the web root entirely.

Why this matters: if your .env file (with real database credentials) or your raw application source lived inside the web root the way it might on a naive hand-rolled PHP site, a misconfigured server could serve those files directly to anyone who requested them by URL. Because Laravel only exposes public/, that entire class of accidental-exposure bug is designed out of the framework from the start.
Up next: With the layout clear, Routing Basics starts writing real routes inside routes/web.php.