Brieflyn
Navigation Menu
Home › Tutorials & How-To › Laravel Folder Structure: Master Your Project Layout in 2026

Laravel Folder Structure: Master Your Project Layout in 2026

Laravel Folder Structure: Master Your Project Layout in 2026
By Brieflyn Editorial Team • Published: August 16, 2026 • 15 min read (2,931 words) • 12 views
Discover how to design a Laravel Folder Structure that boosts performance, simplifies onboarding, and scales with your team in 2026. Follow step‑by‑step guide.

Laravel folder structure diagram showing default directories and custom feature-based layout in 2026

The Laravel folder structure is the blueprint that keeps a PHP application readable, testable, and ready to scale. In 2026, with Laravel 11, 12, and the upcoming 13 release, the framework ships a leaner default tree than ever before, yet most teams still debate whether to keep the conventions or reorganize around features, domains, or Docker services. This guide walks through the default Laravel folder structure, the patterns that actually pay off, the trade-offs of going custom, and the tooling (Laradocs, Octane, Docker Compose, Traefik) that interacts with every directory you touch.

Overview: What is Laravel Folder Structure?

What is Laravel Folder Structure?

At its core, the Laravel folder structure is a convention-over-configuration layout that mirrors the MVC pattern. The framework groups controllers, models, views, routes, tests, configuration, and bootstrap files into predictable directories. The default tree includes app/, bootstrap/, config/, database/, public/, resources/, routes/, storage/, tests/, and vendor/, each with a specific responsibility that any Laravel developer can recognize in seconds.

Definition: Laravel folder structure refers to the default and customized directory hierarchy of a Laravel project, defining where controllers, models, views, routes, tests, configs, and infrastructure files live so the framework, Composer, Artisan, and the broader PHP ecosystem can autoload, cache, and deploy them predictably.

Why It Matters for Modern Development

A clear folder layout is not just aesthetic. It determines how fast new engineers onboard, how safely your CI pipeline runs, and how cleanly you can containerize each service. When the structure mirrors your team's mental model, code review cycles shorten, autoloading stays fast, and debugging with php artisan becomes straightforward. When it does not, you spend hours hunting for a misplaced service class or fighting a Docker volume that points to the wrong host directory.

Quick Takeaway

Default structure works for solo projects and small teams. Custom layouts (feature-based, domain-driven, modular) start paying off once you cross roughly five developers or need to ship multiple business capabilities from one repository. Whatever you choose, document it, version-control it, and let your tooling (Composer autoloading, Laradocs, Docker volumes) know about it.

Why It Matters in 2026

Flat lay of a closed laptop, notebook, and tablet on neutral surface.
Photo by Mikhail Nilov via Pexels. Laravel Folder Structure Technology.

PHP 8.2+, Laravel 11/12, and the preview of 13 have shifted the folder story. Laravel 11 ships with fewer default files than any previous version, while remaining fully compatible with the Laravel 10 application structure for projects that need to migrate gradually.

Current Trends in the PHP Ecosystem

The wider PHP community has rallied around Package Development Standards (PDS) for clean per-package layouts, while Laravel itself doubles down on PSR-4 autoloading and PSR-12 coding style. Adoption of long-running runtimes like Swoole, RoadRunner, and FrankenPHP through Laravel Octane changes how the storage/ and bootstrap/cache/ directories behave, because the framework stays in memory between requests.

Impact on Team Collaboration

Modern Laravel teams ship faster when the folder structure maps to team boundaries. A feature-based layout means the payments team owns app/Features/Payments/ end to end, including its controllers, jobs, policies, and tests. A domain-driven approach takes this further by adding bounded contexts and shared kernels. Either pattern reduces merge conflicts and clarifies ownership more than a flat MVC tree ever could.

Performance and Scalability Considerations

