Mastering Laravel: Where to Put Your Custom Code (And Why)

Laravel has plenty of built-in features and conventions to keep your code clean. But let’s be real: sooner or later, you’ll need to wri...

Karan Datwani
Karan Datwani
Share:

Laravel has plenty of built-in features and conventions to keep your code clean. But let’s be real: sooner or later, you’ll need to write custom code. The big question is… where do you put it?

If you’ve ever hesitated before creating a new class or stuffing everything inside a controller (because it's easy), you’re not alone. Even devs with 5+ years of Laravel experience struggle with this. Laravel gives you so many places to put custom logic—it’s flexible, but that flexibility can be overwhelming.

So let’s break it down. Here’s where experienced Laravel developers typically put their custom code—and why.

The Main Places for Custom Logic in Laravel

There’s no single right answer. Different types of custom logic belong in different places. Here’s the breakdown:

TLDR (For the Impatient)

Where should you put your custom Laravel code? You should create:

  • ✅ Custom Classes → For Business logic, reusable services
  • ✅ Helpers → For Tiny utility functions
  • ✅ Middleware → For Request filtering, security rules
  • ✅ Blade Directives → For Cleaner views
  • ✅ Background Jobs → To Offload slow tasks
  • ✅ Commands → To Automate CLI tasks
  • ✅ Notifications → For Custom alerts (email, SMS, WhatsApp, etc.)
  • ✅ Actions → For One-task classes (e.g., CreateOrder)

1. Custom Classes (Services, Libraries, Helpers)

Why? You want reusable, self-contained logic that’s easy to test and maintain. Is this definition confusing? That's ok. It's better explained through an example👇

When you’ve got domain-specific logic that doesn’t quite fit into a model, controller, or middleware, a custom class is a great choice. Some devs throw these into app/Library, app/Services, or app/Actions—it’s really up to you. The key is keeping them focused on a single responsibility.

👉 Example: A CurrencyConverter class that fetches exchange rates and does conversions. Another example is creating a PaymentGateway class that will include all functions related to payment - initiate(), capture(), verify() etc.

💡 Pro tip: Bind it in a service provider if you want a singleton instance across your app.


2. Laravel Helpers (Global Utility Functions)

Why? You want quick, reusable functions that doesn’t belong to a specific class.

Helpers are great for those little functions you use everywhere—like formatting money, generating slugs, or manipulating arrays. Keep them in a helpers.php file and load them in composer.json.

👉 Example: A format_price($value) function that always returns a formatted currency string.

💡 Use with caution! Overusing global helpers can make dependencies less obvious.


3. Custom Middleware (Intercepting Requests)

Why? You need to modify or validate requests before they hit your controllers.

Middleware is the best place to handle things like authentication, rate-limiting, logging, and request transformations. It keeps controllers clean and makes sure every request meets certain conditions.

👉 Example: EnsureUserHasRole middleware that blocks unauthorized access.

💡 Use parameterized middleware if you need to pass arguments dynamically.


4. Custom Blade Directives (Cleaner Views)

Why? Keep your views DRY by extracting repeated logic.

If you find yourself repeating the same logic in Blade templates, you can create custom directives. These make your views cleaner and easier to maintain.

👉 Example: @isMobile(), @isDesktop(), @isTablet(), which checks the device type and renders sections accordingly.

💡 Bundle related directives into files and then register them in service provider for easy organization.


5. Background Jobs & Queues (Handle Heavy Tasks)

Why? Keep your app fast by offloading work to background processes.

If something takes longer than a second, it probably belongs in a job. Laravel’s queue system makes it easy to send tasks to the background—things like sending emails, processing videos, or generating long .csv export files.

👉 Example: SendWelcomeEmail job that runs asynchronously.

💡 Use database or Redis queues in production. Avoid sync unless you're debugging.


6. Custom Artisan Commands (Automate Tasks)

Why? Automate repetitive work with your own CLI commands.

Need to clean up old records? Send daily reports? Scrape data? A custom Artisan command lets you do all that from the terminal.

👉 Example: php artisan generate:sitemap to create a fresh sitemap.

💡 Schedule it in app/Console/Kernel.php if it should run on a regular basis.


7. Custom Notifications (Flexible Alerts)

Why? Send messages via email, SMS, Slack, WhatsApp, or custom channels.

Laravel makes notifications easy, but sometimes you need a custom notification channel. Maybe you're integrating with Telegram, or maybe you need an in-app notification system.

👉 Example: App\Notifications\NewOrderReceived or App\Notifications\WhatsAppChannel.

💡 Use notification queues for better performance.

Final Thoughts

Laravel’s flexibility gives you a ton of options, but it’s up to you to use them wisely.

The key takeaway? Put code where it makes sense. Keep controllers thin, use dedicated classes for reusable logic, and take advantage of Laravel’s built-in features to stay organized.

Want to receive more articles like this?

Subscribe to our "Article Digest". We'll send you a list of the new articles, every week, month or quarter - your choice.

Reactions & Comments

What do you think about this?

Latest Articles

Wondering what our community has been up to?