Best practices

Accept the standards and principles and follow them.

Code is then easier to maintain and it also improves readability and consistency.

If you don't how to write specific code, try to make some research - dig deeper inside the Laravel codebase, list GitHub repositories with many stars, or browse the source code of well-known packages...

1"Consistency is key" - Spatie

Duplicated code is preferred over the wrong abstraction.

If you stumble, fixing a bad abstraction can cost you a lot of time because it can be used in many places and may have other things tied to it that will need to be rewritten.

Better wait a while and make refactor when you are confident with the abstraction.

Keep test coverage as high as possible.

The ideal coverage is higher than 70%. We specifically strive that our applications have at least 80%.

1php artisan test --coverage --min=80

Use static analysis to keep code high quality.

We use PHPStan and it catches all missing type hints and return types.


Use Artisan CLI for creating classes.

Artisan generates classes from stubs and it causes that you will follow some defined structure.

1php artisan make:migration CreateProductsTable
2php artisan make:controller ProductController

Simplify your business logic with action classes.

They are responsible for only one single task and the code is then cleaner and more understandable for others.

1class VerifyUserAction
3 /**
4 * Run the action.
5 */
6 public function run(): void
7 {
8 //
9 }

Group classes into subfolders by resources.

The folder structure is more clean and more simplified to maintain.

1- Actions/User/VerifyUserAction.php
2- Actions/User/BanUserAction.php
4- Actions/Order/CreateOrderAction.php
5- Actions/Order/ConfirmOrderAction.php
6- Actions/Order/CancelOrderAction.php

Keep controller methods thin.

Controllers are responsible for one main thing - returning a response. There should not be some significant logic.

2 * Store a newly created resource in storage.
3 */
4public function store(StoreUserRequest $request): JsonResponse
6 $user = User::query()->create($request->validated());
8 return response()->json($user);

Models should contain only database-related things.

Don't put there your huge business logic, it should be written in Support or Action classes instead.

Never update the database directly, always use migrations.

Migrations allow you to share database schema between team members and between environments.

They are also your database version control. If you modify the database hardcoded, it can create a lot of problems that will be hard to find in reverse. There isn't a single reason why someone shouldn't use them.

Edit this page