Folder choices affect runtime performance in subtle ways. Autoloader maps grow with the number of PSR-4 namespaces you register, so deeply nested or fragmented structures can slow Composer's optimized classmap. On the positive side, running Octane with FrankenPHP can reduce framework rebuild time from 40-60 ms to 4-6 ms per request, a 10x improvement that turns folder structure from a stylistic choice into a lever for scale.

Prerequisites and Requirements

Before you reorganize a single directory, lock down the environment that will load, cache, and serve your application.

Laravel Version Compatibility

Pick a Laravel version that matches your team's PHP runtime. Laravel 11 requires PHP 8.2 or higher, Laravel 12 raises that floor to 8.2 with 8.3+ recommended, and the 13 line in 2026 expects PHP 8.3 at minimum. If you are maintaining a legacy codebase on Laravel 10, the official upgrade guide walks through directory, middleware, and route changes that affect every file in app/Http.

Development Environment Essentials

You will need Composer for dependency management, Git for version control, a working PHP CLI with the right extensions, and either Node.js (for front-end assets) or a separate SPA build pipeline. The DotEnv library powers the .env file that holds every environment variable, from database credentials to API keys. Never commit .env; rely on .env.example as the shareable template.

Docker Compose Basics

Containerizing Laravel is no longer optional for production-grade work. A modern docker-compose.yml typically isolates the web server, queue worker (Horizon), scheduler, Redis cache, and database into separate containers, with Traefik acting as the reverse proxy. This separation is what eliminates system pollution and lets you rebuild only the service that changed.

Default Laravel Folder Layout

A plain cardboard folder against a white background, perfect for design mockups.
Photo by https://kaboompics.com/ via Pexels. Laravel Folder Structure Concept.

Laravel's stock structure has been refined over a decade. The 2026 default still feels familiar to anyone who started with Laravel 4, but with sharper boundaries and a much smaller surface area.

Core Directories Explained

  • app/ holds the application code: HTTP controllers, models, console kernels, and service providers. Subdirectories like app/Http/Controllers, app/Models, and app/Providers keep concerns separated.
  • bootstrap/ contains app.php, which is where you now configure middleware, routing, and exception handling using fluent methods like withMiddleware().
  • config/ stores every configuration file the framework reads. Values are merged with .env at boot.
  • database/ keeps migrations, seeders, and factories. The database.sqlite default makes zero-config local development painless.
  • public/ is the web server's document root. It contains index.php, compiled assets, and the build/ folder for Vite output.
  • resources/ holds Blade templates, raw CSS or JS, and language files.
  • routes/ defines HTTP and console entry points: web.php, api.php, console.php, and (in Laravel 11+) channel definitions for broadcasting.
  • storage/ is the writable scratchpad for logs, cached views, sessions, and uploaded files.
  • tests/ splits unit and feature tests into Unit/ and Feature/ subfolders, each with its own base TestCase.

File Naming Conventions

Studly case for classes, snake_case for configuration keys and method names, and kebab-case for route URIs. The php artisan make: family (for example, make:controller, make:model, make:test) enforces these conventions automatically, which is why most teams resist manual file creation in app/.

Typical Use Cases

The default layout is ideal for SaaS MVPs, internal tools, content sites, and APIs under roughly 50 routes. It also matches every Laravel tutorial, course, and AI coding assistant's expectation, which makes debugging easier when you copy a snippet from a Laravel News post or a Packagist README.

Customizing the Folder Structure

Customization is where Laravel stops feeling generic and starts reflecting your business.

When to Re-organize

Reorganize when you find yourself scrolling through app/Http/Controllers hunting for the right file, when onboarding a new engineer takes more than a day, or when two teams keep clobbering each other's PRs. The signs are social before they are technical.

Modular Architecture Patterns

Modular patterns treat each business capability (Billing, Inventory, Notifications) as a self-contained package with its own routes, controllers, models, tests, and even service provider. Packages like Packagist distribution make this trivial: each module can be a Composer package consumed by the main application.

Service Providers and Facades

