Laravel is one of the most popular PHP frameworks for building modern web applications. It is widely used to develop SaaS platforms, CRM systems, API services, marketplaces, and complex B2B solutions. One of the key reasons for the popularity of outsource Laravel app development services is the combination of a wide range of features and ease of use. Laravel provides a ready-to-use ORM layer, Eloquent, for database interaction, the Artisan CLI for automating common tasks, and starter authentication kits such as Breeze or Jetstream. These tools make it easy to implement core user logic quickly.
In this article, we’ll cover how to create a Laravel project, look at its structure, review example use cases, discuss best practices, and walk through deployment. The Asabix team has extensive Laravel web app development expertise and has delivered over 50 Laravel projects, so our recommendations are based on our real production experience.
Laravel development: project setup and creation
If you’ve decided to build a new Laravel project, the first step is to complete three key actions: prepare your local environment, install the required tools, and generate the base application structure. Laravel development solutions for startups have a straightforward initialization process – you only need to install PHP and Composer, create a project via CLI, and configure the environment. After that, you connect to the database, run migrations, and start your first local server. The official Laravel documentation provides detailed technical explanations for each step, but this is the core workflow we’ll walk through below.
Environment requirements
Before creating a Laravel project, make sure your system meets the basic requirements. Modern Laravel versions run on PHP 8.2 or higher and require several standard PHP extensions, including BCMath, Ctype, JSON, Mbstring, OpenSSL, PDO, Tokenizer, and XML.
In addition to PHP, you will need the following tools:
- Composer – a dependency manager for PHP used to install libraries and the framework itself;
- MySQL or PostgreSQL – a database management system;
- Node.js and npm – used for building frontend assets (via Vite);
- Git – recommended for version control and repository management.
You can verify that the required tools are installed using CLI:
php -v
composer --version
node -v
If all components are installed, you can proceed with creating your Laravel project.
Installing Composer and Laravel Installer
There are two main ways to create a project: using Composer directly or via the Laravel Installer, which simplifies project generation.
To install Laravel Installer globally, run:
composer global require laravel/installer
After installation, the laravel command will be available in your CLI. You can verify it with:
laravel --version
This allows you to quickly generate new Laravel projects without additional setup.
Creating a new project
There are two primary ways to create a new Laravel application.
1) Using Laravel Installer:
laravel new example-app
cd example-app
The installer will automatically generate the project structure, install dependencies, and prepare the base configuration.
2) Alternatively, using Composer:
composer create-project laravel/laravel example-app
cd example-app
This method uses Composer’s standard mechanism to download the Laravel project template. It gives you more control over the installation process, but functionally, the result is the same.
Environment configuration
The next step is configuring the environment. In Laravel, all key application settings are stored in the .env file.
First, copy the example file:
cp .env.example .env
Then generate a unique application key:
php artisan key:generate
This key is used to encrypt sessions, cookies, and other sensitive data. Without it, Laravel will not function properly.
Environment variables
The .env file defines the application configuration depending on the environment. Key parameters include:
APP_NAME="My App"
APP_ENV=local
APP_DEBUG=true
APP_URL=http://localhost:8000
The APP_ENV value determines the application mode:
- local – development environment with detailed error reporting
- staging – testing environment before release
- production – live environment
In production, you should always set:
APP_DEBUG=false
This prevents sensitive technical information and errors from being exposed to users. Also, note that the .env file should never be committed to a Git repository – it is typically already included in .gitignore.
Database connection
Laravel uses the Eloquent ORM and migration system to manage databases. Before running the application, configure the database connection in the .env file:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=my_app
DB_USERNAME=root
DB_PASSWORD=secret
Prior to running migrations, make sure the my_app database has already been created. Then generate the database schema using:
php artisan migrate
This command will execute all migration files and create the required tables. After configuration, start the local server:
php artisan serve
Your Laravel application will be available at:
http://localhost:8000
If everything is set up correctly, you’ll see the default Laravel welcome page in your browser, meaning the project has been successfully created and is ready for further development.
Setting up a local development environment
The next step is running your application locally. A local development environment allows you to test functionality, validate routes, work with the database, and debug code before deployment. The simplest way to set up a local stack is by using Laravel’s built-in server, which can be launched with a single command. It is ideal for individual development, quick feature testing, or learning the framework. It requires no additional services or containerization – you only need PHP installed and can run the command from the project root.
However, in team environments or more complex projects, maintaining consistency across development setups becomes critical. Differences in PHP versions, extensions, or local services often lead to errors. Laravel offers an alternative approach: a Docker-based containerized environment. For this purpose, the framework provides Laravel Sail, a tool that allows you to spin up a full development stack with just a few commands. Laravel Sail creates an isolated environment using Docker containers, preconfigured with essential services such as PHP, a web server, a database, cache, and other supporting components. This ensures all Laravel app developers work in the same environment regardless of operating system or local configuration.
So, which should you choose: the built-in Laravel server or a Docker-based setup? It depends on your project needs. If you are working on a small application or just getting started with Laravel, the built-in server is enough. For team-based development, multi-service integrations, or more complex infrastructure, containerization with Sail is the better choice. Let’s look at both options.
Laravel built-in server
The simplest way to run your application is by using Laravel’s built-in server. In the project root, run:
php artisan serve
After launch, the application will be available in your browser at:
http://localhost:8000
This server leverages PHP’s built-in capabilities to handle HTTP requests and allows you to quickly test routing, controllers, and views. It is not intended for production use, but it works perfectly for local development.
Laravel Sail (Docker)
For team development, Laravel recommends using Laravel Sail – a ready-to-use Docker environment for running your project.
To install Sail, run:
php artisan sail:install
After installation, start the environment with:
./vendor/bin/sail up
Laravel Sail automatically creates Docker containers for the core services your application requires.
From our experience in Laravel web app development, the key advantages of Sail are:
- Consistent environment across the entire team;
- Preconfigured containers for services like MySQL, Redis, and Mailpit;
- No issues with local PHP versions or extensions.
With Sail, a Laravel developer can quickly join a project without spending time configuring local infrastructure, ensuring a smoother and more predictable development process.
Laravel project structure
As mentioned earlier, Laravel is popular partly due to its clear and logical project structure. The framework follows a standardized architecture that makes it easy to navigate the codebase, separate responsibilities between components, and maintain the system over time. The default Laravel directory structure is built around the principle of Separation of Concerns, meaning that application logic is divided by role. Routes, business logic, configuration, templates, and system files are all organized into separate directories.
After creating a new Laravel project, you will see several core directories. The most important ones handle application logic, routing, configuration, and temporary data storage.
Core directories
| Folder | Purpose | Key files |
| app/ | Application business logic | Models, Controllers |
| routes/ | Application routing | web.php, api.php |
| resources/ | Templates and frontend assets | views/ |
| public/ | Web server public directory | index.php |
| config/ | Configuration files | app.php |
| storage/ | Logs, cache, and system files | logs/, cache/ |
Let’s briefly review the role of each directory.
app/ – this is the core folder containing your application code. It includes controllers, models, services, events, middleware, and other components that implement the system’s business logic. Most Laravel development happens here.
routes/ – contains routing definitions. Laravel allows you to separate routes for web interfaces and APIs. Typically, web.php is used for browser-based routes, while api.php handles REST API endpoints.
resources/ – used for the user interface layer. It contains Blade templates as well as frontend assets compiled with Vite or other tools.
public/ – this is the only directory that should be accessible by the web server. It contains the index.php file, which serves as the entry point for all HTTP requests. Static assets such as images may also be stored here.
config/ – holds the framework’s configuration files. Here you can define application settings, services, queues, caching, database connections, and other system parameters.
storage/ – used for storing application-generated data such as logs, cache, sessions, temporary files, and user uploads. Since this directory is used at runtime, the web server must have write permissions to it.
Storage Symlink
In many cases, files stored in the storage directory need to be accessible from the web interface, for example, user-uploaded images.
Laravel solves this by creating a symbolic link between the storage and public directories. You can create it with the following command:
php artisan storage:link
This command creates a symlink between storage/app/public and public/storage. As a result, files stored within the application’s storage become accessible via the browser without directly exposing Laravel’s internal directories.
Code examples and Laravel architecture
The next step in Laravel development is understanding how application code is structured. The framework provides a set of tools and conventions to quickly build core components, including controllers, routes, validation requests, and service layers for business logic. This keeps the codebase structured and maintainable, even in large-scale projects. Laravel uses the Artisan CLI to automatically generate files and component scaffolding. This significantly speeds up Laravel web app development and ensures consistency with framework standards.
Creating a Controller
Controllers handle HTTP requests and act as the bridge between models and views. In Laravel, they can be generated quickly using Artisan. For example, the following command creates a resource controller with a full set of CRUD methods:
php artisan make:controller UserController --resource
After running this command, a app/Http/Controllers file will appear in the UserController.php directory. It will include standard methods:
- index() – display a list of records
- create() – show the form to create a new record
- store() – save a new record
- show() – display a single record
- edit() – show the edit form
- update() – update a record
- destroy() – delete a record
Routing
After creating a controller, you need to define routes that determine how HTTP requests are handled.
In Laravel, routes are typically defined in the routes/web.php file. For example:
Route::prefix('admin')->group(function () {
Route::resource('users', UserController::class);
});
In this case, all routes for the users resource will be available under the /admin prefix. Laravel automatically generates a full set of CRUD routes, such as:
- /admin/users
- /admin/users/create
- /admin/users/{id}
- /admin/users/{id}/edit
Validation with Form Request
Laravel provides a dedicated mechanism for validation called Form Request, which allows you to move validation rules out of controllers into separate classes.
You can create a Form Request using Artisan:
php artisan make:request StoreUserRequest
This will generate a class in the app/Http/Requests directory, where you can define validation rules. For example:
public function rules()
{
return [
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users'
];
}
This approach keeps controllers clean and improves the reusability of validation logic.
Service layer for business Logic
In smaller projects, business logic is sometimes placed directly in controllers. However, in more complex systems, this leads to so-called “fat controllers,” which are difficult to maintain and test.
To avoid this, in Laravel app development services, application logic is often moved into a separate Service Layer.
Example structure:
app/
Services/
UserService.php
This service can contain operations related to users: creation, updates, validation, or integration with other services. Using a service layer helps:
- keep controllers lightweight;
- isolate business logic from the HTTP layer;
- simplify unit testing;
- enable code reuse across the application.
Domain-based structure for large systems
In large projects, the default Laravel structure is often extended with a domain-based approach. Instead of organizing code only by type, it is grouped by business domains.
For example:
app/
Domains/
Users/
Controllers
Models
Services
This approach groups all components related to a specific domain in one place, making large systems easier for new developers to navigate and understand.
Example of a Laravel project
How does Laravel architecture work in practice? Let’s look at a simplified example of an admin panel for user management. Such a project could be part of a CRM, internal dashboard, or B2B system. It includes basic CRUD functionality, validation, and a service layer for business logic.
Project structure example:
app/
Http/
Controllers/
UserController.php
Requests/
StoreUserRequest.php
UpdateUserRequest.php
Models/
User.php
Services/
UserService.php
routes/
web.php
resources/
views/
users/
index.blade.php
create.blade.php
edit.blade.php
database/
migrations/
2026_01_01_000000_create_users_table.php
In this structure:
- UserController handles HTTP requests and responses;
- StoreUserRequest and UpdateUserRequest manage validation;
- UserService contains business logic for user operations;
- User model interacts with the users database table;
- Blade templates render the UI;
- migrations define the database schema.
For example, routing may look like:
Route::prefix('admin')->group(function () {
Route::resource('users', UserController::class);
});
The controller should not contain all logic directly. Its role is to receive the request, pass data to the service, and return a response:
public function store(StoreUserRequest $request, UserService $userService)
{
$userService->create($request->validated());
return redirect()->route('users.index')
->with('success', 'User created successfully.');
}
The core logic is handled in the service:
public function create(array $data): User
{
return User::create($data);
}
This demonstrates proper separation of responsibilities in a Laravel project: the controller manages request flow, Form Request handles validation, the model interacts with the database, and the service encapsulates business logic.
In real-world applications, this structure is often extended with roles, authorization, queues, events, APIs, and integrations with external systems. However, even this basic setup shows how Laravel enables clean, scalable architecture.
Web development using Laravel: Best practices
When developing with Laravel, it’s important to maintain a clean and scalable architecture. Following core best practices helps avoid overloaded controllers, simplifies testing, and ensures stable performance in production. Key recommendations of our Laravel web development agency are:
- Use a Service Layer for business logic. Controllers should only handle HTTP requests and pass data to services. Core business logic should be placed in separate service classes. This prevents so-called “fat controllers,” improves code reusability, and makes the system more modular.
- Use Form Request for validation. Laravel allows you to move validation rules into dedicated request classes. This keeps controllers concise, reduces code duplication, and centralizes validation logic.
- Write automated tests. Laravel has built-in testing support via PHPUnit. A recommended test structure looks like this:
tests/
Feature/
Unit/
Feature tests validate HTTP requests, routes, and controllers, while Unit tests focus on individual classes and business logic.
- Use caching in production. Laravel provides several commands for caching configuration and routes, significantly improving application performance:
php artisan config:cache
php artisan route:cache
php artisan view:cache
Caching reduces the need to repeatedly read configuration files and speeds up HTTP request handling.
- Avoid direct use of .env in code. Environment variables should only be accessed within configuration files. In your application code, always use the (config()) helper to avoid caching issues.
- Follow Laravel’s standard structure. Even as projects grow, it’s better to extend the default architecture using services, domain modules, or packages rather than modifying the framework’s core directory structure.
- Use queues for heavy tasks. Operations such as sending emails, generating reports, or integrating with external APIs should be handled via queues. This prevents blocking the main HTTP request and improves overall system responsiveness.
Laravel project deployment
After completing local development, a Laravel project must be properly prepared for production. Deployment involves more than just copying files – it requires correct web server configuration, permissions setup, environment configuration, and performance optimization. Skipping these steps can result in unstable, slow, or insecure applications. So, how do you deploy a Laravel project correctly?
- Web server configuration
Laravel is designed so that the only public entry point to the application is the public. directory. It contains the index.php file, which handles all HTTP requests.
The web server must be configured so that the document root points to:
/public/index.php
This is critical for two reasons in app development using Laravel. First, it ensures that all requests are properly routed through Laravel. Second, it improves security by preventing direct access to internal framework files, configurations, and service directories. For Nginx or Apache, the document root should always point to the public/ directory. If the server is configured to point to the project root instead, it may expose sensitive files and create serious security risks. - Permissions
For Laravel to function correctly, the web server must have write permissions for certain directories, primarily:
storage
bootstrap/cache
The storage directory is used for logs, cache, sessions, and user-uploaded files, while bootstrap/cache stores cached configuration and system files. If the server cannot write to these directories, the application may throw errors, fail to log data, or behave unpredictably. Before deploying to production, always verify ownership and permissions. The exact setup depends on your OS, server configuration, and the user running PHP-FPM or Apache. - Production optimization
Laravel provides built-in tools to optimize the application before production. The basic command is:
php artisan optimize
This command prepares the application by caching parts of the framework and reducing overhead during request handling. As a result, the application starts faster and performs more efficiently under load. In production environments, it is also common to cache configuration, routes, and views, especially when using automated deployment pipelines (CI/CD). - Disabling debug mode
One of the mandatory steps before deployment is disabling debug mode. In the .env file, set:
APP_DEBUG=false
If APP_DEBUG=true is left enabled, users may see detailed error messages, stack traces, file paths, and parts of the internal system logic. This creates serious security risks. In production, errors should be logged rather than displayed. - Deployment automation
For small projects, deployment may sometimes be done manually. However, for team environments and frequent releases, automation is far more efficient.
Within the Laravel ecosystem, several approaches are commonly used:- Laravel Forge – simplifies server setup and automated deployment on VPS;
- Laravel Vapor – designed for scalable serverless infrastructure;
- CI/CD pipelines using platforms like GitHub Actions or GitLab CI.
Conclusion
Laravel enables rapid development of scalable web applications thanks to its clear structure, powerful CLI tools, and extensive ecosystem. In this article, our Laravel app development company covered how to create a project, explored the framework’s structure, reviewed code examples, discussed best practices for Laravel app development, and outlined the core deployment process. The best way to truly understand Laravel is to build your own project and work with its architecture in practice.
If you need Laravel development services, the Asabix team can deliver a full-cycle Laravel development solution, from architecture design to production deployment. As a Laravel PHP development company, we build scalable web systems, integrate third-party services, and help businesses create reliable digital platforms.
Contact Asabix to discuss your Laravel project.
Read more articles in our blog