Service providers are the glue that registers bindings, routes, migrations, and views. When you adopt a custom layout, every new module typically ships with its own ModuleServiceProvider that the root AppServiceProvider or a module-discovery package loads. Facades give the rest of the app a stable interface to those bindings.

Example: Feature-Based Folder

app/
├── Features/
│ ├── Billing/
│ │ ├── Http/Controllers/
│ │ ├── Models/
│ │ ├── Jobs/
│ │ ├── Policies/
│ │ ├── Routes/web.php
│ │ ├── Tests/
│ │ └── Providers/BillingServiceProvider.php
│ └── Inventory/
│ └── ...
├── Shared/
│ ├── ValueObjects/
│ ├── Exceptions/
│ └── Providers/SharedServiceProvider.php
└── Providers/AppServiceProvider.php

This shape lets you ship Billing as a standalone Composer package, run php artisan test --testsuite=Billing in isolation, and review PRs that touch only one feature at a time.

Docker Compose and Folder Structure

Docker does not care about your MVC folders, but the volumes you map will dictate how the container sees them.

Why Docker Compose for Laravel?

Docker Compose lets you define the web, queue, scheduler, cache, and database services in a single YAML file, ensuring every developer and CI runner uses the same PHP version, extensions, and OS libraries. It eliminates "works on my machine" bugs and removes the need to install PHP, Composer, or Redis globally.

Mapping Volumes and Service Paths

The most common mistake is mounting the entire project root into every container, which causes file-permission conflicts between the web container and the worker container. Instead, mount only what each service needs: the app/, config/, routes/, resources/, and database/ directories for the web container, plus storage/ as a shared volume for log and cache continuity.

Optimizing for Production vs Development

Production images should be slim: a multi-stage Dockerfile that compiles assets, installs Composer dependencies with --no-dev, and copies only the resulting vendor/ and public/build/ into a lean runtime image. Development images can include Xdebug, MailHog, and a hot-reload Vite server.

Common Pitfalls

Building images directly on a production server hogs CPU. Use a CI runner (GitHub Actions, GitLab CI) to build and push to a registry, then have the server pull a prebuilt image. Also, configure Docker's automatic restart policy so containers come back after a host reboot, removing the need for a separate Supervisor layer for basic resilience.

Caching Laradocs and Folder Impact

If you keep documentation inside the codebase, Laradocs is the cleanest way to serve it.

What is Laradocs?

Laradocs is a Laravel package that turns a tree of Markdown files into a full documentation site, complete with sidebar navigation, breadcrumbs, dark mode, and SEO tags. It parses Markdown through CommonMark, supports GitHub-flavored extensions (tables, footnotes, task lists), and respects YAML front-matter for per-page metadata like title, order, slug, and group.

Cache Strategies

Laradocs ships with a render cache. The command php artisan laradocs:cache pre-renders every page to HTML, while php artisan laradocs:clear purges the cache after a Markdown file changes. Smart auto-invalidation watches the source files, so most edits regenerate on the next request without a manual command.

Security Implications

Caching means a half-written page never accidentally reaches production if you forgot to remove the draft, because the cache can be tied to a deployment pipeline that only runs after merge. Pair this with an authentication middleware on the documentation route in staging to keep unpublished content off the open web.

Performance Gains

Pre-rendered HTML turns documentation serving from a per-request Markdown parse into a static file lookup. For large doc sets, this can drop page time-to-first-byte from tens of milliseconds to under five, and it slashes CPU usage on the documentation host during traffic spikes.

Pros and Cons of Custom Folder Structures

Customization is not free. Here is the honest ledger.

Advantages for Large Teams

Feature-based layouts give each team a clear directory boundary, reduce cross-team merge conflicts, and let you split a monolith into separately deployed Composer packages later. They also map cleanly to CI matrix builds, where each feature's tests run in parallel.

Potential Drawbacks

Custom structures confuse AI coding assistants, third-party packages, and any new hire who learned Laravel from official docs. Composer autoload maps grow as you add namespaces, and a missed composer dump-autoload leads to silent autoload failures. The maintenance tax is real.

Balancing Convention vs Flexibility

The pragmatic answer is to keep the default top-level structure (app/, routes/, tests/) and reorganize only the inside of app/. You keep every Laravel tool, tutorial, and AI assistant working, while gaining the clarity of feature ownership.

Case Study: Laravel Octane

Running php artisan octane:start with FrankenPHP keeps the framework resident in memory, which means your storage/ and bootstrap/cache/ directories behave differently. Configuration is read once at boot, so a feature that hot-swaps .env values at runtime will not see updates. A custom folder structure that separates runtime config from boot config becomes much easier to reason about in this context.

Best Practices and Recommendations

These are the rules that survive contact with real codebases.

Naming Conventions

Stick with PSR-12 for class and method names, snake_case for configuration keys, kebab-case for route URIs, and PascalCase for namespace directories. Resist the urge to rename app/Http/Controllers to app/http-controllers; every tool in the ecosystem assumes the default casing.

Autoloading and PSR-4

Register each feature namespace in composer.json under autoload.psr-4, then run composer dump-autoload. Use --optimize-autoloader in production to build a classmap that bypasses filesystem lookups.

Testing and CI Integration

Keep tests/Unit/ for logic that does not boot the framework and tests/Feature/ for HTTP-level tests that extend Laravel's TestCase. The phpunit.xml at the project root sets the APP_ENV=testing and an in-memory SQLite database, so feature tests stay isolated.

Documentation and Onboarding

Use Laradocs to render a docs/ folder that explains the project's folder conventions, deployment workflow, and architectural decisions. Link it from your README so new hires find it before they open their first PR.

Common Mistakes and Troubleshooting

Even seasoned teams hit these. Here is how to recover fast.

Misplaced Files and Autoload Failures

If a class cannot be found, the first command to run is php artisan optimize:clear, followed by composer dump-autoload -o. Then verify the namespace declaration matches the directory path exactly, including capitalization.

Docker Volume Conflicts

When the web container reports "permission denied" on storage/, your host UID and container UID do not match. Set user: "1000:1000" in docker-compose.yml or fix ownership with chown -R on the host.

Permission Issues

Both storage/ and bootstrap/cache/ must be writable by the PHP process. In Docker, this means granting the right UID. On a traditional LAMP server, chmod -R 775 plus the web server group usually solves it.

Debugging with php artisan

Run php artisan list to discover every available command, then php artisan route:list to confirm your routes resolved correctly. For middleware issues, inspect the order with php artisan route:list -v and adjust using the withMiddleware() methods in bootstrap/app.php.

Who Is This Best For? (Structured Table)

Target PersonaRecommended OptionKey Reason and Real-World Benefit
Small Solo ProjectsDefault Laravel folder structureZero setup cost, every tutorial and AI tool works out of the box, faster prototyping.
Mid-Size Teams (5-20 devs)Feature-based layout inside app/Features/Clear ownership, fewer merge conflicts, easier code review, parallel testing in CI.
Enterprise ScaleModular Composer packages per domainIndependent versioning, selective deployment, isolated autoloading, team-aligned ownership.
DevOps-Focused TeamsDefault structure + Docker Compose + Traefik + OctaneReproducible environments, zero system pollution, sub-10 ms request handling, automatic restarts.

Frequently Asked Questions

It defines all HTTP routes that respond to web requests, typically returning views or redirecting, and is automatically loaded by the framework’s RouteServiceProvider.

No comments yet. Be the first to share your technical feedback!

Leave Technical Feedback / Discussion

B

Brieflyn Editorial Team

Senior cybersecurity researchers, DevOps engineers, and technical editors at Brieflyn.

EXPERTISE: CYBERSECURITY, CLOUD INFRASTRUCTURE, & SOFTWARE SYSTEMS

Related Guides & Documentation